NewsletterSegmentRepository.php
94 lines
| 1 | <?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing |
| 2 | |
| 3 | namespace MailPoet\Newsletter\Segment; |
| 4 | |
| 5 | if (!defined('ABSPATH')) exit; |
| 6 | |
| 7 | |
| 8 | use MailPoet\Doctrine\Repository; |
| 9 | use MailPoet\Entities\NewsletterEntity; |
| 10 | use MailPoet\Entities\NewsletterSegmentEntity; |
| 11 | use MailPoet\Newsletter\Options\NewsletterOptionsRepository; |
| 12 | use MailPoetVendor\Doctrine\ORM\EntityManager; |
| 13 | |
| 14 | /** |
| 15 | * @extends Repository<NewsletterSegmentEntity> |
| 16 | */ |
| 17 | class NewsletterSegmentRepository extends Repository { |
| 18 | |
| 19 | /** @var NewsletterOptionsRepository */ |
| 20 | private $newsletterOptionsRepository; |
| 21 | |
| 22 | public function __construct( |
| 23 | NewsletterOptionsRepository $newsletterOptionsRepository, |
| 24 | EntityManager $entityManager |
| 25 | ) { |
| 26 | parent::__construct($entityManager); |
| 27 | $this->newsletterOptionsRepository = $newsletterOptionsRepository; |
| 28 | } |
| 29 | |
| 30 | protected function getEntityClassName() { |
| 31 | return NewsletterSegmentEntity::class; |
| 32 | } |
| 33 | |
| 34 | public function getSubjectsOfActivelyUsedEmailsForSegments(array $segmentIds): array { |
| 35 | $nameMap = []; |
| 36 | // Welcome emails |
| 37 | foreach ($this->newsletterOptionsRepository->findWelcomeNotificationsForSegments($segmentIds) as $option) { |
| 38 | $newsletter = $option->getNewsletter(); |
| 39 | if (!$newsletter instanceof NewsletterEntity) continue; |
| 40 | $nameMap[(string)$option->getValue()][] = $newsletter->getSubject(); |
| 41 | } |
| 42 | // Automatic emails |
| 43 | foreach ($this->newsletterOptionsRepository->findAutomaticEmailsForSegments($segmentIds) as $option) { |
| 44 | $newsletter = $option->getNewsletter(); |
| 45 | if (!$newsletter instanceof NewsletterEntity) continue; |
| 46 | $nameMap[(string)$option->getValue()][] = $newsletter->getSubject(); |
| 47 | } |
| 48 | |
| 49 | $otherNewsletters = $this->doctrineRepository->createQueryBuilder('ns') |
| 50 | ->join('ns.newsletter', 'n') |
| 51 | ->leftJoin('n.queues', 'q') |
| 52 | ->leftJoin('q.task', 't') |
| 53 | ->select('IDENTITY(ns.segment) AS segment_id, n.subject') |
| 54 | ->where('(n.type = (:postNotification) OR n.status = :scheduled OR (t.id IS NOT NULL AND t.status IS NULL))') |
| 55 | ->andWhere('ns.segment IN (:segmentIds)') |
| 56 | ->setParameter('postNotification', NewsletterEntity::TYPE_NOTIFICATION) |
| 57 | ->setParameter('segmentIds', $segmentIds) |
| 58 | ->setParameter('scheduled', NewsletterEntity::STATUS_SCHEDULED) |
| 59 | ->addGroupBy('ns.segment, q.id, t.id') |
| 60 | ->getQuery() |
| 61 | ->getResult(); |
| 62 | |
| 63 | foreach ($otherNewsletters as $result) { |
| 64 | if (isset($nameMap[(string)$result['segment_id']]) && in_array($result['subject'], $nameMap[(string)$result['segment_id']])) { |
| 65 | continue; |
| 66 | } |
| 67 | $nameMap[(string)$result['segment_id']][] = $result['subject']; |
| 68 | } |
| 69 | |
| 70 | // Sort email subjects alphabetically for each segment |
| 71 | foreach ($nameMap as &$names) { |
| 72 | sort($names); |
| 73 | } |
| 74 | |
| 75 | return $nameMap; |
| 76 | } |
| 77 | |
| 78 | /** @param int[] $ids */ |
| 79 | public function deleteByNewsletterIds(array $ids): void { |
| 80 | $this->entityManager->createQueryBuilder() |
| 81 | ->delete(NewsletterSegmentEntity::class, 's') |
| 82 | ->where('s.newsletter IN (:ids)') |
| 83 | ->setParameter('ids', $ids) |
| 84 | ->getQuery() |
| 85 | ->execute(); |
| 86 | |
| 87 | // delete was done via DQL, make sure the entities are also detached from the entity manager |
| 88 | $this->detachAll(function (NewsletterSegmentEntity $entity) use ($ids) { |
| 89 | $newsletter = $entity->getNewsletter(); |
| 90 | return $newsletter && in_array($newsletter->getId(), $ids, true); |
| 91 | }); |
| 92 | } |
| 93 | } |
| 94 |