Remove old model usages from AutomaticEmailScheduler

[MAILPOET-4372]
This commit is contained in:
Jan Lysý
2022-09-28 15:37:20 +02:00
committed by Aschepikov
parent 745ff6af2a
commit a1e96c63a0
4 changed files with 110 additions and 30 deletions

View File

@ -2,23 +2,46 @@
namespace MailPoet\Newsletter\Scheduler; namespace MailPoet\Newsletter\Scheduler;
use MailPoet\Cron\Workers\SendingQueue\SendingQueue;
use MailPoet\Entities\NewsletterEntity; use MailPoet\Entities\NewsletterEntity;
use MailPoet\Entities\NewsletterOptionFieldEntity; use MailPoet\Entities\NewsletterOptionFieldEntity;
use MailPoet\Entities\ScheduledTaskEntity;
use MailPoet\Entities\ScheduledTaskSubscriberEntity;
use MailPoet\Entities\SendingQueueEntity; use MailPoet\Entities\SendingQueueEntity;
use MailPoet\Models\ScheduledTask; use MailPoet\Newsletter\Sending\ScheduledTasksRepository;
use MailPoet\Models\ScheduledTaskSubscriber; use MailPoet\Newsletter\Sending\ScheduledTaskSubscribersRepository;
use MailPoet\Models\SendingQueue; use MailPoet\Newsletter\Sending\SendingQueuesRepository;
use MailPoet\Tasks\Sending as SendingTask; use MailPoet\Subscribers\SubscribersRepository;
class AutomaticEmailScheduler { class AutomaticEmailScheduler {
/** @var Scheduler */ /** @var Scheduler */
private $scheduler; private $scheduler;
/** @var ScheduledTasksRepository */
private $scheduledTasksRepository;
/** @var SendingQueuesRepository */
private $sendingQueuesRepository;
/** @var ScheduledTaskSubscribersRepository */
private $scheduledTaskSubscribersRepository;
/** @var SubscribersRepository */
private $subscribersRepository;
public function __construct( public function __construct(
Scheduler $scheduler Scheduler $scheduler,
ScheduledTasksRepository $scheduledTasksRepository,
ScheduledTaskSubscribersRepository $scheduledTaskSubscribersRepository,
SendingQueuesRepository $sendingQueuesRepository,
SubscribersRepository $subscribersRepository
) { ) {
$this->scheduler = $scheduler; $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) { 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 // try to find existing scheduled task for given subscriber
$task = ScheduledTask::findOneScheduledByNewsletterIdAndSubscriberId($newsletter->getId(), $subscriberId); $task = $this->scheduledTasksRepository->findOneScheduledByNewsletterAndSubscriberId($newsletter, $subscriberId);
if ($task) { if ($task) {
$this->rescheduleAutomaticEmailSendingTask($newsletter, $task, $meta); $this->rescheduleAutomaticEmailSendingTask($newsletter, $task, $meta);
} else { } else {
@ -76,7 +99,7 @@ class AutomaticEmailScheduler {
} }
// try to find existing scheduled task for given subscriber // try to find existing scheduled task for given subscriber
$task = ScheduledTask::findOneScheduledByNewsletterIdAndSubscriberId($newsletter->getId(), $subscriberId); $task = $this->scheduledTasksRepository->findOneScheduledByNewsletterAndSubscriberId($newsletter, $subscriberId);
if ($task) { if ($task) {
$this->rescheduleAutomaticEmailSendingTask($newsletter, $task); $this->rescheduleAutomaticEmailSendingTask($newsletter, $task);
} }
@ -95,44 +118,66 @@ class AutomaticEmailScheduler {
} }
// try to find existing scheduled task for given subscriber // try to find existing scheduled task for given subscriber
$task = ScheduledTask::findOneScheduledByNewsletterIdAndSubscriberId($newsletter->getId(), $subscriberId); $task = $this->scheduledTasksRepository->findOneScheduledByNewsletterAndSubscriberId($newsletter, $subscriberId);
if ($task) { if ($task) {
SendingQueue::where('task_id', $task->id)->deleteMany(); $this->sendingQueuesRepository->deleteByTask($task);
ScheduledTaskSubscriber::where('task_id', $task->id)->deleteMany(); $this->scheduledTaskSubscribersRepository->deleteByTask($task);
$task->delete(); $this->scheduledTasksRepository->remove($task);
$this->scheduledTasksRepository->flush();
} }
} }
} }
public function createAutomaticEmailSendingTask(NewsletterEntity $newsletter, $subscriberId, $meta = false) { public function createAutomaticEmailSendingTask(NewsletterEntity $newsletter, $subscriberId, $meta = false) {
$sendingTask = SendingTask::create(); $subscriber = $subscriberId ? $this->subscribersRepository->findOneById($subscriberId) : null;
$sendingTask->newsletterId = $newsletter->getId(); $scheduledTask = new ScheduledTaskEntity();
if ($newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_SEND_TO) === 'user' && $subscriberId) { $scheduledTask->setType(SendingQueue::TASK_TYPE);
$sendingTask->setSubscribers([$subscriberId]); $scheduledTask->setStatus(SendingQueueEntity::STATUS_SCHEDULED);
} $scheduledTask->setPriority(ScheduledTaskEntity::PRIORITY_MEDIUM);
if ($meta) {
$sendingTask->__set('meta', $meta);
}
$sendingTask->status = SendingQueueEntity::STATUS_SCHEDULED;
$sendingTask->priority = SendingQueueEntity::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_TYPE),
$newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_AFTER_TIME_NUMBER) $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) { private function rescheduleAutomaticEmailSendingTask(NewsletterEntity $newsletter, ScheduledTaskEntity $scheduledTask, $meta = false) {
$sendingTask = SendingTask::createFromScheduledTask($task); $sendingQueue = $this->sendingQueuesRepository->findOneBy(['task' => $scheduledTask]);
if (!$sendingQueue) {
return;
}
if ($meta) { if ($meta) {
$sendingTask->__set('meta', $meta); $sendingQueue->setMeta($meta);
$scheduledTask->setMeta($meta);
} }
// compute new 'scheduled_at' from now // 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_TYPE),
$newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_AFTER_TIME_NUMBER) $newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_AFTER_TIME_NUMBER)
); ));
$sendingTask->save(); $this->sendingQueuesRepository->flush();
} }
} }

View File

@ -77,6 +77,15 @@ class ScheduledTaskSubscribersRepository extends Repository {
return $subscribersIds; 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 { private function getBaseSubscribersIdsBatchForTaskQuery(int $taskId, int $lastProcessedSubscriberId): QueryBuilder {
return $this->entityManager return $this->entityManager
->createQueryBuilder() ->createQueryBuilder()

View File

@ -96,6 +96,23 @@ class ScheduledTasksRepository extends Repository {
->getResult(); ->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 { public function findScheduledOrRunningTask(?string $type): ?ScheduledTaskEntity {
$queryBuilder = $this->doctrineRepository->createQueryBuilder('st') $queryBuilder = $this->doctrineRepository->createQueryBuilder('st')
->select('st') ->select('st')

View File

@ -141,4 +141,13 @@ class SendingQueuesRepository extends Repository {
$this->flush(); $this->flush();
} }
} }
public function deleteByTask(ScheduledTaskEntity $scheduledTask): void {
$this->entityManager->createQueryBuilder()
->delete(SendingQueueEntity::class, 'sq')
->where('sq.task = :task')
->setParameter('task', $scheduledTask)
->getQuery()
->execute();
}
} }