暂无描述

StatisticsOpensRepository.php 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <?php declare(strict_types=1);
  2. namespace MailPoet\Statistics;
  3. if (!defined('ABSPATH')) exit;
  4. use MailPoet\Doctrine\Repository;
  5. use MailPoet\Entities\SegmentEntity;
  6. use MailPoet\Entities\StatisticsNewsletterEntity;
  7. use MailPoet\Entities\StatisticsOpenEntity;
  8. use MailPoet\Entities\SubscriberEntity;
  9. use MailPoetVendor\Carbon\Carbon;
  10. use MailPoetVendor\Doctrine\ORM\QueryBuilder;
  11. /**
  12. * @extends Repository<StatisticsOpenEntity>
  13. */
  14. class StatisticsOpensRepository extends Repository {
  15. protected function getEntityClassName(): string {
  16. return StatisticsOpenEntity::class;
  17. }
  18. public function recalculateSubscriberScore(SubscriberEntity $subscriber): void {
  19. $subscriber->setEngagementScoreUpdatedAt(new \DateTimeImmutable());
  20. $dateTime = (new Carbon())->subYear();
  21. $newslettersSentCount = $this
  22. ->entityManager
  23. ->createQueryBuilder()
  24. ->select('count(DISTINCT statisticsNewsletter.newsletter)')
  25. ->from(StatisticsNewsletterEntity::class, 'statisticsNewsletter')
  26. ->where('statisticsNewsletter.subscriber = :subscriber')
  27. ->andWhere('statisticsNewsletter.sentAt > :dateTime')
  28. ->setParameter('subscriber', $subscriber)
  29. ->setParameter('dateTime', $dateTime)
  30. ->getQuery()
  31. ->getSingleScalarResult();
  32. if ($newslettersSentCount < 3) {
  33. $this->entityManager->flush();
  34. return;
  35. }
  36. $opens = $this
  37. ->entityManager
  38. ->createQueryBuilder()
  39. ->select('count(DISTINCT opens.newsletter)')
  40. ->from(StatisticsOpenEntity::class, 'opens')
  41. ->join('opens.newsletter', 'newsletter')
  42. ->where('opens.subscriber = :subscriberId')
  43. ->andWhere('(newsletter.sentAt > :dateTime OR newsletter.sentAt IS NULL)')
  44. ->andWhere('opens.createdAt > :dateTime')
  45. ->setParameter('subscriberId', $subscriber)
  46. ->setParameter('dateTime', $dateTime)
  47. ->getQuery()
  48. ->getSingleScalarResult();
  49. $score = ($opens / $newslettersSentCount) * 100;
  50. $subscriber->setEngagementScore($score);
  51. $this->entityManager->flush();
  52. }
  53. public function resetSubscribersScoreCalculation() {
  54. $this->entityManager->createQueryBuilder()->update(SubscriberEntity::class, 's')
  55. ->set('s.engagementScoreUpdatedAt', ':updatedAt')
  56. ->setParameter('updatedAt', null)
  57. ->getQuery()->execute();
  58. }
  59. public function recalculateSegmentScore(SegmentEntity $segment): void {
  60. $segment->setAverageEngagementScoreUpdatedAt(new \DateTimeImmutable());
  61. $avgScore = $this
  62. ->entityManager
  63. ->createQueryBuilder()
  64. ->select('avg(subscriber.engagementScore)')
  65. ->from(SubscriberEntity::class, 'subscriber')
  66. ->join('subscriber.subscriberSegments', 'subscriberSegments')
  67. ->where('subscriberSegments.segment = :segment')
  68. ->andWhere('subscriber.status = :subscribed')
  69. ->andWhere('subscriber.deletedAt IS NULL')
  70. ->andWhere('subscriberSegments.status = :subscribed')
  71. ->setParameter('segment', $segment)
  72. ->setParameter('subscribed', SubscriberEntity::STATUS_SUBSCRIBED)
  73. ->getQuery()
  74. ->getSingleScalarResult();
  75. $segment->setAverageEngagementScore($avgScore === null ? $avgScore : (float)$avgScore);
  76. $this->entityManager->flush();
  77. }
  78. public function resetSegmentsScoreCalculation(): void {
  79. $this->entityManager->createQueryBuilder()->update(SegmentEntity::class, 's')
  80. ->set('s.averageEngagementScoreUpdatedAt', ':updatedAt')
  81. ->setParameter('updatedAt', null)
  82. ->getQuery()->execute();
  83. }
  84. public function getAllForSubscriber(SubscriberEntity $subscriber): QueryBuilder {
  85. return $this->entityManager->createQueryBuilder()
  86. ->select('opens.id id, queue.newsletterRenderedSubject, opens.createdAt, userAgent.userAgent')
  87. ->from(StatisticsOpenEntity::class, 'opens')
  88. ->join('opens.queue', 'queue')
  89. ->leftJoin('opens.userAgent', 'userAgent')
  90. ->where('opens.subscriber = :subscriber')
  91. ->orderBy('queue.newsletterRenderedSubject')
  92. ->setParameter('subscriber', $subscriber->getId());
  93. }
  94. }