From a1e96c63a0cd11357db666e3eee8c875328b64fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lys=C3=BD?= Date: Wed, 28 Sep 2022 15:37:20 +0200 Subject: [PATCH] Remove old model usages from AutomaticEmailScheduler [MAILPOET-4372] --- .../Scheduler/AutomaticEmailScheduler.php | 105 +++++++++++++----- .../ScheduledTaskSubscribersRepository.php | 9 ++ .../Sending/ScheduledTasksRepository.php | 17 +++ .../Sending/SendingQueuesRepository.php | 9 ++ 4 files changed, 110 insertions(+), 30 deletions(-) diff --git a/mailpoet/lib/Newsletter/Scheduler/AutomaticEmailScheduler.php b/mailpoet/lib/Newsletter/Scheduler/AutomaticEmailScheduler.php index 57111ffbf4..f1cf0ba1a7 100644 --- a/mailpoet/lib/Newsletter/Scheduler/AutomaticEmailScheduler.php +++ b/mailpoet/lib/Newsletter/Scheduler/AutomaticEmailScheduler.php @@ -2,23 +2,46 @@ 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\SendingQueueEntity; -use MailPoet\Models\ScheduledTask; -use MailPoet\Models\ScheduledTaskSubscriber; -use MailPoet\Models\SendingQueue; -use MailPoet\Tasks\Sending as SendingTask; +use MailPoet\Newsletter\Sending\ScheduledTasksRepository; +use MailPoet\Newsletter\Sending\ScheduledTaskSubscribersRepository; +use MailPoet\Newsletter\Sending\SendingQueuesRepository; +use MailPoet\Subscribers\SubscribersRepository; class AutomaticEmailScheduler { /** @var Scheduler */ private $scheduler; + /** @var ScheduledTasksRepository */ + private $scheduledTasksRepository; + + /** @var SendingQueuesRepository */ + private $sendingQueuesRepository; + + /** @var ScheduledTaskSubscribersRepository */ + private $scheduledTaskSubscribersRepository; + + /** @var SubscribersRepository */ + private $subscribersRepository; + public function __construct( - Scheduler $scheduler + Scheduler $scheduler, + ScheduledTasksRepository $scheduledTasksRepository, + ScheduledTaskSubscribersRepository $scheduledTaskSubscribersRepository, + SendingQueuesRepository $sendingQueuesRepository, + SubscribersRepository $subscribersRepository ) { $this->scheduler = $scheduler; + $this->scheduledTasksRepository = $scheduledTasksRepository; + $this->scheduledTaskSubscribersRepository = $scheduledTaskSubscribersRepository; + $this->sendingQueuesRepository = $sendingQueuesRepository; + $this->subscribersRepository = $subscribersRepository; } public function scheduleAutomaticEmail(string $group, string $event, $schedulingCondition = false, $subscriberId = false, $meta = false, $metaModifier = null) { @@ -55,7 +78,7 @@ class AutomaticEmailScheduler { } // try to find existing scheduled task for given subscriber - $task = ScheduledTask::findOneScheduledByNewsletterIdAndSubscriberId($newsletter->getId(), $subscriberId); + $task = $this->scheduledTasksRepository->findOneScheduledByNewsletterAndSubscriberId($newsletter, $subscriberId); if ($task) { $this->rescheduleAutomaticEmailSendingTask($newsletter, $task, $meta); } else { @@ -76,7 +99,7 @@ class AutomaticEmailScheduler { } // try to find existing scheduled task for given subscriber - $task = ScheduledTask::findOneScheduledByNewsletterIdAndSubscriberId($newsletter->getId(), $subscriberId); + $task = $this->scheduledTasksRepository->findOneScheduledByNewsletterAndSubscriberId($newsletter, $subscriberId); if ($task) { $this->rescheduleAutomaticEmailSendingTask($newsletter, $task); } @@ -95,44 +118,66 @@ class AutomaticEmailScheduler { } // try to find existing scheduled task for given subscriber - $task = ScheduledTask::findOneScheduledByNewsletterIdAndSubscriberId($newsletter->getId(), $subscriberId); + $task = $this->scheduledTasksRepository->findOneScheduledByNewsletterAndSubscriberId($newsletter, $subscriberId); if ($task) { - SendingQueue::where('task_id', $task->id)->deleteMany(); - ScheduledTaskSubscriber::where('task_id', $task->id)->deleteMany(); - $task->delete(); + $this->sendingQueuesRepository->deleteByTask($task); + $this->scheduledTaskSubscribersRepository->deleteByTask($task); + $this->scheduledTasksRepository->remove($task); + $this->scheduledTasksRepository->flush(); } } } public function createAutomaticEmailSendingTask(NewsletterEntity $newsletter, $subscriberId, $meta = false) { - $sendingTask = SendingTask::create(); - $sendingTask->newsletterId = $newsletter->getId(); - if ($newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_SEND_TO) === 'user' && $subscriberId) { - $sendingTask->setSubscribers([$subscriberId]); - } - if ($meta) { - $sendingTask->__set('meta', $meta); - } - $sendingTask->status = SendingQueueEntity::STATUS_SCHEDULED; - $sendingTask->priority = SendingQueueEntity::PRIORITY_MEDIUM; + $subscriber = $subscriberId ? $this->subscribersRepository->findOneById($subscriberId) : null; + $scheduledTask = new ScheduledTaskEntity(); + $scheduledTask->setType(SendingQueue::TASK_TYPE); + $scheduledTask->setStatus(SendingQueueEntity::STATUS_SCHEDULED); + $scheduledTask->setPriority(ScheduledTaskEntity::PRIORITY_MEDIUM); - $sendingTask->scheduledAt = $this->scheduler->getScheduledTimeWithDelay( + $scheduledTask->setScheduledAt($this->scheduler->getScheduledTimeWithDelay( $newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_AFTER_TIME_TYPE), $newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_AFTER_TIME_NUMBER) - ); - return $sendingTask->save(); + )); + $this->scheduledTasksRepository->persist($scheduledTask); + $this->scheduledTasksRepository->flush(); + + $sendingQueue = new SendingQueueEntity(); + $sendingQueue->setNewsletter($newsletter); + $sendingQueue->setTask($scheduledTask); + $scheduledTask->setSendingQueue($sendingQueue); + + if ($meta) { + $scheduledTask->setMeta($meta); + $sendingQueue->setMeta($meta); + } + + $this->sendingQueuesRepository->persist($sendingQueue); + $this->sendingQueuesRepository->flush(); + + if ($newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_SEND_TO) === 'user' && $subscriber) { + $scheduledTaskSubscriber = new ScheduledTaskSubscriberEntity($scheduledTask, $subscriber); + $this->scheduledTaskSubscribersRepository->persist($scheduledTaskSubscriber); + $this->scheduledTaskSubscribersRepository->flush(); + $scheduledTask->getSubscribers()->add($scheduledTaskSubscriber); + } } - private function rescheduleAutomaticEmailSendingTask(NewsletterEntity $newsletter, ScheduledTask $task, $meta = false) { - $sendingTask = SendingTask::createFromScheduledTask($task); + private function rescheduleAutomaticEmailSendingTask(NewsletterEntity $newsletter, ScheduledTaskEntity $scheduledTask, $meta = false) { + $sendingQueue = $this->sendingQueuesRepository->findOneBy(['task' => $scheduledTask]); + if (!$sendingQueue) { + return; + } + if ($meta) { - $sendingTask->__set('meta', $meta); + $sendingQueue->setMeta($meta); + $scheduledTask->setMeta($meta); } // compute new 'scheduled_at' from now - $sendingTask->scheduledAt = $this->scheduler->getScheduledTimeWithDelay( + $scheduledTask->setScheduledAt($this->scheduler->getScheduledTimeWithDelay( $newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_AFTER_TIME_TYPE), $newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_AFTER_TIME_NUMBER) - ); - $sendingTask->save(); + )); + $this->sendingQueuesRepository->flush(); } } diff --git a/mailpoet/lib/Newsletter/Sending/ScheduledTaskSubscribersRepository.php b/mailpoet/lib/Newsletter/Sending/ScheduledTaskSubscribersRepository.php index a2ff9e0995..d995666808 100644 --- a/mailpoet/lib/Newsletter/Sending/ScheduledTaskSubscribersRepository.php +++ b/mailpoet/lib/Newsletter/Sending/ScheduledTaskSubscribersRepository.php @@ -77,6 +77,15 @@ class ScheduledTaskSubscribersRepository extends Repository { return $subscribersIds; } + public function deleteByTask(ScheduledTaskEntity $scheduledTask): void { + $this->entityManager->createQueryBuilder() + ->delete(ScheduledTaskSubscriberEntity::class, 'sts') + ->where('sts.task = :task') + ->setParameter('task', $scheduledTask) + ->getQuery() + ->execute(); + } + private function getBaseSubscribersIdsBatchForTaskQuery(int $taskId, int $lastProcessedSubscriberId): QueryBuilder { return $this->entityManager ->createQueryBuilder() diff --git a/mailpoet/lib/Newsletter/Sending/ScheduledTasksRepository.php b/mailpoet/lib/Newsletter/Sending/ScheduledTasksRepository.php index 66ddfbcc8c..9896f6e641 100644 --- a/mailpoet/lib/Newsletter/Sending/ScheduledTasksRepository.php +++ b/mailpoet/lib/Newsletter/Sending/ScheduledTasksRepository.php @@ -96,6 +96,23 @@ class ScheduledTasksRepository extends Repository { ->getResult(); } + public function findOneScheduledByNewsletterAndSubscriberId(NewsletterEntity $newsletter, int $subscriberId): ?ScheduledTaskEntity { + $scheduledTask = $this->doctrineRepository->createQueryBuilder('st') + ->join(SendingQueueEntity::class, 'sq', Join::WITH, 'st = sq.task') + ->join(ScheduledTaskSubscriberEntity::class, 'sts', Join::WITH, 'st = sts.task') + ->andWhere('st.status = :status') + ->andWhere('sq.newsletter = :newsletter') + ->andWhere('sts.subscriber = :subscriber') + ->setMaxResults(1) + ->setParameter('status', ScheduledTaskEntity::STATUS_SCHEDULED) + ->setParameter('newsletter', $newsletter) + ->setParameter('subscriber', $subscriberId) + ->getQuery() + ->getOneOrNullResult(); + // for phpstan because it detects mixed instead of entity + return ($scheduledTask instanceof ScheduledTaskEntity) ? $scheduledTask : null; + } + public function findScheduledOrRunningTask(?string $type): ?ScheduledTaskEntity { $queryBuilder = $this->doctrineRepository->createQueryBuilder('st') ->select('st') diff --git a/mailpoet/lib/Newsletter/Sending/SendingQueuesRepository.php b/mailpoet/lib/Newsletter/Sending/SendingQueuesRepository.php index 2acbf749e4..ce4020c8f5 100644 --- a/mailpoet/lib/Newsletter/Sending/SendingQueuesRepository.php +++ b/mailpoet/lib/Newsletter/Sending/SendingQueuesRepository.php @@ -141,4 +141,13 @@ class SendingQueuesRepository extends Repository { $this->flush(); } } + + public function deleteByTask(ScheduledTaskEntity $scheduledTask): void { + $this->entityManager->createQueryBuilder() + ->delete(SendingQueueEntity::class, 'sq') + ->where('sq.task = :task') + ->setParameter('task', $scheduledTask) + ->getQuery() + ->execute(); + } }