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\API\JSON\ResponseBuilders\SubscribersResponseBuilder;
|
||||||
use MailPoet\Entities\SegmentEntity;
|
use MailPoet\Entities\SegmentEntity;
|
||||||
use MailPoet\Entities\SubscriberEntity;
|
use MailPoet\Entities\SubscriberEntity;
|
||||||
|
use MailPoet\Features\FeaturesController;
|
||||||
use MailPoet\Models\Segment;
|
use MailPoet\Models\Segment;
|
||||||
use MailPoet\Models\Subscriber;
|
use MailPoet\Models\Subscriber;
|
||||||
use MailPoet\Newsletter\Scheduler\WelcomeScheduler;
|
use MailPoet\Newsletter\Scheduler\WelcomeScheduler;
|
||||||
@@ -42,6 +43,12 @@ class Subscribers {
|
|||||||
/** @var NewSubscriberNotificationMailer */
|
/** @var NewSubscriberNotificationMailer */
|
||||||
private $newSubscriberNotificationMailer;
|
private $newSubscriberNotificationMailer;
|
||||||
|
|
||||||
|
/** @var FeaturesController */
|
||||||
|
private $featuresController;
|
||||||
|
|
||||||
|
/** @var WPFunctions */
|
||||||
|
private $wp;
|
||||||
|
|
||||||
public function __construct (
|
public function __construct (
|
||||||
ConfirmationEmailMailer $confirmationEmailMailer,
|
ConfirmationEmailMailer $confirmationEmailMailer,
|
||||||
NewSubscriberNotificationMailer $newSubscriberNotificationMailer,
|
NewSubscriberNotificationMailer $newSubscriberNotificationMailer,
|
||||||
@@ -50,7 +57,9 @@ class Subscribers {
|
|||||||
SubscriberSegmentRepository $subscriberSegmentRepository,
|
SubscriberSegmentRepository $subscriberSegmentRepository,
|
||||||
SubscribersRepository $subscribersRepository,
|
SubscribersRepository $subscribersRepository,
|
||||||
SubscribersResponseBuilder $subscribersResponseBuilder,
|
SubscribersResponseBuilder $subscribersResponseBuilder,
|
||||||
WelcomeScheduler $welcomeScheduler
|
WelcomeScheduler $welcomeScheduler,
|
||||||
|
FeaturesController $featuresController,
|
||||||
|
WPFunctions $wp
|
||||||
) {
|
) {
|
||||||
$this->confirmationEmailMailer = $confirmationEmailMailer;
|
$this->confirmationEmailMailer = $confirmationEmailMailer;
|
||||||
$this->newSubscriberNotificationMailer = $newSubscriberNotificationMailer;
|
$this->newSubscriberNotificationMailer = $newSubscriberNotificationMailer;
|
||||||
@@ -60,6 +69,8 @@ class Subscribers {
|
|||||||
$this->subscribersRepository = $subscribersRepository;
|
$this->subscribersRepository = $subscribersRepository;
|
||||||
$this->subscribersResponseBuilder = $subscribersResponseBuilder;
|
$this->subscribersResponseBuilder = $subscribersResponseBuilder;
|
||||||
$this->welcomeScheduler = $welcomeScheduler;
|
$this->welcomeScheduler = $welcomeScheduler;
|
||||||
|
$this->featuresController = $featuresController;
|
||||||
|
$this->wp = $wp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -144,6 +155,19 @@ class Subscribers {
|
|||||||
APIException::FAILED_TO_SAVE_SUBSCRIBER
|
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
|
// schedule welcome email
|
||||||
|
@@ -6,12 +6,31 @@ use MailPoet\Doctrine\Repository;
|
|||||||
use MailPoet\Entities\SegmentEntity;
|
use MailPoet\Entities\SegmentEntity;
|
||||||
use MailPoet\Entities\SubscriberEntity;
|
use MailPoet\Entities\SubscriberEntity;
|
||||||
use MailPoet\Entities\SubscriberSegmentEntity;
|
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;
|
use MailPoetVendor\Doctrine\ORM\Query\Expr\Join;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @extends Repository<SubscriberSegmentEntity>
|
* @extends Repository<SubscriberSegmentEntity>
|
||||||
*/
|
*/
|
||||||
class SubscriberSegmentRepository extends Repository {
|
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() {
|
protected function getEntityClassName() {
|
||||||
return SubscriberSegmentEntity::class;
|
return SubscriberSegmentEntity::class;
|
||||||
}
|
}
|
||||||
@@ -83,13 +102,27 @@ class SubscriberSegmentRepository extends Repository {
|
|||||||
|
|
||||||
public function createOrUpdate(SubscriberEntity $subscriber, SegmentEntity $segment, string $status): SubscriberSegmentEntity {
|
public function createOrUpdate(SubscriberEntity $subscriber, SegmentEntity $segment, string $status): SubscriberSegmentEntity {
|
||||||
$subscriberSegment = $this->findOneBy(['segment' => $segment, 'subscriber' => $subscriber]);
|
$subscriberSegment = $this->findOneBy(['segment' => $segment, 'subscriber' => $subscriber]);
|
||||||
|
|
||||||
|
$oldStatus = null;
|
||||||
if ($subscriberSegment instanceof SubscriberSegmentEntity) {
|
if ($subscriberSegment instanceof SubscriberSegmentEntity) {
|
||||||
|
$oldStatus = $subscriberSegment->getStatus();
|
||||||
$subscriberSegment->setStatus($status);
|
$subscriberSegment->setStatus($status);
|
||||||
} else {
|
} else {
|
||||||
$subscriberSegment = new SubscriberSegmentEntity($segment, $subscriber, $status);
|
$subscriberSegment = new SubscriberSegmentEntity($segment, $subscriber, $status);
|
||||||
$subscriber->getSubscriberSegments()->add($subscriberSegment);
|
$subscriber->getSubscriberSegments()->add($subscriberSegment);
|
||||||
$this->entityManager->persist($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();
|
$this->entityManager->flush();
|
||||||
return $subscriberSegment;
|
return $subscriberSegment;
|
||||||
}
|
}
|
||||||
|
@@ -4,6 +4,8 @@ namespace MailPoet\Subscription;
|
|||||||
|
|
||||||
use MailPoet\Config\Renderer as TemplateRenderer;
|
use MailPoet\Config\Renderer as TemplateRenderer;
|
||||||
use MailPoet\Entities\StatisticsUnsubscribeEntity;
|
use MailPoet\Entities\StatisticsUnsubscribeEntity;
|
||||||
|
use MailPoet\Entities\SubscriberEntity;
|
||||||
|
use MailPoet\Features\FeaturesController;
|
||||||
use MailPoet\Form\AssetsController;
|
use MailPoet\Form\AssetsController;
|
||||||
use MailPoet\Models\Subscriber;
|
use MailPoet\Models\Subscriber;
|
||||||
use MailPoet\Models\SubscriberSegment;
|
use MailPoet\Models\SubscriberSegment;
|
||||||
@@ -74,6 +76,9 @@ class Pages {
|
|||||||
/** @var TrackingConfig */
|
/** @var TrackingConfig */
|
||||||
private $trackingConfig;
|
private $trackingConfig;
|
||||||
|
|
||||||
|
/** @var FeaturesController */
|
||||||
|
private $featuresController;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
NewSubscriberNotificationMailer $newSubscriberNotificationSender,
|
NewSubscriberNotificationMailer $newSubscriberNotificationSender,
|
||||||
WPFunctions $wp,
|
WPFunctions $wp,
|
||||||
@@ -88,7 +93,8 @@ class Pages {
|
|||||||
ManageSubscriptionFormRenderer $manageSubscriptionFormRenderer,
|
ManageSubscriptionFormRenderer $manageSubscriptionFormRenderer,
|
||||||
SubscriberHandler $subscriberHandler,
|
SubscriberHandler $subscriberHandler,
|
||||||
SubscribersRepository $subscribersRepository,
|
SubscribersRepository $subscribersRepository,
|
||||||
TrackingConfig $trackingConfig
|
TrackingConfig $trackingConfig,
|
||||||
|
FeaturesController $featuresController
|
||||||
) {
|
) {
|
||||||
$this->wp = $wp;
|
$this->wp = $wp;
|
||||||
$this->newSubscriberNotificationSender = $newSubscriberNotificationSender;
|
$this->newSubscriberNotificationSender = $newSubscriberNotificationSender;
|
||||||
@@ -104,6 +110,7 @@ class Pages {
|
|||||||
$this->subscriberHandler = $subscriberHandler;
|
$this->subscriberHandler = $subscriberHandler;
|
||||||
$this->subscribersRepository = $subscribersRepository;
|
$this->subscribersRepository = $subscribersRepository;
|
||||||
$this->trackingConfig = $trackingConfig;
|
$this->trackingConfig = $trackingConfig;
|
||||||
|
$this->featuresController = $featuresController;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function init($action = false, $data = [], $initShortcodes = false, $initPageFilters = false) {
|
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
|
// 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) {
|
if ($originalStatus !== Subscriber::STATUS_SUBSCRIBED || $subscriberData !== null) {
|
||||||
$this->newSubscriberNotificationSender->send($this->subscriber, $subscriberSegments);
|
$this->newSubscriberNotificationSender->send($this->subscriber, $subscriberSegments);
|
||||||
|
@@ -13,6 +13,7 @@ use MailPoet\CustomFields\CustomFieldsRepository;
|
|||||||
use MailPoet\Entities\CustomFieldEntity;
|
use MailPoet\Entities\CustomFieldEntity;
|
||||||
use MailPoet\Entities\SegmentEntity;
|
use MailPoet\Entities\SegmentEntity;
|
||||||
use MailPoet\Entities\SubscriberEntity;
|
use MailPoet\Entities\SubscriberEntity;
|
||||||
|
use MailPoet\Features\FeaturesController;
|
||||||
use MailPoet\Models\ScheduledTask;
|
use MailPoet\Models\ScheduledTask;
|
||||||
use MailPoet\Models\SendingQueue;
|
use MailPoet\Models\SendingQueue;
|
||||||
use MailPoet\Newsletter\Scheduler\WelcomeScheduler;
|
use MailPoet\Newsletter\Scheduler\WelcomeScheduler;
|
||||||
@@ -25,6 +26,7 @@ use MailPoet\Subscribers\SubscriberSegmentRepository;
|
|||||||
use MailPoet\Subscribers\SubscribersRepository;
|
use MailPoet\Subscribers\SubscribersRepository;
|
||||||
use MailPoet\Tasks\Sending;
|
use MailPoet\Tasks\Sending;
|
||||||
use MailPoet\Test\DataFactories\Subscriber as SubscriberFactory;
|
use MailPoet\Test\DataFactories\Subscriber as SubscriberFactory;
|
||||||
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
use MailPoetVendor\Idiorm\ORM;
|
use MailPoetVendor\Idiorm\ORM;
|
||||||
|
|
||||||
class APITest extends \MailPoetTest {
|
class APITest extends \MailPoetTest {
|
||||||
@@ -57,7 +59,9 @@ class APITest extends \MailPoetTest {
|
|||||||
$this->diContainer->get(SubscriberSegmentRepository::class),
|
$this->diContainer->get(SubscriberSegmentRepository::class),
|
||||||
$this->diContainer->get(SubscribersRepository::class),
|
$this->diContainer->get(SubscribersRepository::class),
|
||||||
$this->diContainer->get(SubscribersResponseBuilder::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\Config\Changelog;
|
||||||
use MailPoet\Entities\SegmentEntity;
|
use MailPoet\Entities\SegmentEntity;
|
||||||
use MailPoet\Entities\SubscriberEntity;
|
use MailPoet\Entities\SubscriberEntity;
|
||||||
|
use MailPoet\Features\FeaturesController;
|
||||||
use MailPoet\Newsletter\Scheduler\WelcomeScheduler;
|
use MailPoet\Newsletter\Scheduler\WelcomeScheduler;
|
||||||
use MailPoet\Segments\SegmentsRepository;
|
use MailPoet\Segments\SegmentsRepository;
|
||||||
use MailPoet\Settings\SettingsController;
|
use MailPoet\Settings\SettingsController;
|
||||||
@@ -20,6 +21,7 @@ use MailPoet\Subscribers\RequiredCustomFieldValidator;
|
|||||||
use MailPoet\Subscribers\SubscriberSegmentRepository;
|
use MailPoet\Subscribers\SubscriberSegmentRepository;
|
||||||
use MailPoet\Subscribers\SubscribersRepository;
|
use MailPoet\Subscribers\SubscribersRepository;
|
||||||
use MailPoet\Test\DataFactories\Subscriber as SubscriberFactory;
|
use MailPoet\Test\DataFactories\Subscriber as SubscriberFactory;
|
||||||
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
|
|
||||||
class SubscribersTest extends \MailPoetTest {
|
class SubscribersTest extends \MailPoetTest {
|
||||||
|
|
||||||
@@ -47,7 +49,9 @@ class SubscribersTest extends \MailPoetTest {
|
|||||||
$this->diContainer->get(SubscriberSegmentRepository::class),
|
$this->diContainer->get(SubscriberSegmentRepository::class),
|
||||||
$this->diContainer->get(SubscribersRepository::class),
|
$this->diContainer->get(SubscribersRepository::class),
|
||||||
$this->diContainer->get(SubscribersResponseBuilder::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),
|
'subscribersSegmentRepository' => $this->diContainer->get(SubscriberSegmentRepository::class),
|
||||||
'subscribersResponseBuilder' => $this->diContainer->get(SubscribersResponseBuilder::class),
|
'subscribersResponseBuilder' => $this->diContainer->get(SubscribersResponseBuilder::class),
|
||||||
'settings' => SettingsController::getInstance(),
|
'settings' => SettingsController::getInstance(),
|
||||||
|
'featuresController' => $this->diContainer->get(FeaturesController::class),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -7,6 +7,7 @@ use MailPoet\Config\Renderer;
|
|||||||
use MailPoet\DI\ContainerWrapper;
|
use MailPoet\DI\ContainerWrapper;
|
||||||
use MailPoet\Entities\StatisticsUnsubscribeEntity;
|
use MailPoet\Entities\StatisticsUnsubscribeEntity;
|
||||||
use MailPoet\Entities\SubscriberEntity;
|
use MailPoet\Entities\SubscriberEntity;
|
||||||
|
use MailPoet\Features\FeaturesController;
|
||||||
use MailPoet\Form\AssetsController;
|
use MailPoet\Form\AssetsController;
|
||||||
use MailPoet\Models\Newsletter;
|
use MailPoet\Models\Newsletter;
|
||||||
use MailPoet\Models\NewsletterOption;
|
use MailPoet\Models\NewsletterOption;
|
||||||
@@ -217,7 +218,8 @@ class PagesTest extends \MailPoetTest {
|
|||||||
$container->get(ManageSubscriptionFormRenderer::class),
|
$container->get(ManageSubscriptionFormRenderer::class),
|
||||||
$container->get(SubscriberHandler::class),
|
$container->get(SubscriberHandler::class),
|
||||||
$this->subscribersRepository,
|
$this->subscribersRepository,
|
||||||
$container->get(TrackingConfig::class)
|
$container->get(TrackingConfig::class),
|
||||||
|
$container->get(FeaturesController::class)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user