From 2403682f872c3e1b245957c66d56788e84ac0404 Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 14:33:19 -0400 Subject: [PATCH 01/16] Move behat.yml file to default location --- features/behat.yml => behat.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename features/behat.yml => behat.yml (100%) diff --git a/features/behat.yml b/behat.yml similarity index 100% rename from features/behat.yml rename to behat.yml From 588ea9502e74cc3cf6662b2c04ff2e422bbfe9c3 Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 14:33:33 -0400 Subject: [PATCH 02/16] Make name of docker compose container consistent --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index b7f3edb..335e831 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,6 @@ version: '2' services: - cli: + test: image: silintl/php7:7.2 volumes: - ./:/data/ From 65e6a3b3273c1a5f52fb6800e5596826abd24905 Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 14:37:01 -0400 Subject: [PATCH 03/16] Fix path to feature file in behat.yml config --- behat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/behat.yml b/behat.yml index 13b8229..4ff545e 100644 --- a/behat.yml +++ b/behat.yml @@ -1,5 +1,5 @@ default: suites: google_sheets: - paths: [ "%paths.base%/google-sheets.feature" ] + paths: [ "%paths.base%/features/google-sheets.feature" ] contexts: [ Sil\GoogleSheets\features\context\GoogleSheetsContext ] From e35eb25fc3b7033fd4b9a890cb700d51a17cd002 Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 14:37:47 -0400 Subject: [PATCH 04/16] Add simple "append data" test scenario --- features/google-sheets.feature | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 features/google-sheets.feature diff --git a/features/google-sheets.feature b/features/google-sheets.feature new file mode 100644 index 0000000..1c154ce --- /dev/null +++ b/features/google-sheets.feature @@ -0,0 +1,5 @@ +Feature: Interacting with Google Sheets + + Scenario: Appending data to a Google Sheet + When I append data to a Google Sheet + Then an exception should NOT have been thrown From f61208d33f998bd90c97bc4fc708389a6d1bddb9 Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 14:49:57 -0400 Subject: [PATCH 05/16] Create folder (to be ignored) for local credentials used for testing --- credentials/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 credentials/.gitkeep diff --git a/credentials/.gitkeep b/credentials/.gitkeep new file mode 100644 index 0000000..e69de29 From 31ea19892fa3d31f3119ee0b150ae6a834482138 Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 14:50:23 -0400 Subject: [PATCH 06/16] Ignore contents of local testing "credentials" folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 987e2a2..669dc01 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ composer.lock vendor +credentials From 510e26d66d7907e48897f2d7cc13ace37fe2ad47 Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 15:11:31 -0400 Subject: [PATCH 07/16] Set up local.env for setting path to credentials JSON file for testing --- .gitignore | 1 + composer.json | 3 ++- docker-compose.yml | 2 ++ local.env.dist | 3 +++ 4 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 local.env.dist diff --git a/.gitignore b/.gitignore index 669dc01..02b18bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ composer.lock vendor credentials +local.env diff --git a/composer.json b/composer.json index 51e5951..2a9ff7c 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,8 @@ }, "require-dev": { "behat/behat": "^3.6", - "roave/security-advisories": "dev-master" + "roave/security-advisories": "dev-master", + "silinternational/php-env": "^2.1" }, "autoload": { "psr-4": { diff --git a/docker-compose.yml b/docker-compose.yml index 335e831..b40294b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,6 +2,8 @@ version: '2' services: test: image: silintl/php7:7.2 + env_file: + - local.env volumes: - ./:/data/ working_dir: /data diff --git a/local.env.dist b/local.env.dist new file mode 100644 index 0000000..6fba7a5 --- /dev/null +++ b/local.env.dist @@ -0,0 +1,3 @@ +# The path (relative to the repo's root) to the Google credentials JSON file to +# use for testing. +TEST_JSON_AUTH_FILE_PATH=credentials/your-credentials-file-name.json From a06a00a2d63f62899af909d1dc31487ed137eda9 Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 15:12:20 -0400 Subject: [PATCH 08/16] Fix configuration of Google_Client to v1 style (which we're using) --- src/GoogleSheets.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/GoogleSheets.php b/src/GoogleSheets.php index ac7cfc8..b32f7b5 100644 --- a/src/GoogleSheets.php +++ b/src/GoogleSheets.php @@ -27,13 +27,8 @@ public function __construct( Assert::isNotEmpty($applicationName, 'applicationName'); Assert::fileExists($jsonAuthFilePath); - $jsonAuthString = \file_get_contents($jsonAuthFilePath); - $credentials = json_decode($jsonAuthString, true); $googleClient = new Google_Client(); - $googleClient->setApplicationName($applicationName); - $googleClient->setScopes($scopes); - $googleClient->setAuthConfig($credentials); - $googleClient->setAccessType('offline'); + $googleClient->loadServiceAccountJson($jsonAuthFilePath, $scopes); $this->sheets = new Google_Service_Sheets($googleClient); } From 5b9fba45d28a077faa72cb371e335d810117eed6 Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 15:19:22 -0400 Subject: [PATCH 09/16] Provide a way to specify the spreadsheet ID for tests --- local.env.dist | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/local.env.dist b/local.env.dist index 6fba7a5..11c56cc 100644 --- a/local.env.dist +++ b/local.env.dist @@ -1,3 +1,7 @@ # The path (relative to the repo's root) to the Google credentials JSON file to # use for testing. TEST_JSON_AUTH_FILE_PATH=credentials/your-credentials-file-name.json + +# The ID of the Google Sheet, shown in its URL after the +# "https://docs.google.com/spreadsheets/d/" prefix, up until the next "/". +TEST_SPREADSHEET_ID= From e117ca90929e4a0320c5b99783ad51e4be31489f Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 16:13:02 -0400 Subject: [PATCH 10/16] Add a basic README with helpful links (for developing this library) --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..ec3d1f7 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Google Sheets PHP + +A simple library for pushing data to a Google Sheet + +## Resources + +How to use the Google PHP API Client (v1) that this uses: +- https://github.com/googleapis/google-api-php-client/blob/v1.1.8/examples/service-account.php + +Documentation on the `append` Google Sheets API: +- https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append \ No newline at end of file From b671eb2ef9ed065132a217a3f19ff2b6d9d048cc Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 16:15:49 -0400 Subject: [PATCH 11/16] Implement simple test --- features/context/GoogleSheetsContext.php | 37 ++++++++++++++++++++++++ features/google-sheets.feature | 2 +- 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 features/context/GoogleSheetsContext.php diff --git a/features/context/GoogleSheetsContext.php b/features/context/GoogleSheetsContext.php new file mode 100644 index 0000000..fc1e5cd --- /dev/null +++ b/features/context/GoogleSheetsContext.php @@ -0,0 +1,37 @@ +googleSheets = new GoogleSheets( + 'Sil\GoogleSheets library', + __DIR__ . '/../../' . $jsonAuthFilePath + ); + } + + /** + * @When I append data to a Google Sheet + */ + public function iAppendDataToAGoogleSheet() + { + $spreadsheetId = Env::requireEnv('TEST_SPREADSHEET_ID'); + $this->googleSheets->append( + [ + ['The', 'first', 'row'], + ['The', 'second', 'row'], + ], + $spreadsheetId + ); + } +} diff --git a/features/google-sheets.feature b/features/google-sheets.feature index 1c154ce..30e0b5d 100644 --- a/features/google-sheets.feature +++ b/features/google-sheets.feature @@ -2,4 +2,4 @@ Feature: Interacting with Google Sheets Scenario: Appending data to a Google Sheet When I append data to a Google Sheet - Then an exception should NOT have been thrown + # Note: The test will fail if an exception is thrown From 155a48ef1db352d6b686678aabf4dfda810e30ab Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 16:16:44 -0400 Subject: [PATCH 12/16] Pass the generated assertion credentials to the Google_Client --- src/GoogleSheets.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/GoogleSheets.php b/src/GoogleSheets.php index b32f7b5..7a60037 100644 --- a/src/GoogleSheets.php +++ b/src/GoogleSheets.php @@ -28,7 +28,11 @@ public function __construct( Assert::fileExists($jsonAuthFilePath); $googleClient = new Google_Client(); - $googleClient->loadServiceAccountJson($jsonAuthFilePath, $scopes); + $assertionCredentials = $googleClient->loadServiceAccountJson( + $jsonAuthFilePath, + $scopes + ); + $googleClient->setAssertionCredentials($assertionCredentials); $this->sheets = new Google_Service_Sheets($googleClient); } From 7d8313f9de154dbb20bba52d4600bf5465a299b9 Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 16:17:09 -0400 Subject: [PATCH 13/16] Fix/document the ability to send multiple rows of data --- src/GoogleSheets.php | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/GoogleSheets.php b/src/GoogleSheets.php index 7a60037..ea624a6 100644 --- a/src/GoogleSheets.php +++ b/src/GoogleSheets.php @@ -39,7 +39,12 @@ public function __construct( /** * Append the provided data to the specified Google Sheet. * - * @param array $data + * @param array[] $data A nested array, where the inner arrays' entries will + * go into consecutive cells in a given row. Example: + * [ + * ['The', 'first', 'row'], + * ['The', 'second', 'row'], + * ] * @param string $spreadsheetId The Spreadsheet ID * @param string $tabName The name of the tab within the Google Sheet */ @@ -50,17 +55,20 @@ public function append( ) { Assert::isNotEmpty($spreadsheetId, 'Spreadsheet ID'); - $range = sprintf('%s!A1:A1000', $tabName); + $range = sprintf('%s!A:A', $tabName); $postBody = new Google_Service_Sheets_ValueRange([ 'range' => $range, - 'majorDimension' => 'COLUMNS', - 'values' => [$data], + 'majorDimension' => 'ROWS', + 'values' => $data, ]); $this->sheets->spreadsheets_values->append( $spreadsheetId, $range, $postBody, - ['valueInputOption' => 'USER_ENTERED'] + [ + 'valueInputOption' => 'USER_ENTERED', + 'insertDataOption' => 'INSERT_ROWS', + ] ); } } From 08426aa8e45477cde8934687fd86bf81cd6724b7 Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 16:19:21 -0400 Subject: [PATCH 14/16] Clarify that this uses VERSION 1 of the Google PHP API Client --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ec3d1f7..2f8c2c8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Google Sheets PHP -A simple library for pushing data to a Google Sheet +A simple library for pushing data to a Google Sheet using the Google PHP API +Client **version 1**. ## Resources From 092d31283912233d7441f84602b069e09800e8ca Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 16:20:52 -0400 Subject: [PATCH 15/16] Add a license (MIT) --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9649ce0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 SIL International + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 836a61dd0fc5c473ddaab6822a2a291d1ed594e4 Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Thu, 28 May 2020 16:36:29 -0400 Subject: [PATCH 16/16] Document how to use this --- README.md | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2f8c2c8..8212f92 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,47 @@ A simple library for pushing data to a Google Sheet using the Google PHP API Client **version 1**. +## Authorization + +To use this library to push data to a Google Sheet... + +1. Go to the Google Developers Console. +2. If you do not yet have a project that you plan to use this with, create one. +3. Enable the "Google Sheets API" for that project. +4. Create credentials for the project: + - To use the Google Sheets API + - From a web server + - To access application data + - Not using Google App Engine or Computer Engine + - Give it a service account name + - Don't give it a role + - Select the JSON key option +5. Save that JSON file to some private folder where your code can access it. +6. Get the Spreadsheet ID of the Google Sheet that you want to push data to. It + is shown in its URL after the "https://docs.google.com/spreadsheets/d/" + prefix, up until the next "/". +7. Share that Google Sheet (cf. the spreadsheet ID) with the `client_email` + value found in your Google credentials JSON file, giving it permission to + edit the spreadsheet. + +Viola! You should now be able to push data to that Google Sheet. + +## Testing + +To test this library (and that your permissions are set up correctly)... + +1. Clone this repo to your local machine. +2. Put your JSON credentials file in the "credentials" folder (Git is set to + ignore that folder's contents... DO NOT COMMIT YOUR JSON FILE TO GIT). +3. Copy the `local.env.dist` file to `local.env`, giving it the requested + values. +4. Open a terminal to the root of the repo and run `make`. +5. Look at your Google Sheet and verify that data has been appended. + ## Resources How to use the Google PHP API Client (v1) that this uses: - https://github.com/googleapis/google-api-php-client/blob/v1.1.8/examples/service-account.php Documentation on the `append` Google Sheets API: -- https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append \ No newline at end of file +- https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append