diff --git a/lib/Cron/Workers/StatsNotifications/NewsletterLinkRepository.php b/lib/Cron/Workers/StatsNotifications/NewsletterLinkRepository.php index 1b97040f12..049191dce8 100644 --- a/lib/Cron/Workers/StatsNotifications/NewsletterLinkRepository.php +++ b/lib/Cron/Workers/StatsNotifications/NewsletterLinkRepository.php @@ -4,6 +4,8 @@ namespace MailPoet\Cron\Workers\StatsNotifications; use MailPoet\Doctrine\Repository; use MailPoet\Entities\NewsletterLinkEntity; +use MailPoet\Entities\StatisticsClickEntity; +use MailPoetVendor\Doctrine\DBAL\Driver\Statement; /** * @extends Repository @@ -18,16 +20,24 @@ class NewsletterLinkRepository extends Repository { * @return NewsletterLinkEntity|null */ public function findTopLinkForNewsletter($newsletterId) { - return $this->doctrineRepository - ->createQueryBuilder('nl') - ->join('nl.clicks', 'c') - ->addSelect('COUNT(c.id) AS HIDDEN counter') - ->where('nl.newsletter = :newsletterId') + $statisticsClicksTable = $this->entityManager->getClassMetadata(StatisticsClickEntity::class)->getTableName(); + $topIdQuery = $this->entityManager->getConnection()->createQueryBuilder() + ->select('c.link_id') + ->addSelect('count(c.id) AS counter') + ->from($statisticsClicksTable, 'c') + ->where('c.newsletter_id = :newsletterId') ->setParameter('newsletterId', $newsletterId) - ->groupBy('nl.id') + ->groupBy('c.link_id') ->orderBy('counter', 'desc') ->setMaxResults(1) - ->getQuery() - ->getOneOrNullResult(); + ->execute(); + if (!$topIdQuery instanceof Statement) { + return null; + } + $topId = $topIdQuery->fetch(); + if (is_array($topId) && isset($topId['link_id'])) { + return $this->findOneById((int)$topId['link_id']); + } + return null; } } diff --git a/tests/integration/Cron/Workers/StatsNotifications/NewsletterLinkRepositoryTest.php b/tests/integration/Cron/Workers/StatsNotifications/NewsletterLinkRepositoryTest.php new file mode 100644 index 0000000000..84986b2282 --- /dev/null +++ b/tests/integration/Cron/Workers/StatsNotifications/NewsletterLinkRepositoryTest.php @@ -0,0 +1,60 @@ +setType(NewsletterEntity::TYPE_STANDARD); + $newsletter->setSubject('My Standard Newsletter'); + $newsletter->setStatus(NewsletterEntity::STATUS_SENT); + $this->entityManager->persist($newsletter); + + $task = new ScheduledTaskEntity(); + $task->setType(SendingTask::TASK_TYPE); + $task->setStatus(ScheduledTaskEntity::STATUS_COMPLETED); + $this->entityManager->persist($task); + + $queue = new SendingQueueEntity(); + $queue->setNewsletter($newsletter); + $queue->setTask($task); + $this->entityManager->persist($queue); + $newsletter->getQueues()->add($queue); + + $link1 = new NewsletterLinkEntity($newsletter, $queue, 'http://example1.com', 'abcd'); + $link2 = new NewsletterLinkEntity($newsletter, $queue, 'http://example2.com', 'efgh'); + $this->entityManager->persist($link1); + $this->entityManager->persist($link2); + + + $click1 = new StatisticsClickEntity($newsletter, $queue, (int)1, $link1, 1); + $click2 = new StatisticsClickEntity($newsletter, $queue, (int)1, $link1, 1); + $click3 = new StatisticsClickEntity($newsletter, $queue, (int)1, $link2, 1); + + $this->entityManager->persist($click1); + $this->entityManager->persist($click2); + $this->entityManager->persist($click3); + $this->entityManager->flush(); + + $repository = $this->diContainer->get(NewsletterLinkRepository::class); + $topLink = $repository->findTopLinkForNewsletter($newsletter->getId()); + expect($topLink->getUrl())->equals('http://example1.com'); + + $newsletter2 = new NewsletterEntity(); + $newsletter2->setType(NewsletterEntity::TYPE_STANDARD); + $newsletter2->setSubject('My Standard Newsletter'); + $newsletter2->setStatus(NewsletterEntity::STATUS_SENT); + $this->entityManager->persist($newsletter2); + $this->entityManager->flush(); + + $nonExistingTopLink = $repository->findTopLinkForNewsletter($newsletter2->getId()); + expect($nonExistingTopLink)->null(); + } +}