From a6a95ec3cb32e687c8c8d156d7266b107ff7cdd3 Mon Sep 17 00:00:00 2001 From: Erick Danzer Date: Mon, 10 Nov 2025 13:35:46 -0700 Subject: [PATCH 1/4] Forms: improve MailPoet subscriber handling --- .../service/class-mailpoet-integration.php | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/projects/packages/forms/src/service/class-mailpoet-integration.php b/projects/packages/forms/src/service/class-mailpoet-integration.php index c0fa0f715a64c..3bf110bd14af6 100644 --- a/projects/packages/forms/src/service/class-mailpoet-integration.php +++ b/projects/packages/forms/src/service/class-mailpoet-integration.php @@ -104,13 +104,45 @@ protected static function get_or_create_list_id( $mailpoet_api, $list_id = null, * @return array|null Subscriber data on success, or null on failure. */ protected static function add_subscriber_to_list( $mailpoet_api, $list_id, $subscriber_data ) { + $email = $subscriber_data['email']; try { - $subscriber = $mailpoet_api->addSubscriber( - $subscriber_data, - array( $list_id ) - ); - return $subscriber; + $existing = $mailpoet_api->getSubscriber( $email ); + + // If already subscribed to list, do nothing. + if ( ! empty( $existing['subscriptions'] ) && is_array( $existing['subscriptions'] ) ) { + foreach ( $existing['subscriptions'] as $subscription ) { + if ( + isset( $subscription['segment_id'] ) && isset( $subscription['status'] ) && + (string) $subscription['segment_id'] === (string) $list_id && + 'subscribed' === $subscription['status'] + ) { + return $existing; + } + } + } + + // Subscriber exists but is not on the target list, so add to list. + // If subscriber already confirmed ('subscribed'), do not resend confirmation. + $options = array(); + if ( isset( $existing['status'] ) && 'subscribed' === $existing['status'] ) { + $options['send_confirmation_email'] = false; + } + + return $mailpoet_api->subscribeToLists( $email, array( $list_id ), $options ); } catch ( \Exception $e ) { + // MailPoet returns APIException code 4 if "subscriber does not exist". + // In that case, take no action and next try statement will add subscriber. + // For other exceptions, return null. + $not_found_code = 4; + if ( method_exists( $e, 'getCode' ) && (int) $e->getCode() !== $not_found_code ) { + return null; + } + } + + // Subscriber does not exist, so add new subscriber to list and send confirmation email. + try { + return $mailpoet_api->addSubscriber( $subscriber_data, array( $list_id ) ); + } catch ( \Exception $e ) { // phpcs:ignore Squiz.PHP.EmptyCatchComment return null; } } From ee7195a3b80699de63e48abd14c6fcb93a316ead Mon Sep 17 00:00:00 2001 From: Erick Danzer Date: Mon, 10 Nov 2025 13:36:41 -0700 Subject: [PATCH 2/4] changelog --- .../changelog/update-forms-mailpoet-subscriber-confirmation | 4 ++++ .../changelog/update-forms-mailpoet-subscriber-confirmation | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 projects/packages/forms/changelog/update-forms-mailpoet-subscriber-confirmation create mode 100644 projects/plugins/jetpack/changelog/update-forms-mailpoet-subscriber-confirmation diff --git a/projects/packages/forms/changelog/update-forms-mailpoet-subscriber-confirmation b/projects/packages/forms/changelog/update-forms-mailpoet-subscriber-confirmation new file mode 100644 index 0000000000000..93e1cc1545f5a --- /dev/null +++ b/projects/packages/forms/changelog/update-forms-mailpoet-subscriber-confirmation @@ -0,0 +1,4 @@ +Significance: minor +Type: changed + +Forms: improve MailPoet subscriber handling. diff --git a/projects/plugins/jetpack/changelog/update-forms-mailpoet-subscriber-confirmation b/projects/plugins/jetpack/changelog/update-forms-mailpoet-subscriber-confirmation new file mode 100644 index 0000000000000..a6074215bef75 --- /dev/null +++ b/projects/plugins/jetpack/changelog/update-forms-mailpoet-subscriber-confirmation @@ -0,0 +1,4 @@ +Significance: minor +Type: enhancement + +Forms: improve MailPoet subscriber handling. From cfa217101e156e56d8acff182befe520670e486f Mon Sep 17 00:00:00 2001 From: Erick Danzer Date: Wed, 12 Nov 2025 13:43:38 -0700 Subject: [PATCH 3/4] Use MailPoet status constant --- .../forms/src/service/class-mailpoet-integration.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/projects/packages/forms/src/service/class-mailpoet-integration.php b/projects/packages/forms/src/service/class-mailpoet-integration.php index 3bf110bd14af6..90d60d1fd3262 100644 --- a/projects/packages/forms/src/service/class-mailpoet-integration.php +++ b/projects/packages/forms/src/service/class-mailpoet-integration.php @@ -108,13 +108,18 @@ protected static function add_subscriber_to_list( $mailpoet_api, $list_id, $subs try { $existing = $mailpoet_api->getSubscriber( $email ); + // Normalize "subscribed" status using MailPoet constant when available. + $status_subscribed = class_exists( '\MailPoet\Entities\SubscriberEntity' ) + ? \MailPoet\Entities\SubscriberEntity::STATUS_SUBSCRIBED + : 'subscribed'; + // If already subscribed to list, do nothing. if ( ! empty( $existing['subscriptions'] ) && is_array( $existing['subscriptions'] ) ) { foreach ( $existing['subscriptions'] as $subscription ) { if ( isset( $subscription['segment_id'] ) && isset( $subscription['status'] ) && (string) $subscription['segment_id'] === (string) $list_id && - 'subscribed' === $subscription['status'] + $status_subscribed === $subscription['status'] ) { return $existing; } @@ -124,7 +129,7 @@ protected static function add_subscriber_to_list( $mailpoet_api, $list_id, $subs // Subscriber exists but is not on the target list, so add to list. // If subscriber already confirmed ('subscribed'), do not resend confirmation. $options = array(); - if ( isset( $existing['status'] ) && 'subscribed' === $existing['status'] ) { + if ( isset( $existing['status'] ) && $existing['status'] === $status_subscribed ) { $options['send_confirmation_email'] = false; } From 8e1216f20fca91ea587c4c711ca3b28183f18c68 Mon Sep 17 00:00:00 2001 From: Erick Danzer Date: Wed, 12 Nov 2025 13:56:03 -0700 Subject: [PATCH 4/4] Fix phan issue --- .../packages/forms/src/service/class-mailpoet-integration.php | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/packages/forms/src/service/class-mailpoet-integration.php b/projects/packages/forms/src/service/class-mailpoet-integration.php index 90d60d1fd3262..ec166bc7cc4b8 100644 --- a/projects/packages/forms/src/service/class-mailpoet-integration.php +++ b/projects/packages/forms/src/service/class-mailpoet-integration.php @@ -110,6 +110,7 @@ protected static function add_subscriber_to_list( $mailpoet_api, $list_id, $subs // Normalize "subscribed" status using MailPoet constant when available. $status_subscribed = class_exists( '\MailPoet\Entities\SubscriberEntity' ) + // @phan-suppress-next-line PhanUndeclaredClassConstant ? \MailPoet\Entities\SubscriberEntity::STATUS_SUBSCRIBED : 'subscribed';