Add inconsistency check and fix for sending queues without newsletter

[MAILPOET-1587]
This commit is contained in:
Rostislav Wolny
2024-08-01 12:52:07 +02:00
committed by Aschepikov
parent cb4cea678a
commit 0d7898b3a5
4 changed files with 57 additions and 0 deletions

View File

@@ -23,6 +23,10 @@ export function DataInconsistencies({ dataInconsistencies }: Props) {
'Orphaned Sending Task Subscribers', 'Orphaned Sending Task Subscribers',
'mailpoet', 'mailpoet',
), ),
sending_queue_without_newsletter: __(
'Sending Queues without Newsletter',
'mailpoet',
),
}), }),
[], [],
); );

View File

@@ -7,10 +7,12 @@ use MailPoet\UnexpectedValueException;
class DataInconsistencyController { class DataInconsistencyController {
const ORPHANED_SENDING_TASKS = 'orphaned_sending_tasks'; const ORPHANED_SENDING_TASKS = 'orphaned_sending_tasks';
const ORPHANED_SENDING_TASK_SUBSCRIBERS = 'orphaned_sending_task_subscribers'; const ORPHANED_SENDING_TASK_SUBSCRIBERS = 'orphaned_sending_task_subscribers';
const SENDING_QUEUE_WITHOUT_NEWSLETTER = 'sending_queue_without_newsletter';
const SUPPORTED_INCONSISTENCY_CHECKS = [ const SUPPORTED_INCONSISTENCY_CHECKS = [
self::ORPHANED_SENDING_TASKS, self::ORPHANED_SENDING_TASKS,
self::ORPHANED_SENDING_TASK_SUBSCRIBERS, self::ORPHANED_SENDING_TASK_SUBSCRIBERS,
self::SENDING_QUEUE_WITHOUT_NEWSLETTER,
]; ];
private DataInconsistencyRepository $repository; private DataInconsistencyRepository $repository;
@@ -25,6 +27,7 @@ class DataInconsistencyController {
$result = [ $result = [
self::ORPHANED_SENDING_TASKS => $this->repository->getOrphanedSendingTasksCount(), self::ORPHANED_SENDING_TASKS => $this->repository->getOrphanedSendingTasksCount(),
self::ORPHANED_SENDING_TASK_SUBSCRIBERS => $this->repository->getOrphanedScheduledTasksSubscribersCount(), self::ORPHANED_SENDING_TASK_SUBSCRIBERS => $this->repository->getOrphanedScheduledTasksSubscribersCount(),
self::SENDING_QUEUE_WITHOUT_NEWSLETTER => $this->repository->getSendingQueuesWithoutNewsletterCount(),
]; ];
$result['total'] = array_sum($result); $result['total'] = array_sum($result);
return $result; return $result;
@@ -38,6 +41,8 @@ class DataInconsistencyController {
$this->repository->cleanupOrphanedSendingTasks(); $this->repository->cleanupOrphanedSendingTasks();
} elseif ($inconsistency === self::ORPHANED_SENDING_TASK_SUBSCRIBERS) { } elseif ($inconsistency === self::ORPHANED_SENDING_TASK_SUBSCRIBERS) {
$this->repository->cleanupOrphanedScheduledTaskSubscribers(); $this->repository->cleanupOrphanedScheduledTaskSubscribers();
} elseif ($inconsistency === self::SENDING_QUEUE_WITHOUT_NEWSLETTER) {
$this->repository->cleanupSendingQueuesWithoutNewsletter();
} }
} }
} }

View File

@@ -3,8 +3,10 @@
namespace MailPoet\Util\DataInconsistency; namespace MailPoet\Util\DataInconsistency;
use MailPoet\Cron\Workers\SendingQueue\SendingQueue; use MailPoet\Cron\Workers\SendingQueue\SendingQueue;
use MailPoet\Entities\NewsletterEntity;
use MailPoet\Entities\ScheduledTaskEntity; use MailPoet\Entities\ScheduledTaskEntity;
use MailPoet\Entities\ScheduledTaskSubscriberEntity; use MailPoet\Entities\ScheduledTaskSubscriberEntity;
use MailPoet\Entities\SendingQueueEntity;
use MailPoetVendor\Doctrine\ORM\EntityManager; use MailPoetVendor\Doctrine\ORM\EntityManager;
use MailPoetVendor\Doctrine\ORM\Query; use MailPoetVendor\Doctrine\ORM\Query;
use MailPoetVendor\Doctrine\ORM\QueryBuilder; use MailPoetVendor\Doctrine\ORM\QueryBuilder;
@@ -35,6 +37,17 @@ class DataInconsistencyRepository {
return intval($count); 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 { public function cleanupOrphanedSendingTasks(): int {
$ids = $this->buildOrphanedSendingTasksQuery( $ids = $this->buildOrphanedSendingTasksQuery(
$this->entityManager->createQueryBuilder() $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 { private function buildOrphanedSendingTasksQuery(QueryBuilder $queryBuilder): Query {
return $queryBuilder return $queryBuilder
->from(ScheduledTaskEntity::class, 'st') ->from(ScheduledTaskEntity::class, 'st')

View File

@@ -6,6 +6,7 @@ use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker;
use MailPoet\Entities\ScheduledTaskEntity; use MailPoet\Entities\ScheduledTaskEntity;
use MailPoet\Entities\ScheduledTaskSubscriberEntity; use MailPoet\Entities\ScheduledTaskSubscriberEntity;
use MailPoet\Entities\SubscriberEntity; use MailPoet\Entities\SubscriberEntity;
use MailPoet\Test\DataFactories\Newsletter;
use MailPoet\Test\DataFactories\ScheduledTask; use MailPoet\Test\DataFactories\ScheduledTask;
use MailPoet\Test\DataFactories\ScheduledTaskSubscriber; use MailPoet\Test\DataFactories\ScheduledTaskSubscriber;
use MailPoet\Test\DataFactories\SendingQueue; use MailPoet\Test\DataFactories\SendingQueue;
@@ -76,4 +77,25 @@ class DataInconsistencyRepositoryTest extends \MailPoetTest {
$this->repository->cleanupOrphanedScheduledTaskSubscribers(); $this->repository->cleanupOrphanedScheduledTaskSubscribers();
verify($this->repository->getOrphanedScheduledTasksSubscribersCount())->equals(0); 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);
}
} }