Skip to content
Open
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
83 changes: 47 additions & 36 deletions src/ConvertKit_API_Traits.php
Original file line number Diff line number Diff line change
Expand Up @@ -818,21 +818,22 @@ public function get_sequence_email(
}

/**
* Updates a sequence
*
* @param integer $sequence_id Sequence ID.
* @param integer $email_id Sequence Email ID.
* @param string|null $subject Subject line of the email.
* @param integer|null $delay_value Number of days or hours to wait before sending this email after the previous one.
* @param string|null $delay_unit Unit for the send delay. Use `days` for schedule-aware delivery, `hours` for a fixed hourly delay.
* @param string|null $preview_text Preview text shown in email clients before the email is opened.
* @param string|null $content HTML body content of the email.
* @param integer|null $email_template_id ID of the email template to use for layout and styling.
* @param boolean|null $published Whether the email is active and will be sent to subscribers.
* @param array<string>|null $send_days Days of the week this email may be sent. Defaults to all 7 days (inherits the sequence schedule). Pass a subset to restrict delivery, or null to reset to all days.
* @param integer|null $position Zero-based position of the email in the sequence. Assigned automatically after the last email if omitted.
*
* @see https://developers.kit.com/api-reference/sequences/create-a-sequence
* Updates a sequence email.
*
* @param integer $sequence_id Sequence ID.
* @param integer $email_id Sequence Email ID.
* @param string|null $subject Subject line of the email.
* @param integer|null $delay_value Number of days or hours to wait before sending this email after the previous one.
* @param string|null $delay_unit Unit for the send delay. Use `days` for schedule-aware delivery, `hours` for a fixed hourly delay.
* @param string|null $preview_text Preview text shown in email clients before the email is opened.
* @param string|null $content HTML body content of the email.
* @param integer|null $email_template_id ID of the email template to use for layout and styling.
* @param boolean|null $published Whether the email is active and will be sent to subscribers.
* @param array<string>|null $send_days Days of the week this email may be sent. Defaults to all 7 days (inherits the sequence schedule). Pass a subset to restrict delivery, or null to reset to all days.
* @param integer|null $position Zero-based position of the email in the sequence. Assigned automatically after the last email if omitted.
* @param boolean $allow_content_loss Confirm changing $email_template_id without $content, when this would discard the email's existing content.
*
* @see https://developers.kit.com/api-reference/sequence-emails/update-a-sequence-email
*
* @return mixed|object
*/
Expand All @@ -848,6 +849,7 @@ public function update_sequence_email(
bool|null $published = null,
array|null $send_days = null,
int|null $position = null,
bool $allow_content_loss = false,
) {
// Build parameters.
$options = ['send_days' => $send_days];
Expand Down Expand Up @@ -879,6 +881,9 @@ public function update_sequence_email(
if (!is_null($position)) {
$options['position'] = $position;
}
if ($allow_content_loss) {
$options['allow_content_loss'] = true;
}

// Send request.
return $this->put(
Expand Down Expand Up @@ -2137,26 +2142,27 @@ public function get_broadcasts_stats(
/**
* Update a broadcast.
*
* @param integer $id Broadcast ID.
* @param string $subject The broadcast email's subject.
* @param string $content The broadcast's email HTML content.
* @param string $description An internal description of this broadcast.
* @param boolean $public Specifies whether or not this is a public post.
* @param \DateTime|null $published_at Specifies the time that this post was published (applicable
* only to public posts).
* @param \DateTime|null $send_at Time that this broadcast should be sent; leave blank to create
* a draft broadcast. If set to a future time, this is the time that
* the broadcast will be scheduled to send.
* @param string $email_address Sending email address; leave blank to use your account's
* default sending email address.
* @param string $email_template_id ID of the email template to use; leave blank to use your
* account's default email template.
* @param string $thumbnail_alt Specify the ALT attribute of the public thumbnail image
* (applicable only to public posts).
* @param string $thumbnail_url Specify the URL of the thumbnail image to accompany the broadcast
* post (applicable only to public posts).
* @param string $preview_text Specify the preview text of the email.
* @param array<string,string> $subscriber_filter Filter subscriber(s) to send the email to.
* @param integer $id Broadcast ID.
* @param string $subject The broadcast email's subject.
* @param string $content The broadcast's email HTML content.
* @param string $description An internal description of this broadcast.
* @param boolean $public Specifies whether or not this is a public post.
* @param \DateTime|null $published_at Specifies the time that this post was published (applicable
* only to public posts).
* @param \DateTime|null $send_at Time that this broadcast should be sent; leave blank to create
* a draft broadcast. If set to a future time, this is the time that
* the broadcast will be scheduled to send.
* @param string $email_address Sending email address; leave blank to use your account's
* default sending email address.
* @param string $email_template_id ID of the email template to use; leave blank to use your
* account's default email template.
* @param string $thumbnail_alt Specify the ALT attribute of the public thumbnail image
* (applicable only to public posts).
* @param string $thumbnail_url Specify the URL of the thumbnail image to accompany the broadcast
* post (applicable only to public posts).
* @param string $preview_text Specify the preview text of the email.
* @param array<string,string> $subscriber_filter Filter subscriber(s) to send the email to.
* @param boolean $allow_content_loss Confirm changing $email_template_id without $content, when this would discard the broadcast's existing content.
*
* @see https://developers.kit.com/api-reference/broadcasts/update-a-broadcast
*
Expand All @@ -2175,7 +2181,8 @@ public function update_broadcast(
string $thumbnail_alt = '',
string $thumbnail_url = '',
string $preview_text = '',
array $subscriber_filter = []
array $subscriber_filter = [],
bool $allow_content_loss = false
) {
$options = [
'email_template_id' => $email_template_id,
Expand Down Expand Up @@ -2206,6 +2213,10 @@ public function update_broadcast(
unset($options['published_at'], $options['thumbnail_alt'], $options['thumbnail_url']);
}

if ($allow_content_loss) {
$options['allow_content_loss'] = true;
}

// Send request.
return $this->put(
sprintf('broadcasts/%s', $id),
Expand Down
126 changes: 126 additions & 0 deletions tests/TestsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -1783,6 +1783,59 @@ public function testCreateGetUpdateAndDeleteSequenceEmail()
$this->assertLastResponseStatusCode(204);
}

/**
* Test that update_sequence_email() returns an error when changing the email template
* without content would discard the email's content, and changes the email template
* when allow_content_loss is specified.
*
* @since 2.9.0
*
* @return void
*/
public function testUpdateSequenceEmailWithAllowContentLoss()
{
$emailTemplateID = $this->getStartingPointEmailTemplateID();
if (!$emailTemplateID) {
$this->markTestSkipped('No Starting point email template exists on the Kit account.');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious why you'd mark this as skipped - shouldn't we have a failure (with an assert that spells out exactly what needs to be done - add a starting place template to the test Kit account)?

}

// Create a draft sequence email with content.
$result = $this->api->create_sequence_email(
sequence_id: (int) $_ENV['CONVERTKIT_API_SEQUENCE_ID'],
subject: 'Test Sequence Email',
delay_value: 1,
delay_unit: 'days',
content: 'Test Content',
email_template_id: (int) $_ENV['CONVERTKIT_API_EMAIL_TEMPLATE_ID'],
published: false
);
$sequenceEmailID = $result->email->id;

// Confirm changing to a Starting point template without content errors, as it would discard the content.
$this->assertApiError(
function () use ($sequenceEmailID, $emailTemplateID) {
return $this->api->update_sequence_email(
sequence_id: (int) $_ENV['CONVERTKIT_API_SEQUENCE_ID'],
email_id: $sequenceEmailID,
email_template_id: $emailTemplateID
);
}
);

// Confirm the email template is changed when allow_content_loss is specified.
$result = $this->api->update_sequence_email(
sequence_id: (int) $_ENV['CONVERTKIT_API_SEQUENCE_ID'],
email_id: $sequenceEmailID,
email_template_id: $emailTemplateID,
allow_content_loss: true
);
$this->assertEquals($emailTemplateID, $result->email->email_template_id);

// Delete Sequence Email.
$this->api->delete_sequence_email((int) $_ENV['CONVERTKIT_API_SEQUENCE_ID'], $sequenceEmailID);
$this->assertLastResponseStatusCode(204);
}

/**
* Test that get_sequence_email() returns the expected data.
*
Expand Down Expand Up @@ -5618,6 +5671,53 @@ public function testCreateAndUpdateDraftBroadcast()
$this->assertLastResponseStatusCode(204);
}

/**
* Test that update_broadcast() returns an error when changing the email template
* without content would discard the broadcast's content, and changes the email
* template when allow_content_loss is specified.
*
* @since 2.9.0
*
* @return void
*/
public function testUpdateBroadcastWithAllowContentLoss()
{
$emailTemplateID = $this->getStartingPointEmailTemplateID();
if (!$emailTemplateID) {
$this->markTestSkipped('No Starting point email template exists on the Kit account.');
}

// Create a broadcast with content.
$result = $this->api->create_broadcast(
subject: 'Test Subject',
content: 'Test Content',
description: 'Test Broadcast from PHP SDK',
email_template_id: $_ENV['CONVERTKIT_API_EMAIL_TEMPLATE_ID']
);
$broadcastID = $result->broadcast->id;

// Set broadcast_ids to ensure broadcast is deleted after test.
$this->broadcast_ids[] = $broadcastID;

// Confirm changing to a Starting point template without content errors, as it would discard the content.
$this->assertApiError(
function () use ($broadcastID, $emailTemplateID) {
return $this->api->update_broadcast(
id: $broadcastID,
email_template_id: (string) $emailTemplateID
);
}
);

// Confirm the email template is changed when allow_content_loss is specified.
$result = $this->api->update_broadcast(
id: $broadcastID,
email_template_id: (string) $emailTemplateID,
allow_content_loss: true
);
$this->assertEquals($emailTemplateID, $result->broadcast->email_template->id);
}

/**
* Test that create_broadcast() works when specifying valid published_at and send_at values.
*
Expand Down Expand Up @@ -7795,6 +7895,32 @@ public function generateWebhookSignature($payload, $secret, $timestamp = null)
);
}

/**
* Returns the ID of an email template in the Starting point category, excluding the
* email template defined in CONVERTKIT_API_EMAIL_TEMPLATE_ID.
*
* @since 2.9.0
*
* @return integer|false
*/
public function getStartingPointEmailTemplateID()
{
$result = $this->api->get_email_templates();

foreach ($result->email_templates as $emailTemplate) {
if ($emailTemplate->category !== 'Starting point') {
continue;
}
if ($emailTemplate->id === (int) $_ENV['CONVERTKIT_API_EMAIL_TEMPLATE_ID']) {
continue;
}

return $emailTemplate->id;
}

return false;
}

/**
* Checks if string is html.
*
Expand Down
Loading