Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 67 additions & 31 deletions src/ConvertKit_API.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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<string, string> $fields Custom Fields.
* @param array<string, int> $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,
]
);
}
Expand Down Expand Up @@ -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<string, int|string> $args Request arguments.
* @param string $endpoint API Endpoint.
* @param array<string, int|string|array<string, int|string>|string> $args Request arguments.
*
* @throws \InvalidArgumentException If the provided arguments are not of the expected type.
*
Expand All @@ -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<string, int|string> $args Request arguments.
* @param string $endpoint API Endpoint.
* @param array<string, int|string|array<string, int|string>|string> $args Request arguments.
*
* @throws \InvalidArgumentException If the provided arguments are not of the expected type.
*
Expand All @@ -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<string, int|string> $args Request arguments.
* @param string $endpoint API Endpoint.
* @param array<string, int|string|array<string, int|string>|string> $args Request arguments.
*
* @throws \InvalidArgumentException If the provided arguments are not of the expected type.
*
Expand All @@ -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<string, int|string> $args Request arguments.
* @param string $endpoint API Endpoint.
* @param array<string, int|string|array<string, int|string>|string> $args Request arguments.
*
* @throws \InvalidArgumentException If the provided arguments are not of the expected type.
*
Expand All @@ -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<string, int|string> $args Request arguments.
* @param string $endpoint API Endpoint.
* @param string $method Request method.
* @param array<string, int|string|array<string, int|string>|string> $args Request arguments.
*
* @throws \InvalidArgumentException If the provided arguments are not of the expected type.
* @throws \Exception If JSON encoding arguments failed.
Expand Down
182 changes: 133 additions & 49 deletions tests/ConvertKitAPITest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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.
Expand All @@ -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);
}

/**
Expand Down