Remove usages of MailPoet\Tasks\Sending from welcome scheduler

[MAILPOET-4375]
This commit is contained in:
Jan Jakes
2023-10-24 09:58:25 +02:00
committed by Aschepikov
parent 728e1781c6
commit b42d579b67
4 changed files with 69 additions and 58 deletions

View File

@@ -19,7 +19,6 @@ use MailPoet\Subscribers\SubscriberListingRepository;
use MailPoet\Subscribers\SubscriberSaveController;
use MailPoet\Subscribers\SubscriberSegmentRepository;
use MailPoet\Subscribers\SubscribersRepository;
use MailPoet\Tasks\Sending;
use MailPoet\Util\Helpers;
use MailPoet\WP\Functions as WPFunctions;
use MailPoetVendor\Carbon\Carbon;
@@ -314,17 +313,14 @@ class Subscribers {
* @throws APIException
*/
protected function _scheduleWelcomeNotification(SubscriberEntity $subscriber, array $segments) {
$result = $this->welcomeScheduler->scheduleSubscriberWelcomeNotification($subscriber->getId(), $segments);
if (is_array($result)) {
foreach ($result as $queue) {
if ($queue instanceof Sending && $queue->getErrors()) {
throw new APIException(
// translators: %s is a comma-separated list of errors
sprintf(__('Subscriber added, but welcome email failed to send: %s', 'mailpoet'), strtolower(implode(', ', $queue->getErrors()))),
APIException::WELCOME_FAILED_TO_SEND
);
}
}
try {
$this->welcomeScheduler->scheduleSubscriberWelcomeNotification($subscriber->getId(), $segments);
} catch (\Throwable $e) {
throw new APIException(
// translators: %s is an error message
sprintf(__('Subscriber added, but welcome email failed to send: %s', 'mailpoet'), $e->getMessage()),
APIException::WELCOME_FAILED_TO_SEND
);
}
}

View File

@@ -2,9 +2,11 @@
namespace MailPoet\Newsletter\Scheduler;
use MailPoet\Cron\Workers\SendingQueue\SendingQueue;
use MailPoet\Entities\NewsletterEntity;
use MailPoet\Entities\NewsletterOptionFieldEntity;
use MailPoet\Entities\ScheduledTaskEntity;
use MailPoet\Entities\ScheduledTaskSubscriberEntity;
use MailPoet\Entities\SegmentEntity;
use MailPoet\Entities\SendingQueueEntity;
use MailPoet\Entities\SubscriberEntity;
@@ -12,12 +14,15 @@ use MailPoet\Newsletter\NewslettersRepository;
use MailPoet\Newsletter\Sending\ScheduledTasksRepository;
use MailPoet\Segments\SegmentsRepository;
use MailPoet\Subscribers\SubscribersRepository;
use MailPoet\Tasks\Sending as SendingTask;
use MailPoetVendor\Doctrine\ORM\EntityManager;
class WelcomeScheduler {
const WORDPRESS_ALL_ROLES = 'mailpoet_all';
/** @var EntityManager */
private $entityManager;
/** @var SubscribersRepository */
private $subscribersRepository;
@@ -34,12 +39,14 @@ class WelcomeScheduler {
private $scheduler;
public function __construct(
EntityManager $entityManager,
SubscribersRepository $subscribersRepository,
SegmentsRepository $segmentsRepository,
NewslettersRepository $newslettersRepository,
ScheduledTasksRepository $scheduledTasksRepository,
Scheduler $scheduler
) {
$this->entityManager = $entityManager;
$this->subscribersRepository = $subscribersRepository;
$this->segmentsRepository = $segmentsRepository;
$this->newslettersRepository = $newslettersRepository;
@@ -47,22 +54,16 @@ class WelcomeScheduler {
$this->scheduler = $scheduler;
}
public function scheduleSubscriberWelcomeNotification($subscriberId, $segments) {
public function scheduleSubscriberWelcomeNotification($subscriberId, $segments): void {
$newsletters = $this->newslettersRepository->findActiveByTypes([NewsletterEntity::TYPE_WELCOME]);
if (empty($newsletters)) return false;
$result = [];
foreach ($newsletters as $newsletter) {
if (
$newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_EVENT) === 'segment' &&
in_array($newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_SEGMENT), $segments)
) {
$sendingTask = $this->createWelcomeNotificationSendingTask($newsletter, $subscriberId);
if ($sendingTask) {
$result[] = $sendingTask;
}
$this->createWelcomeNotificationSendingTask($newsletter, $subscriberId);
}
}
return $result ?: false;
}
public function scheduleWPUserWelcomeNotification(
@@ -97,7 +98,7 @@ class WelcomeScheduler {
}
}
public function createWelcomeNotificationSendingTask(NewsletterEntity $newsletter, $subscriberId) {
public function createWelcomeNotificationSendingTask(NewsletterEntity $newsletter, $subscriberId): void {
$subscriber = $this->subscribersRepository->findOneById($subscriberId);
if (!($subscriber instanceof SubscriberEntity) || $subscriber->getDeletedAt() !== null) {
return;
@@ -118,28 +119,31 @@ class WelcomeScheduler {
if (!empty($previouslyScheduledNotification)) {
return;
}
$sendingTask = SendingTask::create();
$sendingTask->newsletterId = $newsletter->getId();
$sendingTask->setSubscribers([$subscriberId]);
$sendingTask->status = SendingQueueEntity::STATUS_SCHEDULED;
$sendingTask->priority = SendingQueueEntity::PRIORITY_HIGH;
$sendingTask->scheduledAt = $this->scheduler->getScheduledTimeWithDelay(
// task
$task = new ScheduledTaskEntity();
$task->setType(SendingQueue::TASK_TYPE);
$task->setStatus(ScheduledTaskEntity::STATUS_SCHEDULED);
$task->setPriority(ScheduledTaskEntity::PRIORITY_HIGH);
$task->setScheduledAt($this->scheduler->getScheduledTimeWithDelay(
$newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_AFTER_TIME_TYPE),
$newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_AFTER_TIME_NUMBER)
);
));
$this->entityManager->persist($task);
$savedSendingTask = $sendingTask->save();
// queue
$queue = new SendingQueueEntity();
$queue->setTask($task);
$queue->setNewsletter($newsletter);
$queue->setSubscribers((string)$subscriberId);
$task->setSendingQueue($queue);
$this->entityManager->persist($queue);
// Refreshing this entity here is needed while we are still using Paris to create the scheduled tasks and queues
// in the code above using \MailPoet\Tasks\Sending class. Doing this should avoid bugs where the loaded entity contain
// stale data after the corresponding entry in the database is updated using Paris. This code can be removed once
// https://mailpoet.atlassian.net/browse/MAILPOET-4375 is finished. Currently, if this code is removed a few integration
// tests fail (see https://app.circleci.com/pipelines/github/mailpoet/mailpoet/14806/workflows/0d441848-16db-461a-88ec-87bed101fe36/jobs/251385/tests#failed-test-0).
$scheduledTaskEntity = $this->scheduledTasksRepository->findOneScheduledByNewsletterAndSubscriber($newsletter, $subscriber);
if ($scheduledTaskEntity instanceof ScheduledTaskEntity) {
$this->scheduledTasksRepository->refresh($scheduledTaskEntity);
}
// task subscriber
$taskSubscriber = new ScheduledTaskSubscriberEntity($task, $subscriber);
$task->getSubscribers()->add($taskSubscriber);
$this->entityManager->persist($taskSubscriber);
return $savedSendingTask;
$this->entityManager->flush();
}
}

View File

@@ -15,8 +15,6 @@ use MailPoet\CustomFields\CustomFieldsRepository;
use MailPoet\Entities\CustomFieldEntity;
use MailPoet\Entities\SegmentEntity;
use MailPoet\Entities\SubscriberEntity;
use MailPoet\Models\ScheduledTask;
use MailPoet\Models\SendingQueue;
use MailPoet\Newsletter\Scheduler\WelcomeScheduler;
use MailPoet\Segments\SegmentsRepository;
use MailPoet\Settings\SettingsController;
@@ -26,7 +24,6 @@ use MailPoet\Subscribers\RequiredCustomFieldValidator;
use MailPoet\Subscribers\SubscriberSaveController;
use MailPoet\Subscribers\SubscriberSegmentRepository;
use MailPoet\Subscribers\SubscribersRepository;
use MailPoet\Tasks\Sending;
use MailPoet\Test\DataFactories\Segment as SegmentFactory;
use MailPoet\Test\DataFactories\Subscriber as SubscriberFactory;
use MailPoetVendor\Carbon\Carbon;
@@ -610,15 +607,13 @@ class SubscribersTest extends \MailPoetTest {
public function testItThrowsIfWelcomeEmailFails() {
$settings = SettingsController::getInstance();
$settings->set('signup_confirmation.enabled', false);
$task = ScheduledTask::create();
$task->type = 'sending';
$task->setError("Big Error");
$sendingStub = Sending::create($task, SendingQueue::create());
$segment = $this->getSegment();
$subscribers = Stub::copy($this->getSubscribers(), [
'welcomeScheduler' => $this->make('MailPoet\Newsletter\Scheduler\WelcomeScheduler', [
'scheduleSubscriberWelcomeNotification' => [$sendingStub],
'scheduleSubscriberWelcomeNotification' => function () {
throw new \Exception();
},
]),
]);
$API = $this->getApi($subscribers);

View File

@@ -9,18 +9,23 @@ use MailPoet\Entities\SendingQueueEntity;
use MailPoet\Entities\SubscriberEntity;
use MailPoet\Newsletter\NewslettersRepository;
use MailPoet\Newsletter\Sending\ScheduledTasksRepository;
use MailPoet\Newsletter\Sending\SendingQueuesRepository;
use MailPoet\Segments\SegmentsRepository;
use MailPoet\Subscribers\SubscribersRepository;
use MailPoet\Tasks\Sending as SendingTask;
use MailPoet\Test\DataFactories\NewsletterOption;
use MailPoet\WP\Functions as WPFunctions;
use MailPoetVendor\Carbon\Carbon;
use MailPoetVendor\Doctrine\ORM\EntityManager;
class WelcomeTest extends \MailPoetTest {
/** @var SegmentsRepository */
private $segmentRepository;
/** @var SendingQueuesRepository */
private $sendingQueuesRepository;
/** @var WelcomeScheduler */
private $welcomeScheduler;
@@ -39,6 +44,7 @@ class WelcomeTest extends \MailPoetTest {
public function _before() {
parent::_before();
$this->segmentRepository = $this->diContainer->get(SegmentsRepository::class);
$this->sendingQueuesRepository = $this->diContainer->get(SendingQueuesRepository::class);
$this->welcomeScheduler = $this->diContainer->get(WelcomeScheduler::class);
$this->subscriber = $this->createSubscriber('welcome_test_1@example.com');
$this->segment = $this->segmentRepository->createOrUpdate('welcome_segment');
@@ -203,7 +209,7 @@ class WelcomeTest extends \MailPoetTest {
$segment3 = $this->segmentRepository->createOrUpdate('Segment 3');
// queue is created and scheduled for delivery one day later
$result = $this->welcomeScheduler->scheduleSubscriberWelcomeNotification(
$this->welcomeScheduler->scheduleSubscriberWelcomeNotification(
$this->subscriber->getId(),
$segments = [
$this->segment->getId(),
@@ -222,7 +228,10 @@ class WelcomeTest extends \MailPoetTest {
$this->assertInstanceOf(\DateTimeInterface::class, $scheduledAt);
verify($scheduledAt->format('Y-m-d H:i'))
->equals($currentTime->addDay()->format('Y-m-d H:i'));
verify($result[0]->id())->equals($queue->getId());
$queues = $this->sendingQueuesRepository->findAll();
$this->assertCount(1, $queues);
$this->assertSame($queue, $queues[0]);
}
public function testItDoesNotScheduleWelcomeNotificationWhenSubscriberIsInTrash() {
@@ -239,11 +248,13 @@ class WelcomeTest extends \MailPoetTest {
$trashedSubscriber->setDeletedAt(Carbon::now());
$this->entityManager->flush();
// subscriber welcome notification is not scheduled
$result = $this->welcomeScheduler->scheduleSubscriberWelcomeNotification(
$this->welcomeScheduler->scheduleSubscriberWelcomeNotification(
$trashedSubscriber->getId(),
$segments = [$this->segment->getId()]
);
verify($result)->false();
$queues = $this->sendingQueuesRepository->findAll();
$this->assertEmpty($queues);
}
public function testItDoesNotScheduleWelcomeNotificationWhenSegmentIsInTrash() {
@@ -259,27 +270,31 @@ class WelcomeTest extends \MailPoetTest {
$this->segment->setDeletedAt(Carbon::now());
$this->entityManager->flush();
// subscriber welcome notification is not scheduled
$result = $this->welcomeScheduler->scheduleSubscriberWelcomeNotification(
$this->welcomeScheduler->scheduleSubscriberWelcomeNotification(
$this->subscriber->getId(),
$segments = [$this->segment->getId()]
);
verify($result)->false();
$queues = $this->sendingQueuesRepository->findAll();
$this->assertEmpty($queues);
}
public function itDoesNotScheduleAnythingWhenNewsletterDoesNotExist() {
// subscriber welcome notification is not scheduled
$result = $this->welcomeScheduler->scheduleSubscriberWelcomeNotification(
$this->welcomeScheduler->scheduleSubscriberWelcomeNotification(
$this->subscriber->getId(),
$segments = []
);
verify($result)->false();
$queues = $this->sendingQueuesRepository->findAll();
$this->assertEmpty($queues);
// WP user welcome notification is not scheduled
$result = $this->welcomeScheduler->scheduleWPUserWelcomeNotification(
$this->welcomeScheduler->scheduleWPUserWelcomeNotification(
$this->subscriber->getId(),
$wpUser = ['roles' => ['editor']]
);
verify($result)->false();
$queues = $this->sendingQueuesRepository->findAll();
$this->assertEmpty($queues);
}
public function testItDoesNotScheduleWPUserWelcomeNotificationWhenRoleHasNotChanged() {
@@ -453,6 +468,7 @@ class WelcomeTest extends \MailPoetTest {
->method('currentTime')
->willReturn($currentTime->getTimestamp());
return new WelcomeScheduler(
$this->diContainer->get(EntityManager::class),
$this->diContainer->get(SubscribersRepository::class),
$this->segmentRepository,
$this->diContainer->get(NewslettersRepository::class),