diff --git a/mailpoet/lib/Subscribers/SubscribersEmailCountsController.php b/mailpoet/lib/Subscribers/SubscribersEmailCountsController.php index 82bfba59ea..9b044bfced 100644 --- a/mailpoet/lib/Subscribers/SubscribersEmailCountsController.php +++ b/mailpoet/lib/Subscribers/SubscribersEmailCountsController.php @@ -15,15 +15,18 @@ class SubscribersEmailCountsController { /** @var string */ private $subscribersTable; + /** @var string */ + private $scheduledTasksTable; + public function __construct( EntityManager $entityManager ) { $this->entityManager = $entityManager; $this->subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName(); + $this->scheduledTasksTable = $this->entityManager->getClassMetadata(ScheduledTaskEntity::class)->getTableName(); } public function updateSubscribersEmailCounts(?\DateTimeInterface $dateLastProcessed, int $batchSize, ?int $startId = null): array { - $scheduledTasksTable = $this->entityManager->getClassMetadata(ScheduledTaskEntity::class)->getTableName(); $scheduledTaskSubscribersTable = $this->entityManager->getClassMetadata(ScheduledTaskSubscriberEntity::class)->getTableName(); $connection = $this->entityManager->getConnection(); @@ -33,6 +36,11 @@ class SubscribersEmailCountsController { $startId = (int)$startId; + // Return if there are no new sending tasks + if ($dateLastProcessed && !$this->newSendingTasksSince($dateLastProcessed)) { + return [0, 0]; + } + // Return if there are no subscribers to update [$countSubscribersToUpdate, $endId] = $this->countAndMaxOfSubscribersInRange($startId, $batchSize); if (!$countSubscribersToUpdate) { return [0, 0]; @@ -58,7 +66,7 @@ class SubscribersEmailCountsController { SELECT s.id, COUNT(st.id) as email_count FROM {$this->subscribersTable} as s JOIN {$scheduledTaskSubscribersTable} as sts ON s.id = sts.subscriber_id - JOIN {$scheduledTasksTable} as st ON st.id = sts.task_id + JOIN {$this->scheduledTasksTable} as st ON st.id = sts.task_id WHERE s.id >= :startId AND s.id <= :endId AND st.type = 'sending' @@ -75,10 +83,30 @@ class SubscribersEmailCountsController { return [$countSubscribersToUpdate, $endId]; } - private function countAndMaxOfSubscribersInRange(int $startId, int $batchSize): array { - $connection = $this->entityManager->getConnection(); + private function newSendingTasksSince(\DateTimeInterface $dateLastProcessed): bool { + $carbonDateLastProcessed = Carbon::createFromTimestamp($dateLastProcessed->getTimestamp()); + $dateFromIso = ($carbonDateLastProcessed->subDay())->toDateTimeString(); + $queryParams['dateFrom'] = $dateFromIso; + $dayAgo = new Carbon(); + $dayAgoIso = $dayAgo->subDay()->toDateTimeString(); + $queryParams['dayAgo'] = $dayAgoIso; - $result = $connection->executeQuery(" + $result = $this->entityManager->getConnection()->executeQuery(" + SELECT count(id) FROM {$this->scheduledTasksTable} + WHERE type = 'sending' + AND processed_at IS NOT NULL + AND processed_at < :dayAgo + AND processed_at >= :dateFrom + ", + $queryParams + )->fetchNumeric(); + + /** @var int[] $result - it's required for PHPStan */ + return is_array($result) && isset($result[0]) && ((int)$result[0] > 0); + } + + private function countAndMaxOfSubscribersInRange(int $startId, int $batchSize): array { + $result = $this->entityManager->getConnection()->executeQuery(" SELECT s.id FROM {$this->subscribersTable} as s WHERE s.id >= :startId ORDER BY s.id diff --git a/mailpoet/tests/integration/Subscribers/SubscribersEmailCountsControllerTest.php b/mailpoet/tests/integration/Subscribers/SubscribersEmailCountsControllerTest.php index bb23392b68..bad543d0d0 100644 --- a/mailpoet/tests/integration/Subscribers/SubscribersEmailCountsControllerTest.php +++ b/mailpoet/tests/integration/Subscribers/SubscribersEmailCountsControllerTest.php @@ -151,7 +151,7 @@ class SubscribersEmailCountsControllerTest extends \MailPoetTest { expect($subscriber3->getEmailCount())->equals(0); } - public function testItDoesNotCountIfThereAreNoSubscribersToUpdate() { + public function testItDoesNotCountIfThereAreNoSubscribersOrTasksToUpdate() { // Subscribers empty table [$count, $maxSubscriberId] = $this->controller->updateSubscribersEmailCounts(null, 1); expect($count)->equals(0); @@ -160,6 +160,12 @@ class SubscribersEmailCountsControllerTest extends \MailPoetTest { $subscriber2 = $this->createSubscriber('s2@email.com', 20); $subscriber3 = $this->createSubscriber('s3@email.com', 10); + // Tasks empty table + $dateFromCarbon = new Carbon(); + $dateFrom = $dateFromCarbon->subDays(7)->toDateTime(); + [$count, $maxSubscriberId] = $this->controller->updateSubscribersEmailCounts($dateFrom, 1); + expect($count)->equals(0); + $this->createCompletedSendingTasksForSubscriber($subscriber1, 80, 90); $this->createCompletedSendingTasksForSubscriber($subscriber2, 8, 3); $this->createCompletedSendingTasksForSubscriber($subscriber3, 1, 4);