diff --git a/src/ConvertKit_API.php b/src/ConvertKit_API.php index 9ea9c4a..1921d42 100644 --- a/src/ConvertKit_API.php +++ b/src/ConvertKit_API.php @@ -206,6 +206,8 @@ public function get_form_subscriptions( /** * Gets all sequences * + * @see https://developers.convertkit.com/#list-sequences + * * @return false|mixed */ public function get_sequences() @@ -219,39 +221,73 @@ public function get_sequences() } /** - * Gets subscribers to a sequence + * Adds a subscriber to a sequence by email address * - * @param integer $sequence_id Sequence ID. - * @param string $sort_order Sort Order (asc|desc). + * @param integer $sequence_id Sequence ID. + * @param string $email Email Address. + * @param string $first_name First Name. + * @param array $fields Custom Fields. + * @param array $tag_ids Tag ID(s) to subscribe to. + * + * @see https://developers.convertkit.com/#add-subscriber-to-a-sequence * * @return false|mixed */ - public function get_sequence_subscriptions(int $sequence_id, string $sort_order = 'asc') - { - return $this->get( - sprintf('sequences/%s/subscriptions', $sequence_id), - [ - 'api_secret' => $this->api_secret, - 'sort_order' => $sort_order, - ] + public function add_subscriber_to_sequence( + int $sequence_id, + string $email, + string $first_name = '', + array $fields = [], + array $tag_ids = [] + ) { + // Build parameters. + $options = [ + 'api_key' => $this->api_key, + 'email' => $email, + ]; + + if (!empty($first_name)) { + $options['first_name'] = $first_name; + } + if (!empty($fields)) { + $options['fields'] = $fields; + } + if (!empty($tag_ids)) { + $options['tags'] = $tag_ids; + } + + // Send request. + return $this->post( + sprintf('sequences/%s/subscribe', $sequence_id), + $options ); } /** - * Adds a subscriber to a sequence by email address + * Gets subscribers to a sequence + * + * @param integer $sequence_id Sequence ID. + * @param string $sort_order Sort Order (asc|desc). + * @param string $subscriber_state Subscriber State (active,cancelled). + * @param integer $page Page. * - * @param integer $sequence_id Sequence ID. - * @param string $email Email Address. + * @see https://developers.convertkit.com/#list-subscriptions-to-a-sequence * * @return false|mixed */ - public function add_subscriber_to_sequence(int $sequence_id, string $email) - { - return $this->post( - sprintf('courses/%s/subscribe', $sequence_id), + public function get_sequence_subscriptions( + int $sequence_id, + string $sort_order = 'asc', + string $subscriber_state = 'active', + int $page = 1 + ) { + return $this->get( + sprintf('sequences/%s/subscriptions', $sequence_id), [ - 'api_key' => $this->api_key, - 'email' => $email, + 'api_secret' => $this->api_secret, + 'sort_order' => $sort_order, + 'subscriber_state' => $subscriber_state, + 'page' => $page, ] ); } @@ -747,8 +783,8 @@ private function strip_html_head_body_tags(string $markup) /** * Performs a GET request to the API. * - * @param string $endpoint API Endpoint. - * @param array $args Request arguments. + * @param string $endpoint API Endpoint. + * @param array|string> $args Request arguments. * * @throws \InvalidArgumentException If the provided arguments are not of the expected type. * @@ -766,8 +802,8 @@ public function get(string $endpoint, array $args = []) /** * Performs a POST request to the API. * - * @param string $endpoint API Endpoint. - * @param array $args Request arguments. + * @param string $endpoint API Endpoint. + * @param array|string> $args Request arguments. * * @throws \InvalidArgumentException If the provided arguments are not of the expected type. * @@ -785,8 +821,8 @@ public function post(string $endpoint, array $args = []) /** * Performs a PUT request to the API. * - * @param string $endpoint API Endpoint. - * @param array $args Request arguments. + * @param string $endpoint API Endpoint. + * @param array|string> $args Request arguments. * * @throws \InvalidArgumentException If the provided arguments are not of the expected type. * @@ -804,8 +840,8 @@ public function put(string $endpoint, array $args = []) /** * Performs a DELETE request to the API. * - * @param string $endpoint API Endpoint. - * @param array $args Request arguments. + * @param string $endpoint API Endpoint. + * @param array|string> $args Request arguments. * * @throws \InvalidArgumentException If the provided arguments are not of the expected type. * @@ -823,9 +859,9 @@ public function delete(string $endpoint, array $args = []) /** * Performs an API request using Guzzle. * - * @param string $endpoint API Endpoint. - * @param string $method Request method (POST, GET, PUT, PATCH, DELETE). - * @param array $args Request arguments. + * @param string $endpoint API Endpoint. + * @param string $method Request method. + * @param array|string> $args Request arguments. * * @throws \InvalidArgumentException If the provided arguments are not of the expected type. * @throws \Exception If JSON encoding arguments failed. diff --git a/tests/ConvertKitAPITest.php b/tests/ConvertKitAPITest.php index a8bdeee..b0dda34 100644 --- a/tests/ConvertKitAPITest.php +++ b/tests/ConvertKitAPITest.php @@ -248,6 +248,135 @@ public function testGetSequences() $this->assertArrayHasKey('created_at', $sequence); } + /** + * Test that add_subscriber_to_sequence() returns the expected data. + * + * @since 1.0.0 + * + * @return void + */ + public function testAddSubscriberToSequence() + { + $result = $this->api->add_subscriber_to_sequence( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], + $this->generateEmailAddress() + ); + $this->assertInstanceOf('stdClass', $result); + $this->assertArrayHasKey('subscription', get_object_vars($result)); + } + + /** + * Test that add_subscriber_to_sequence() throws a ClientException when an invalid + * sequence is specified. + * + * @since 1.0.0 + * + * @return void + */ + public function testAddSubscriberToSequenceWithInvalidSequenceID() + { + $this->expectException(GuzzleHttp\Exception\ClientException::class); + $result = $this->api->add_subscriber_to_sequence(12345, $this->generateEmailAddress()); + } + + /** + * Test that add_subscriber_to_sequence() throws a ClientException when an invalid + * email address is specified. + * + * @since 1.0.0 + * + * @return void + */ + public function testAddSubscriberToSequenceWithInvalidEmailAddress() + { + $this->expectException(GuzzleHttp\Exception\ClientException::class); + $result = $this->api->add_subscriber_to_sequence($_ENV['CONVERTKIT_API_SEQUENCE_ID'], 'not-an-email-address'); + } + + /** + * Test that add_subscriber_to_sequence() returns the expected data + * when a first_name parameter is included. + * + * @since 1.0.0 + * + * @return void + */ + public function testAddSubscriberToSequenceWithFirstName() + { + $emailAddress = $this->generateEmailAddress(); + $firstName = 'First Name'; + $result = $this->api->add_subscriber_to_sequence( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], + $emailAddress, + $firstName + ); + + $this->assertInstanceOf('stdClass', $result); + $this->assertArrayHasKey('subscription', get_object_vars($result)); + + // Fetch subscriber from API to confirm the first name was saved. + $subscriber = $this->api->get_subscriber($result->subscription->subscriber->id); + $this->assertEquals($subscriber->subscriber->email_address, $emailAddress); + $this->assertEquals($subscriber->subscriber->first_name, $firstName); + } + + /** + * Test that add_subscriber_to_sequence() returns the expected data + * when custom field data is included. + * + * @since 1.0.0 + * + * @return void + */ + public function testAddSubscriberToSequenceWithCustomFields() + { + $result = $this->api->add_subscriber_to_sequence( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], + $this->generateEmailAddress(), + 'First Name', + [ + 'last_name' => 'Last Name', + ] + ); + + // Check subscription object returned. + $this->assertInstanceOf('stdClass', $result); + $this->assertArrayHasKey('subscription', get_object_vars($result)); + + // Fetch subscriber from API to confirm the custom fields were saved. + $subscriber = $this->api->get_subscriber($result->subscription->subscriber->id); + $this->assertEquals($subscriber->subscriber->fields->last_name, 'Last Name'); + } + + /** + * Test that add_subscriber_to_sequence() returns the expected data + * when custom field data is included. + * + * @since 1.0.0 + * + * @return void + */ + public function testAddSubscriberToSequenceWithTagID() + { + $result = $this->api->add_subscriber_to_sequence( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], + $this->generateEmailAddress(), + 'First Name', + [], + [ + (int) $_ENV['CONVERTKIT_API_TAG_ID'] + ] + ); + + // Check subscription object returned. + $this->assertInstanceOf('stdClass', $result); + $this->assertArrayHasKey('subscription', get_object_vars($result)); + + // Fetch subscriber tags from API to confirm the tag saved. + $subscriberTags = $this->api->get_subscriber_tags($result->subscription->subscriber->id); + $this->assertEquals($subscriberTags->tags[0]->id, $_ENV['CONVERTKIT_API_TAG_ID']); + } + /** * Test that get_sequence_subscriptions() returns the expected data. * @@ -305,20 +434,6 @@ public function testGetSequenceSubscriptionsWithDescSortOrder() ); } - /** - * Test that get_sequence_subscriptions() throws a ClientException when an invalid - * sequence ID is specified. - * - * @since 1.0.0 - * - * @return void - */ - public function testGetSequenceSubscriptionsWithInvalidSequenceID() - { - $this->expectException(GuzzleHttp\Exception\ClientException::class); - $result = $this->api->get_sequence_subscriptions(12345); - } - /** * Test that get_sequence_subscriptions() throws a ClientException when an invalid * sort order is specified. @@ -334,48 +449,17 @@ public function testGetSequenceSubscriptionsWithInvalidSortOrder() } /** - * Test that add_subscriber_to_sequence() returns the expected data. - * - * @since 1.0.0 - * - * @return void - */ - public function testAddSubscriberToSequence() - { - $result = $this->api->add_subscriber_to_sequence( - $_ENV['CONVERTKIT_API_SEQUENCE_ID'], - $this->generateEmailAddress() - ); - $this->assertInstanceOf('stdClass', $result); - $this->assertArrayHasKey('subscription', get_object_vars($result)); - } - - /** - * Test that add_subscriber_to_sequence() throws a ClientException when an invalid - * sequence is specified. - * - * @since 1.0.0 - * - * @return void - */ - public function testAddSubscriberToSequenceWithInvalidSequenceID() - { - $this->expectException(GuzzleHttp\Exception\ClientException::class); - $result = $this->api->add_subscriber_to_sequence(12345, $this->generateEmailAddress()); - } - - /** - * Test that add_subscriber_to_sequence() throws a ClientException when an invalid - * email address is specified. + * Test that get_sequence_subscriptions() throws a ClientException when an invalid + * sequence ID is specified. * * @since 1.0.0 * * @return void */ - public function testAddSubscriberToSequenceWithInvalidEmailAddress() + public function testGetSequenceSubscriptionsWithInvalidSequenceID() { $this->expectException(GuzzleHttp\Exception\ClientException::class); - $result = $this->api->add_subscriber_to_sequence($_ENV['CONVERTKIT_API_SEQUENCE_ID'], 'not-an-email-address'); + $result = $this->api->get_sequence_subscriptions(12345); } /**