From bc4dfafe58ad46d0e48f0f9f150aa4af5a2c1488 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 6 Mar 2023 15:14:54 +0000 Subject: [PATCH 1/8] Assert less / greater than or equal to, as two subscribers might be subscribed in the same second --- tests/ConvertKitAPITest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ConvertKitAPITest.php b/tests/ConvertKitAPITest.php index d985103..7bb72b8 100644 --- a/tests/ConvertKitAPITest.php +++ b/tests/ConvertKitAPITest.php @@ -109,7 +109,7 @@ public function testGetSequenceSubscriptions() $this->assertIsArray($result['subscriptions']); // Assert sort order is ascending. - $this->assertGreaterThan($result['subscriptions'][0]->created_at, $result['subscriptions'][1]->created_at); + $this->assertGreaterThanOrEqual($result['subscriptions'][0]->created_at, $result['subscriptions'][1]->created_at); } /** @@ -134,7 +134,7 @@ public function testGetSequenceSubscriptionsWithDescSortOrder() $this->assertIsArray($result['subscriptions']); // Assert sort order. - $this->assertLessThan($result['subscriptions'][0]->created_at, $result['subscriptions'][1]->created_at); + $this->assertLessThanOrEqual($result['subscriptions'][0]->created_at, $result['subscriptions'][1]->created_at); } /** From 3918ecdcf000d5f20cc5ce1be4ffccbe69cf6234 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 6 Mar 2023 15:16:05 +0000 Subject: [PATCH 2/8] Updated testing docs to include using PHP CodeSniffer on code --- TESTING.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/TESTING.md b/TESTING.md index e2e5c09..2a56209 100644 --- a/TESTING.md +++ b/TESTING.md @@ -36,6 +36,26 @@ If a test fails, you can inspect the output. Any errors should be corrected by making applicable code or test changes. +## Run PHP CodeSniffer + +[PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) checks that all code meets the [PSR-12 Coding Standards](https://www.php-fig.org/psr/psr-12/). + +To run CodeSniffer on tests, enter the following command: + +```bash +vendor/bin/phpcs +``` + +Any errors should be corrected by either: +- making applicable code changes +- (Experimental) running `vendor/bin/phpcbf` to automatically fix coding standards + +Need to change the coding standard rules applied? Either: +- ignore a rule in the affected code, by adding `phpcs:ignore {rule}`, where {rule} is the given rule that failed in the above output. +- edit the [phpcs.tests.xml](phpcs.xml) file. + +**Rules can be ignored with caution**, but it's essential that rules relating to coding style and inline code commenting / docblocks remain. + ## Run PHP CodeSniffer for Tests [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) checks that all test code meets the [PSR-12 Coding Standards](https://www.php-fig.org/psr/psr-12/). From ea8699c137c4feb586467b1fb3b8ea1442bbecd8 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 6 Mar 2023 15:18:45 +0000 Subject: [PATCH 3/8] Fix coding standards on tests --- tests/ConvertKitAPITest.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/ConvertKitAPITest.php b/tests/ConvertKitAPITest.php index 7bb72b8..4be5743 100644 --- a/tests/ConvertKitAPITest.php +++ b/tests/ConvertKitAPITest.php @@ -109,7 +109,10 @@ public function testGetSequenceSubscriptions() $this->assertIsArray($result['subscriptions']); // Assert sort order is ascending. - $this->assertGreaterThanOrEqual($result['subscriptions'][0]->created_at, $result['subscriptions'][1]->created_at); + $this->assertGreaterThanOrEqual( + $result['subscriptions'][0]->created_at, + $result['subscriptions'][1]->created_a + ); } /** @@ -134,7 +137,10 @@ public function testGetSequenceSubscriptionsWithDescSortOrder() $this->assertIsArray($result['subscriptions']); // Assert sort order. - $this->assertLessThanOrEqual($result['subscriptions'][0]->created_at, $result['subscriptions'][1]->created_at); + $this->assertLessThanOrEqual( + $result['subscriptions'][0]->created_at, + $result['subscriptions'][1]->created_a + ); } /** From 4aff3b7636293232df9f840df6c9108906becadb Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 6 Mar 2023 15:20:42 +0000 Subject: [PATCH 4/8] Fix typo on tests --- tests/ConvertKitAPITest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ConvertKitAPITest.php b/tests/ConvertKitAPITest.php index 4be5743..398bb42 100644 --- a/tests/ConvertKitAPITest.php +++ b/tests/ConvertKitAPITest.php @@ -111,7 +111,7 @@ public function testGetSequenceSubscriptions() // Assert sort order is ascending. $this->assertGreaterThanOrEqual( $result['subscriptions'][0]->created_at, - $result['subscriptions'][1]->created_a + $result['subscriptions'][1]->created_at ); } @@ -139,7 +139,7 @@ public function testGetSequenceSubscriptionsWithDescSortOrder() // Assert sort order. $this->assertLessThanOrEqual( $result['subscriptions'][0]->created_at, - $result['subscriptions'][1]->created_a + $result['subscriptions'][1]->created_at ); } From 69523a4f1e5780626baaf07f902f8629abec048f Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 6 Mar 2023 16:01:01 +0000 Subject: [PATCH 5/8] Adds get, post, put and delete function calls --- src/ConvertKit_API.php | 85 +++++++++++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 13 deletions(-) diff --git a/src/ConvertKit_API.php b/src/ConvertKit_API.php index a816750..59ab3bd 100644 --- a/src/ConvertKit_API.php +++ b/src/ConvertKit_API.php @@ -136,7 +136,7 @@ public function get_account() $this->create_log(sprintf('GET account: %s, %s', $request, json_encode($options))); - return $this->make_request($request, 'GET', $options); + return $this->get($request, $options); } @@ -155,7 +155,7 @@ public function get_sequences() $this->create_log(sprintf('GET sequences: %s, %s', $request, json_encode($options))); - return $this->make_request($request, 'GET', $options); + return $this->get($request, $options); } @@ -185,7 +185,7 @@ public function get_sequence_subscriptions(int $sequence_id, string $sort_order ) ); - return $this->make_request($request, 'GET', $options); + return $this->get($request, $options); } @@ -216,7 +216,7 @@ public function add_subscriber_to_sequence(int $sequence_id, string $email) ) ); - return $this->make_request($request, 'POST', $options); + return $this->post($request, $options); } @@ -242,7 +242,7 @@ public function add_tag(int $tag, array $options) $this->create_log(sprintf('POST add tag: %s, %s, %s', $request, json_encode($options), $tag)); - return $this->make_request($request, 'POST', $options); + return $this->post($request, $options); } @@ -275,7 +275,7 @@ public function get_resources(string $resource) $this->create_log(sprintf('GET request %s, %s', $request, json_encode($options))); - $resources = $this->make_request($request, 'GET', $options); + $resources = $this->get($request, $options); if (!$resources) { $this->create_log('No resources'); @@ -369,7 +369,7 @@ public function form_subscribe(int $form_id, array $options) $this->create_log(sprintf('POST form subscribe: %s, %s, %s', $request, json_encode($options), $form_id)); - return $this->make_request($request, 'POST', $options); + return $this->post($request, $options); } @@ -394,7 +394,7 @@ public function form_unsubscribe(array $options) $this->create_log(sprintf('PUT form unsubscribe: %s, %s', $request, json_encode($options))); - return $this->make_request($request, 'PUT', $options); + return $this->put($request, $options); } @@ -431,7 +431,7 @@ public function get_subscriber_id(string $email_address) ) ); - $subscribers = $this->make_request($request, 'GET', $options); + $subscribers = $this->get($request, $options); if (!$subscribers) { $this->create_log('No subscribers'); @@ -473,7 +473,7 @@ public function get_subscriber(int $subscriber_id) $this->create_log(sprintf('GET subscriber tags: %s, %s, %s', $request, json_encode($options), $subscriber_id)); - return $this->make_request($request, 'GET', $options); + return $this->get($request, $options); } @@ -500,7 +500,7 @@ public function get_subscriber_tags(int $subscriber_id) $this->create_log(sprintf('GET subscriber tags: %s, %s, %s', $request, json_encode($options), $subscriber_id)); - return $this->make_request($request, 'GET', $options); + return $this->get($request, $options); } @@ -525,7 +525,7 @@ public function list_purchases(array $options) $this->create_log(sprintf('GET list purchases: %s, %s', $request, json_encode($options))); - return $this->make_request($request, 'GET', $options); + return $this->get($request, $options); } @@ -550,7 +550,7 @@ public function create_purchase(array $options) $this->create_log(sprintf('POST create purchase: %s, %s', $request, json_encode($options))); - return $this->make_request($request, 'POST', $options); + return $this->post($request, $options); } @@ -694,6 +694,65 @@ private function strip_html_head_body_tags(string $markup) return $markup; } + /** + * Performs a GET request to the API. + * + * @param string $endpoint API Endpoint. + * @param array $args Request arguments. + * + * @throws \InvalidArgumentException If the provided arguments are not of the expected type. + * + * @return false|mixed + */ + public function get(string $endpoint, array $args = []) + { + return $this->make_request($endpoint, 'GET', $args); + } + + /** + * Performs a POST request to the API. + * + * @param string $endpoint API Endpoint. + * @param array $args Request arguments. + * + * @throws \InvalidArgumentException If the provided arguments are not of the expected type. + * + * @return false|mixed + */ + public function post(string $endpoint, array $args = []) + { + return $this->make_request($endpoint, 'POST', $args); + } + + /** + * Performs a PUT request to the API. + * + * @param string $endpoint API Endpoint. + * @param array $args Request arguments. + * + * @throws \InvalidArgumentException If the provided arguments are not of the expected type. + * + * @return false|mixed + */ + public function put(string $endpoint, array $args = []) + { + return $this->make_request($endpoint, 'PUT', $args); + } + + /** + * Performs a DELETE request to the API. + * + * @param string $endpoint API Endpoint. + * @param array $args Request arguments. + * + * @throws \InvalidArgumentException If the provided arguments are not of the expected type. + * + * @return false|mixed + */ + public function delete(string $endpoint, array $args = []) + { + return $this->make_request($endpoint, 'DELETE', $args); + } /** * Performs an API request using Guzzle. From 2db290b47a14f9c86f64032004de0d37f1e6312d Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 6 Mar 2023 16:13:45 +0000 Subject: [PATCH 6/8] Move repetitive `api_version` property into `make_request()` --- src/ConvertKit_API.php | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/ConvertKit_API.php b/src/ConvertKit_API.php index 59ab3bd..26d2666 100644 --- a/src/ConvertKit_API.php +++ b/src/ConvertKit_API.php @@ -128,7 +128,7 @@ private function create_log(string $message) */ public function get_account() { - $request = $this->api_version . '/account'; + $request = 'account'; $options = [ 'api_secret' => $this->api_secret, @@ -147,7 +147,7 @@ public function get_account() */ public function get_sequences() { - $request = $this->api_version . '/sequences'; + $request = 'sequences'; $options = [ 'api_key' => $this->api_key, @@ -169,7 +169,7 @@ public function get_sequences() */ public function get_sequence_subscriptions(int $sequence_id, string $sort_order = 'asc') { - $request = $this->api_version . sprintf('/sequences/%s/subscriptions', $sequence_id); + $request = sprintf('/sequences/%s/subscriptions', $sequence_id); $options = [ 'api_secret' => $this->api_secret, @@ -199,7 +199,7 @@ public function get_sequence_subscriptions(int $sequence_id, string $sort_order */ public function add_subscriber_to_sequence(int $sequence_id, string $email) { - $request = $this->api_version . sprintf('/courses/%s/subscribe', $sequence_id); + $request = sprintf('/courses/%s/subscribe', $sequence_id); $options = [ 'api_key' => $this->api_key, @@ -236,7 +236,7 @@ public function add_tag(int $tag, array $options) throw new \InvalidArgumentException(); } - $request = $this->api_version . sprintf('/tags/%s/subscribe', $tag); + $request = sprintf('/tags/%s/subscribe', $tag); $options['api_key'] = $this->api_key; @@ -271,7 +271,13 @@ public function get_resources(string $resource) 'Accept-Encoding' => 'gzip', ]; - $request = sprintf('/%s/%s', $this->api_version, (($resource === 'landing_pages') ? 'forms' : $resource)); + // Assign the resource to the request variable. + $request = $resource; + + // Landing pages are included in the /forms endpoint. + if ($resource === 'landing_pages') { + $request = 'forms'; + } $this->create_log(sprintf('GET request %s, %s', $request, json_encode($options))); @@ -363,7 +369,7 @@ public function form_subscribe(int $form_id, array $options) throw new \InvalidArgumentException(); } - $request = $this->api_version . sprintf('/forms/%s/subscribe', $form_id); + $request = sprintf('/forms/%s/subscribe', $form_id); $options['api_key'] = $this->api_key; @@ -388,7 +394,7 @@ public function form_unsubscribe(array $options) throw new \InvalidArgumentException(); } - $request = $this->api_version . '/unsubscribe'; + $request = 'unsubscribe'; $options['api_secret'] = $this->api_secret; @@ -414,7 +420,7 @@ public function get_subscriber_id(string $email_address) throw new \InvalidArgumentException(); } - $request = $this->api_version . '/subscribers'; + $request = 'subscribers'; $options = [ 'api_secret' => $this->api_secret, @@ -465,7 +471,7 @@ public function get_subscriber(int $subscriber_id) throw new \InvalidArgumentException(); } - $request = $this->api_version . sprintf('/subscribers/%s', $subscriber_id); + $request = sprintf('/subscribers/%s', $subscriber_id); $options = [ 'api_secret' => $this->api_secret, @@ -492,7 +498,7 @@ public function get_subscriber_tags(int $subscriber_id) throw new \InvalidArgumentException(); } - $request = $this->api_version . sprintf('/subscribers/%s/tags', $subscriber_id); + $request = sprintf('/subscribers/%s/tags', $subscriber_id); $options = [ 'api_key' => $this->api_key, @@ -519,7 +525,7 @@ public function list_purchases(array $options) throw new \InvalidArgumentException(); } - $request = $this->api_version . '/purchases'; + $request = 'purchases'; $options['api_secret'] = $this->api_secret; @@ -544,7 +550,7 @@ public function create_purchase(array $options) throw new \InvalidArgumentException(); } - $request = $this->api_version . '/purchases'; + $request = 'purchases'; $options['api_secret'] = $this->api_secret; @@ -771,7 +777,7 @@ public function make_request(string $endpoint, string $method, array $args = []) throw new \InvalidArgumentException(); } - $url = $this->api_url_base . $endpoint; + $url = $this->api_url_base . $this->api_version . '/' . $endpoint; $this->create_log(sprintf('Making request on %s.', $url)); From c7f51f3b184f340759ae744aff3b2ddb6fb7d31a Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 6 Mar 2023 16:48:31 +0000 Subject: [PATCH 7/8] Replace check_if_subscriber_in_array() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is no longer needed, as we query the API by `email_address`, so inspecting the response’s `total_subscribers` is sufficient. --- src/ConvertKit_API.php | 34 +++++----------------------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/src/ConvertKit_API.php b/src/ConvertKit_API.php index a816750..3300895 100644 --- a/src/ConvertKit_API.php +++ b/src/ConvertKit_API.php @@ -438,15 +438,13 @@ public function get_subscriber_id(string $email_address) return false; } - $subscriber_id = $this::check_if_subscriber_in_array($email_address, $subscribers->subscribers); - - if ($subscriber_id) { - return $subscriber_id; + if ($subscribers->total_subscribers === 0) { + $this->create_log('No subscribers'); + return false; } - $this->create_log('Subscriber not found'); - - return false; + // Return the subscriber's ID. + return $subscribers->subscribers[0]->id; } @@ -761,26 +759,4 @@ public function make_request(string $endpoint, string $method, array $args = []) $this->create_log('Failed to finish request.'); return false; } - - - /** - * Looks for subscriber with email in array - * - * @param string $email_address Email Address. - * @param array $subscribers Subscribers. - * - * @return false|integer false if not found, else subscriber object - */ - private function check_if_subscriber_in_array(string $email_address, array $subscribers) - { - foreach ($subscribers as $subscriber) { - if ($subscriber->email_address === $email_address) { - $this->create_log('Subscriber found!'); - return $subscriber->id; - } - } - - $this->create_log('Subscriber not found on current page.'); - return false; - } } From 7d7676bc8dcec79859dd90bb946b7527a418418d Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 6 Mar 2023 17:40:28 +0000 Subject: [PATCH 8/8] Remove leading forwardslash on endpoints --- src/ConvertKit_API.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ConvertKit_API.php b/src/ConvertKit_API.php index 26d2666..19074be 100644 --- a/src/ConvertKit_API.php +++ b/src/ConvertKit_API.php @@ -169,7 +169,7 @@ public function get_sequences() */ public function get_sequence_subscriptions(int $sequence_id, string $sort_order = 'asc') { - $request = sprintf('/sequences/%s/subscriptions', $sequence_id); + $request = sprintf('sequences/%s/subscriptions', $sequence_id); $options = [ 'api_secret' => $this->api_secret, @@ -199,7 +199,7 @@ public function get_sequence_subscriptions(int $sequence_id, string $sort_order */ public function add_subscriber_to_sequence(int $sequence_id, string $email) { - $request = sprintf('/courses/%s/subscribe', $sequence_id); + $request = sprintf('courses/%s/subscribe', $sequence_id); $options = [ 'api_key' => $this->api_key, @@ -236,7 +236,7 @@ public function add_tag(int $tag, array $options) throw new \InvalidArgumentException(); } - $request = sprintf('/tags/%s/subscribe', $tag); + $request = sprintf('tags/%s/subscribe', $tag); $options['api_key'] = $this->api_key; @@ -369,7 +369,7 @@ public function form_subscribe(int $form_id, array $options) throw new \InvalidArgumentException(); } - $request = sprintf('/forms/%s/subscribe', $form_id); + $request = sprintf('forms/%s/subscribe', $form_id); $options['api_key'] = $this->api_key; @@ -471,7 +471,7 @@ public function get_subscriber(int $subscriber_id) throw new \InvalidArgumentException(); } - $request = sprintf('/subscribers/%s', $subscriber_id); + $request = sprintf('subscribers/%s', $subscriber_id); $options = [ 'api_secret' => $this->api_secret, @@ -498,7 +498,7 @@ public function get_subscriber_tags(int $subscriber_id) throw new \InvalidArgumentException(); } - $request = sprintf('/subscribers/%s/tags', $subscriber_id); + $request = sprintf('subscribers/%s/tags', $subscriber_id); $options = [ 'api_key' => $this->api_key,