Add hook for segment subscription
This will be used for a "SegmentSubscribed" trigger for automation that can trigger welcome emails and other actions. [MAILPOET-4136]
This commit is contained in:
@@ -5,6 +5,7 @@ namespace MailPoet\API\MP\v1;
|
||||
use MailPoet\API\JSON\ResponseBuilders\SubscribersResponseBuilder;
|
||||
use MailPoet\Entities\SegmentEntity;
|
||||
use MailPoet\Entities\SubscriberEntity;
|
||||
use MailPoet\Features\FeaturesController;
|
||||
use MailPoet\Models\Segment;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Newsletter\Scheduler\WelcomeScheduler;
|
||||
@@ -42,6 +43,12 @@ class Subscribers {
|
||||
/** @var NewSubscriberNotificationMailer */
|
||||
private $newSubscriberNotificationMailer;
|
||||
|
||||
/** @var FeaturesController */
|
||||
private $featuresController;
|
||||
|
||||
/** @var WPFunctions */
|
||||
private $wp;
|
||||
|
||||
public function __construct (
|
||||
ConfirmationEmailMailer $confirmationEmailMailer,
|
||||
NewSubscriberNotificationMailer $newSubscriberNotificationMailer,
|
||||
@@ -50,7 +57,9 @@ class Subscribers {
|
||||
SubscriberSegmentRepository $subscriberSegmentRepository,
|
||||
SubscribersRepository $subscribersRepository,
|
||||
SubscribersResponseBuilder $subscribersResponseBuilder,
|
||||
WelcomeScheduler $welcomeScheduler
|
||||
WelcomeScheduler $welcomeScheduler,
|
||||
FeaturesController $featuresController,
|
||||
WPFunctions $wp
|
||||
) {
|
||||
$this->confirmationEmailMailer = $confirmationEmailMailer;
|
||||
$this->newSubscriberNotificationMailer = $newSubscriberNotificationMailer;
|
||||
@@ -60,6 +69,8 @@ class Subscribers {
|
||||
$this->subscribersRepository = $subscribersRepository;
|
||||
$this->subscribersResponseBuilder = $subscribersResponseBuilder;
|
||||
$this->welcomeScheduler = $welcomeScheduler;
|
||||
$this->featuresController = $featuresController;
|
||||
$this->wp = $wp;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,6 +155,19 @@ class Subscribers {
|
||||
APIException::FAILED_TO_SAVE_SUBSCRIBER
|
||||
);
|
||||
}
|
||||
|
||||
// when global status changes to subscribed, fire subscribed hook for all subscribed segments
|
||||
if (
|
||||
$this->featuresController->isSupported(FeaturesController::AUTOMATION)
|
||||
&& $subscriber->getStatus() === SubscriberEntity::STATUS_SUBSCRIBED
|
||||
) {
|
||||
$subscriberSegments = $subscriber->getSubscriberSegments();
|
||||
foreach ($subscriberSegments as $subscriberSegment) {
|
||||
if ($subscriberSegment->getStatus() === SubscriberEntity::STATUS_SUBSCRIBED) {
|
||||
$this->wp->doAction('mailpoet_segment_subscribed', $subscriberSegment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// schedule welcome email
|
||||
|
@@ -6,12 +6,31 @@ use MailPoet\Doctrine\Repository;
|
||||
use MailPoet\Entities\SegmentEntity;
|
||||
use MailPoet\Entities\SubscriberEntity;
|
||||
use MailPoet\Entities\SubscriberSegmentEntity;
|
||||
use MailPoet\Features\FeaturesController;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
use MailPoetVendor\Doctrine\ORM\EntityManager;
|
||||
use MailPoetVendor\Doctrine\ORM\Query\Expr\Join;
|
||||
|
||||
/**
|
||||
* @extends Repository<SubscriberSegmentEntity>
|
||||
*/
|
||||
class SubscriberSegmentRepository extends Repository {
|
||||
/** @var FeaturesController */
|
||||
private $featuresController;
|
||||
|
||||
/** @var WPFunctions */
|
||||
private $wp;
|
||||
|
||||
public function __construct(
|
||||
EntityManager $entityManager,
|
||||
FeaturesController $featuresController,
|
||||
WPFunctions $wp
|
||||
) {
|
||||
parent::__construct($entityManager);
|
||||
$this->featuresController = $featuresController;
|
||||
$this->wp = $wp;
|
||||
}
|
||||
|
||||
protected function getEntityClassName() {
|
||||
return SubscriberSegmentEntity::class;
|
||||
}
|
||||
@@ -83,13 +102,27 @@ class SubscriberSegmentRepository extends Repository {
|
||||
|
||||
public function createOrUpdate(SubscriberEntity $subscriber, SegmentEntity $segment, string $status): SubscriberSegmentEntity {
|
||||
$subscriberSegment = $this->findOneBy(['segment' => $segment, 'subscriber' => $subscriber]);
|
||||
|
||||
$oldStatus = null;
|
||||
if ($subscriberSegment instanceof SubscriberSegmentEntity) {
|
||||
$oldStatus = $subscriberSegment->getStatus();
|
||||
$subscriberSegment->setStatus($status);
|
||||
} else {
|
||||
$subscriberSegment = new SubscriberSegmentEntity($segment, $subscriber, $status);
|
||||
$subscriber->getSubscriberSegments()->add($subscriberSegment);
|
||||
$this->entityManager->persist($subscriberSegment);
|
||||
}
|
||||
|
||||
// fire subscribed hook for new subscriptions
|
||||
if (
|
||||
$this->featuresController->isSupported(FeaturesController::AUTOMATION)
|
||||
&& $subscriber->getStatus() === SubscriberEntity::STATUS_SUBSCRIBED
|
||||
&& $subscriberSegment->getStatus() === SubscriberEntity::STATUS_SUBSCRIBED
|
||||
&& $oldStatus !== SubscriberEntity::STATUS_SUBSCRIBED
|
||||
) {
|
||||
$this->wp->doAction('mailpoet_segment_subscribed', $subscriberSegment);
|
||||
}
|
||||
|
||||
$this->entityManager->flush();
|
||||
return $subscriberSegment;
|
||||
}
|
||||
|
@@ -4,6 +4,8 @@ namespace MailPoet\Subscription;
|
||||
|
||||
use MailPoet\Config\Renderer as TemplateRenderer;
|
||||
use MailPoet\Entities\StatisticsUnsubscribeEntity;
|
||||
use MailPoet\Entities\SubscriberEntity;
|
||||
use MailPoet\Features\FeaturesController;
|
||||
use MailPoet\Form\AssetsController;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Models\SubscriberSegment;
|
||||
@@ -74,6 +76,9 @@ class Pages {
|
||||
/** @var TrackingConfig */
|
||||
private $trackingConfig;
|
||||
|
||||
/** @var FeaturesController */
|
||||
private $featuresController;
|
||||
|
||||
public function __construct(
|
||||
NewSubscriberNotificationMailer $newSubscriberNotificationSender,
|
||||
WPFunctions $wp,
|
||||
@@ -88,7 +93,8 @@ class Pages {
|
||||
ManageSubscriptionFormRenderer $manageSubscriptionFormRenderer,
|
||||
SubscriberHandler $subscriberHandler,
|
||||
SubscribersRepository $subscribersRepository,
|
||||
TrackingConfig $trackingConfig
|
||||
TrackingConfig $trackingConfig,
|
||||
FeaturesController $featuresController
|
||||
) {
|
||||
$this->wp = $wp;
|
||||
$this->newSubscriberNotificationSender = $newSubscriberNotificationSender;
|
||||
@@ -104,6 +110,7 @@ class Pages {
|
||||
$this->subscriberHandler = $subscriberHandler;
|
||||
$this->subscribersRepository = $subscribersRepository;
|
||||
$this->trackingConfig = $trackingConfig;
|
||||
$this->featuresController = $featuresController;
|
||||
}
|
||||
|
||||
public function init($action = false, $data = [], $initShortcodes = false, $initPageFilters = false) {
|
||||
@@ -193,6 +200,17 @@ class Pages {
|
||||
);
|
||||
}
|
||||
|
||||
// when global status changes to subscribed, fire subscribed hook for all subscribed segments
|
||||
if ($this->featuresController->isSupported(FeaturesController::AUTOMATION)) {
|
||||
$subscriber = $this->subscribersRepository->findOneById($this->subscriber->id);
|
||||
$segments = $subscriber ? $subscriber->getSubscriberSegments() : [];
|
||||
foreach ($segments as $subscriberSegment) {
|
||||
if ($subscriberSegment->getStatus() === SubscriberEntity::STATUS_SUBSCRIBED) {
|
||||
$this->wp->doAction('mailpoet_segment_subscribed', $subscriberSegment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send new subscriber notification only when status changes to subscribed or there are unconfirmed data to avoid spamming
|
||||
if ($originalStatus !== Subscriber::STATUS_SUBSCRIBED || $subscriberData !== null) {
|
||||
$this->newSubscriberNotificationSender->send($this->subscriber, $subscriberSegments);
|
||||
|
@@ -13,6 +13,7 @@ use MailPoet\CustomFields\CustomFieldsRepository;
|
||||
use MailPoet\Entities\CustomFieldEntity;
|
||||
use MailPoet\Entities\SegmentEntity;
|
||||
use MailPoet\Entities\SubscriberEntity;
|
||||
use MailPoet\Features\FeaturesController;
|
||||
use MailPoet\Models\ScheduledTask;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Newsletter\Scheduler\WelcomeScheduler;
|
||||
@@ -25,6 +26,7 @@ use MailPoet\Subscribers\SubscriberSegmentRepository;
|
||||
use MailPoet\Subscribers\SubscribersRepository;
|
||||
use MailPoet\Tasks\Sending;
|
||||
use MailPoet\Test\DataFactories\Subscriber as SubscriberFactory;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
use MailPoetVendor\Idiorm\ORM;
|
||||
|
||||
class APITest extends \MailPoetTest {
|
||||
@@ -57,7 +59,9 @@ class APITest extends \MailPoetTest {
|
||||
$this->diContainer->get(SubscriberSegmentRepository::class),
|
||||
$this->diContainer->get(SubscribersRepository::class),
|
||||
$this->diContainer->get(SubscribersResponseBuilder::class),
|
||||
Stub::makeEmpty(WelcomeScheduler::class)
|
||||
Stub::makeEmpty(WelcomeScheduler::class),
|
||||
$this->diContainer->get(FeaturesController::class),
|
||||
$this->diContainer->get(WPFunctions::class)
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -11,6 +11,7 @@ use MailPoet\API\MP\v1\Subscribers;
|
||||
use MailPoet\Config\Changelog;
|
||||
use MailPoet\Entities\SegmentEntity;
|
||||
use MailPoet\Entities\SubscriberEntity;
|
||||
use MailPoet\Features\FeaturesController;
|
||||
use MailPoet\Newsletter\Scheduler\WelcomeScheduler;
|
||||
use MailPoet\Segments\SegmentsRepository;
|
||||
use MailPoet\Settings\SettingsController;
|
||||
@@ -20,6 +21,7 @@ use MailPoet\Subscribers\RequiredCustomFieldValidator;
|
||||
use MailPoet\Subscribers\SubscriberSegmentRepository;
|
||||
use MailPoet\Subscribers\SubscribersRepository;
|
||||
use MailPoet\Test\DataFactories\Subscriber as SubscriberFactory;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
|
||||
class SubscribersTest extends \MailPoetTest {
|
||||
|
||||
@@ -47,7 +49,9 @@ class SubscribersTest extends \MailPoetTest {
|
||||
$this->diContainer->get(SubscriberSegmentRepository::class),
|
||||
$this->diContainer->get(SubscribersRepository::class),
|
||||
$this->diContainer->get(SubscribersResponseBuilder::class),
|
||||
Stub::makeEmpty(WelcomeScheduler::class)
|
||||
Stub::makeEmpty(WelcomeScheduler::class),
|
||||
$this->diContainer->get(FeaturesController::class),
|
||||
$this->diContainer->get(WPFunctions::class)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -178,6 +182,7 @@ class SubscribersTest extends \MailPoetTest {
|
||||
'subscribersSegmentRepository' => $this->diContainer->get(SubscriberSegmentRepository::class),
|
||||
'subscribersResponseBuilder' => $this->diContainer->get(SubscribersResponseBuilder::class),
|
||||
'settings' => SettingsController::getInstance(),
|
||||
'featuresController' => $this->diContainer->get(FeaturesController::class),
|
||||
]
|
||||
);
|
||||
|
||||
|
@@ -7,6 +7,7 @@ use MailPoet\Config\Renderer;
|
||||
use MailPoet\DI\ContainerWrapper;
|
||||
use MailPoet\Entities\StatisticsUnsubscribeEntity;
|
||||
use MailPoet\Entities\SubscriberEntity;
|
||||
use MailPoet\Features\FeaturesController;
|
||||
use MailPoet\Form\AssetsController;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\NewsletterOption;
|
||||
@@ -217,7 +218,8 @@ class PagesTest extends \MailPoetTest {
|
||||
$container->get(ManageSubscriptionFormRenderer::class),
|
||||
$container->get(SubscriberHandler::class),
|
||||
$this->subscribersRepository,
|
||||
$container->get(TrackingConfig::class)
|
||||
$container->get(TrackingConfig::class),
|
||||
$container->get(FeaturesController::class)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user