diff --git a/mailpoet/assets/js/src/help/data-inconsistencies.tsx b/mailpoet/assets/js/src/help/data-inconsistencies.tsx index 05deb11d00..eb529f1d1d 100644 --- a/mailpoet/assets/js/src/help/data-inconsistencies.tsx +++ b/mailpoet/assets/js/src/help/data-inconsistencies.tsx @@ -23,6 +23,10 @@ export function DataInconsistencies({ dataInconsistencies }: Props) { 'Orphaned Sending Task Subscribers', 'mailpoet', ), + sending_queue_without_newsletter: __( + 'Sending Queues without Newsletter', + 'mailpoet', + ), }), [], ); diff --git a/mailpoet/lib/Util/DataInconsistency/DataInconsistencyController.php b/mailpoet/lib/Util/DataInconsistency/DataInconsistencyController.php index d608023146..e13135ab5b 100644 --- a/mailpoet/lib/Util/DataInconsistency/DataInconsistencyController.php +++ b/mailpoet/lib/Util/DataInconsistency/DataInconsistencyController.php @@ -7,10 +7,12 @@ use MailPoet\UnexpectedValueException; class DataInconsistencyController { const ORPHANED_SENDING_TASKS = 'orphaned_sending_tasks'; const ORPHANED_SENDING_TASK_SUBSCRIBERS = 'orphaned_sending_task_subscribers'; + const SENDING_QUEUE_WITHOUT_NEWSLETTER = 'sending_queue_without_newsletter'; const SUPPORTED_INCONSISTENCY_CHECKS = [ self::ORPHANED_SENDING_TASKS, self::ORPHANED_SENDING_TASK_SUBSCRIBERS, + self::SENDING_QUEUE_WITHOUT_NEWSLETTER, ]; private DataInconsistencyRepository $repository; @@ -25,6 +27,7 @@ class DataInconsistencyController { $result = [ self::ORPHANED_SENDING_TASKS => $this->repository->getOrphanedSendingTasksCount(), self::ORPHANED_SENDING_TASK_SUBSCRIBERS => $this->repository->getOrphanedScheduledTasksSubscribersCount(), + self::SENDING_QUEUE_WITHOUT_NEWSLETTER => $this->repository->getSendingQueuesWithoutNewsletterCount(), ]; $result['total'] = array_sum($result); return $result; @@ -38,6 +41,8 @@ class DataInconsistencyController { $this->repository->cleanupOrphanedSendingTasks(); } elseif ($inconsistency === self::ORPHANED_SENDING_TASK_SUBSCRIBERS) { $this->repository->cleanupOrphanedScheduledTaskSubscribers(); + } elseif ($inconsistency === self::SENDING_QUEUE_WITHOUT_NEWSLETTER) { + $this->repository->cleanupSendingQueuesWithoutNewsletter(); } } } diff --git a/mailpoet/lib/Util/DataInconsistency/DataInconsistencyRepository.php b/mailpoet/lib/Util/DataInconsistency/DataInconsistencyRepository.php index 5f175d1e74..6cd9f38a21 100644 --- a/mailpoet/lib/Util/DataInconsistency/DataInconsistencyRepository.php +++ b/mailpoet/lib/Util/DataInconsistency/DataInconsistencyRepository.php @@ -3,8 +3,10 @@ namespace MailPoet\Util\DataInconsistency; use MailPoet\Cron\Workers\SendingQueue\SendingQueue; +use MailPoet\Entities\NewsletterEntity; use MailPoet\Entities\ScheduledTaskEntity; use MailPoet\Entities\ScheduledTaskSubscriberEntity; +use MailPoet\Entities\SendingQueueEntity; use MailPoetVendor\Doctrine\ORM\EntityManager; use MailPoetVendor\Doctrine\ORM\Query; use MailPoetVendor\Doctrine\ORM\QueryBuilder; @@ -35,6 +37,17 @@ class DataInconsistencyRepository { return intval($count); } + public function getSendingQueuesWithoutNewsletterCount(): int { + $sqTable = $this->entityManager->getClassMetadata(SendingQueueEntity::class)->getTableName(); + $newsletterTable = $this->entityManager->getClassMetadata(NewsletterEntity::class)->getTableName(); + $count = $this->entityManager->getConnection()->executeQuery(" + SELECT count(*) FROM $sqTable sq + LEFT JOIN $newsletterTable n ON n.`id` = sq.`newsletter_id` + WHERE n.`id` IS NULL + ")->fetchOne(); + return intval($count); + } + public function cleanupOrphanedSendingTasks(): int { $ids = $this->buildOrphanedSendingTasksQuery( $this->entityManager->createQueryBuilder() @@ -74,6 +87,19 @@ class DataInconsistencyRepository { "); } + public function cleanupSendingQueuesWithoutNewsletter(): int { + $sqTable = $this->entityManager->getClassMetadata(SendingQueueEntity::class)->getTableName(); + $newsletterTable = $this->entityManager->getClassMetadata(NewsletterEntity::class)->getTableName(); + $deletedQueuesCount = (int)$this->entityManager->getConnection()->executeStatement(" + DELETE sq FROM $sqTable sq + LEFT JOIN $newsletterTable n ON n.`id` = sq.`newsletter_id` + WHERE n.`id` IS NULL + "); + + $this->cleanupOrphanedSendingTasks(); + return $deletedQueuesCount; + } + private function buildOrphanedSendingTasksQuery(QueryBuilder $queryBuilder): Query { return $queryBuilder ->from(ScheduledTaskEntity::class, 'st') diff --git a/mailpoet/tests/integration/Util/DataInconsistency/DataInconsistencyRepositoryTest.php b/mailpoet/tests/integration/Util/DataInconsistency/DataInconsistencyRepositoryTest.php index bb7312b245..fe3e32d351 100644 --- a/mailpoet/tests/integration/Util/DataInconsistency/DataInconsistencyRepositoryTest.php +++ b/mailpoet/tests/integration/Util/DataInconsistency/DataInconsistencyRepositoryTest.php @@ -6,6 +6,7 @@ use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker; use MailPoet\Entities\ScheduledTaskEntity; use MailPoet\Entities\ScheduledTaskSubscriberEntity; use MailPoet\Entities\SubscriberEntity; +use MailPoet\Test\DataFactories\Newsletter; use MailPoet\Test\DataFactories\ScheduledTask; use MailPoet\Test\DataFactories\ScheduledTaskSubscriber; use MailPoet\Test\DataFactories\SendingQueue; @@ -76,4 +77,25 @@ class DataInconsistencyRepositoryTest extends \MailPoetTest { $this->repository->cleanupOrphanedScheduledTaskSubscribers(); verify($this->repository->getOrphanedScheduledTasksSubscribersCount())->equals(0); } + + public function testItHandlesSendingQueuesWithoutNewsletter(): void { + $newsletter = (new Newsletter())->create(); + $taskWithSubscriber = (new ScheduledTask())->create(SendingQueueWorker::TASK_TYPE, ScheduledTaskEntity::STATUS_SCHEDULED); + + $subscriber1 = (new Subscriber())->create(); + (new ScheduledTaskSubscriber())->createProcessed($taskWithSubscriber, $subscriber1); + $subscriber2 = (new Subscriber())->create(); + (new ScheduledTaskSubscriber())->createProcessed($taskWithSubscriber, $subscriber2); + + (new SendingQueue())->create($taskWithSubscriber, $newsletter); + + $this->entityManager->remove($newsletter); + $this->entityManager->flush(); + + verify($this->repository->getSendingQueuesWithoutNewsletterCount())->equals(1); + $this->repository->cleanupSendingQueuesWithoutNewsletter(); + verify($this->repository->getSendingQueuesWithoutNewsletterCount())->equals(0); + verify($this->repository->getOrphanedSendingTasksCount())->equals(0); + verify($this->repository->getOrphanedScheduledTasksSubscribersCount())->equals(0); + } }