Fix trashing check to check also welcome and automatic emails

[MAILPOET-3463]
This commit is contained in:
Rostislav Wolny
2021-03-25 14:22:44 +01:00
committed by Veljko V
parent fc66381da2
commit 51e5206ed8
6 changed files with 218 additions and 13 deletions

View File

@ -33,4 +33,23 @@ class NewsletterOptionsRepository extends Repository {
->setParameter('segmentIds', $segmentIds)
->getQuery()->getResult();
}
/**
* @return NewsletterOptionEntity[]
*/
public function findAutomaticEmailsForSegments(array $segmentIds): array {
return $this->entityManager->createQueryBuilder()
->select('no')
->from(NewsletterOptionEntity::class, 'no')
->join('no.newsletter', 'n')
->join('no.optionField', 'nof')
->where('n.deletedAt IS NULL')
->andWhere('n.type = :typeAutomatic')
->andWhere('nof.name = :nameSegment')
->andWhere('no.value IN (:segmentIds)')
->setParameter('typeAutomatic', NewsletterEntity::TYPE_AUTOMATIC)
->setParameter('nameSegment', NewsletterOptionFieldEntity::NAME_SEGMENT)
->setParameter('segmentIds', $segmentIds)
->getQuery()->getResult();
}
}

View File

@ -5,36 +5,62 @@ namespace MailPoet\Newsletter\Segment;
use MailPoet\Doctrine\Repository;
use MailPoet\Entities\NewsletterEntity;
use MailPoet\Entities\NewsletterSegmentEntity;
use MailPoet\Newsletter\Options\NewsletterOptionsRepository;
use MailPoetVendor\Doctrine\ORM\EntityManager;
/**
* @extends Repository<NewsletterSegmentEntity>
*/
class NewsletterSegmentRepository extends Repository {
/** @var NewsletterOptionsRepository */
private $newsletterOptionsRepository;
public function __construct(
NewsletterOptionsRepository $newsletterOptionsRepository,
EntityManager $entityManager
) {
parent::__construct($entityManager);
$this->newsletterOptionsRepository = $newsletterOptionsRepository;
}
protected function getEntityClassName() {
return NewsletterSegmentEntity::class;
}
public function getSubjectsOfActivelyUsedEmailsForSegments(array $segmentIds): array {
$results = $this->doctrineRepository->createQueryBuilder('ns')
$nameMap = [];
// Welcome emails
foreach ($this->newsletterOptionsRepository->findWelcomeNotificationsForSegments($segmentIds) as $option) {
$newsletter = $option->getNewsletter();
if (!$newsletter instanceof NewsletterEntity) continue;
$nameMap[(string)$option->getValue()][] = $newsletter->getSubject();
}
// Automatic emails
foreach ($this->newsletterOptionsRepository->findAutomaticEmailsForSegments($segmentIds) as $option) {
$newsletter = $option->getNewsletter();
if (!$newsletter instanceof NewsletterEntity) continue;
$nameMap[(string)$option->getValue()][] = $newsletter->getSubject();
}
$otherNewsletters = $this->doctrineRepository->createQueryBuilder('ns')
->join('ns.newsletter', 'n')
->leftJoin('n.queues', 'q')
->leftJoin('q.task', 't')
->select('IDENTITY(ns.segment) AS segment_id, n.subject')
->where('(n.type IN (:types) OR n.status = :scheduled OR (t.id IS NOT NULL AND t.status IS NULL))')
->where('(n.type = (:postNotification) OR n.status = :scheduled OR (t.id IS NOT NULL AND t.status IS NULL))')
->andWhere('ns.segment IN (:segmentIds)')
->setParameter('types', [
NewsletterEntity::TYPE_AUTOMATIC,
NewsletterEntity::TYPE_WELCOME,
NewsletterEntity::TYPE_NOTIFICATION,
])
->setParameter('postNotification', NewsletterEntity::TYPE_NOTIFICATION)
->setParameter('segmentIds', $segmentIds)
->setParameter('scheduled', NewsletterEntity::STATUS_SCHEDULED)
->addGroupBy('n.id, q.id, t.id')
->addGroupBy('ns.segment, q.id, t.id')
->getQuery()
->getResult();
$nameMap = [];
foreach ($results as $result) {
foreach ($otherNewsletters as $result) {
if (isset($nameMap[(string)$result['segment_id']]) && in_array($result['subject'], $nameMap[(string)$result['segment_id']])) {
continue;
}
$nameMap[(string)$result['segment_id']][] = $result['subject'];
}
return $nameMap;

View File

@ -90,7 +90,7 @@ class DynamicSegmentsTest extends \MailPoetTest {
$dynamicSegment = $this->createDynamicSegmentEntity('Trash test 2', 'description');
$newsletter = new NewsletterEntity();
$newsletter->setSubject('Subject');
$newsletter->setType(NewsletterEntity::TYPE_WELCOME);
$newsletter->setType(NewsletterEntity::TYPE_NOTIFICATION);
$newsletterSegment = new NewsletterSegmentEntity($newsletter, $dynamicSegment);
$this->entityManager->persist($newsletter);
$this->entityManager->persist($newsletterSegment);

View File

@ -150,7 +150,7 @@ class SegmentsTest extends \MailPoetTest {
public function testItReturnsErrorWhenTrashingSegmentWithActiveNewsletter() {
$newsletter = new NewsletterEntity();
$newsletter->setSubject('Subject');
$newsletter->setType(NewsletterEntity::TYPE_WELCOME);
$newsletter->setType(NewsletterEntity::TYPE_NOTIFICATION);
$newsletterSegment = new NewsletterSegmentEntity($newsletter, $this->segment2);
$this->entityManager->persist($newsletter);
$this->entityManager->persist($newsletterSegment);

View File

@ -0,0 +1,160 @@
<?php declare(strict_types = 1);
namespace MailPoet\Newsletter\Segment;
use Codeception\Util\Fixtures;
use MailPoet\Entities\NewsletterEntity;
use MailPoet\Entities\NewsletterOptionEntity;
use MailPoet\Entities\NewsletterOptionFieldEntity;
use MailPoet\Entities\NewsletterSegmentEntity;
use MailPoet\Entities\ScheduledTaskEntity;
use MailPoet\Entities\SegmentEntity;
use MailPoet\Entities\SendingQueueEntity;
use MailPoet\Tasks\Sending as SendingTask;
class NewsletterSegmentRepositoryTest extends \MailPoetTest {
/** @var NewsletterSegmentRepository */
private $repository;
/** @var NewsletterOptionFieldEntity */
private $welcomeEmailSegmentOption;
/** @var NewsletterOptionFieldEntity */
private $automaticEmailSegmentOption;
public function _before() {
parent::_before();
$this->cleanup();
$this->repository = $this->diContainer->get(NewsletterSegmentRepository::class);
$this->welcomeEmailSegmentOption = $this->createNewsletterOptionField(NewsletterEntity::TYPE_WELCOME, NewsletterOptionFieldEntity::NAME_SEGMENT);
$this->automaticEmailSegmentOption = $this->createNewsletterOptionField(NewsletterEntity::TYPE_AUTOMATIC, NewsletterOptionFieldEntity::NAME_SEGMENT);
}
public function testItCanGetActiveNewslettersForSegments() {
$draftNewsletter = $this->createNewsletter(NewsletterEntity::TYPE_STANDARD, 'Draft');
$scheduledNewsletter = $this->createNewsletter(NewsletterEntity::TYPE_STANDARD, 'Scheduled', NewsletterEntity::STATUS_SCHEDULED);
$this->createQueueWithTaskAndSegment($scheduledNewsletter);
$sendingNewsletter = $this->createNewsletter(NewsletterEntity::TYPE_STANDARD, 'Sending', NewsletterEntity::STATUS_SENDING);
$this->createQueueWithTaskAndSegment($sendingNewsletter, null);
$welcomeEmail = $this->createNewsletter(NewsletterEntity::TYPE_WELCOME, 'Welcome');
$welcomeEmail2 = $this->createNewsletter(NewsletterEntity::TYPE_WELCOME, 'Welcome2');
$automaticEmail = $this->createNewsletter(NewsletterEntity::TYPE_AUTOMATIC, 'Automatic');
$postNotification = $this->createNewsletter(NewsletterEntity::TYPE_NOTIFICATION, 'Notification');
$unusedSegment = $this->createSegment('Unused', SegmentEntity::TYPE_DEFAULT);
$dynamicWithScheduledNewsletter = $this->createSegment('Dynamic Segment', SegmentEntity::TYPE_DYNAMIC);
$this->addSegmentToNewsletter($scheduledNewsletter, $dynamicWithScheduledNewsletter);
$segmentWithSendingEmail = $this->createSegment('Sending Segment', SegmentEntity::TYPE_DEFAULT);
$this->addSegmentToNewsletter($sendingNewsletter, $segmentWithSendingEmail);
$segmentWithAutomaticEmail = $this->createSegment('Automatic Segment', SegmentEntity::TYPE_DEFAULT);
$this->addSegmentToNewsletter($automaticEmail, $segmentWithAutomaticEmail);
$segmentWithWelcomeEmail = $this->createSegment('Welcome Segment', SegmentEntity::TYPE_DEFAULT);
$this->addSegmentToNewsletter($welcomeEmail, $segmentWithWelcomeEmail);
$segmentWithPostNotification = $this->createSegment('Notification Segment', SegmentEntity::TYPE_DEFAULT);
$this->addSegmentToNewsletter($postNotification, $segmentWithPostNotification);
$segmentWithMultipleActiveEmails = $this->createSegment('Multiple Segment', SegmentEntity::TYPE_DEFAULT);
$this->addSegmentToNewsletter($postNotification, $segmentWithMultipleActiveEmails);
$this->addSegmentToNewsletter($welcomeEmail2, $segmentWithMultipleActiveEmails);
$this->addSegmentToNewsletter($sendingNewsletter, $segmentWithMultipleActiveEmails);
$usedSegments = $this->repository->getSubjectsOfActivelyUsedEmailsForSegments([
$unusedSegment->getId(),
$dynamicWithScheduledNewsletter->getId(),
$segmentWithSendingEmail->getId(),
$segmentWithAutomaticEmail->getId(),
$segmentWithWelcomeEmail->getId(),
$segmentWithPostNotification->getId(),
$segmentWithMultipleActiveEmails->getId(),
]);
expect(isset($usedSegments[$unusedSegment->getId()]))->false();
expect($usedSegments[$dynamicWithScheduledNewsletter->getId()])->equals(['Scheduled']);
expect($usedSegments[$segmentWithSendingEmail->getId()])->equals(['Sending']);
expect($usedSegments[$segmentWithAutomaticEmail->getId()])->equals(['Automatic']);
expect($usedSegments[$segmentWithWelcomeEmail->getId()])->equals(['Welcome']);
expect($usedSegments[$segmentWithPostNotification->getId()])->equals(['Notification']);
sort($usedSegments[$segmentWithMultipleActiveEmails->getId()]);
expect($usedSegments[$segmentWithMultipleActiveEmails->getId()])->equals(['Notification', 'Sending', 'Welcome2']);
}
public function _after() {
$this->cleanup();
}
private function createNewsletter(string $type, $subject, string $status = NewsletterEntity::STATUS_DRAFT): NewsletterEntity {
$newsletter = new NewsletterEntity();
$newsletter->setType($type);
$newsletter->setSubject($subject);
$newsletter->setBody(Fixtures::get('newsletter_body_template'));
$newsletter->setStatus($status);
$this->entityManager->persist($newsletter);
$this->entityManager->flush();
return $newsletter;
}
private function createSegment(string $name, string $type): SegmentEntity {
$segment = new SegmentEntity($name, $type, 'Description');
$this->entityManager->persist($segment);
$this->entityManager->flush();
return $segment;
}
private function addSegmentToNewsletter(NewsletterEntity $newsletter, SegmentEntity $segment) {
if (in_array($newsletter->getType(), [NewsletterEntity::TYPE_AUTOMATIC, NewsletterEntity::TYPE_WELCOME])) {
$this->createNewsletterOption(
$newsletter,
$newsletter->getType() === NewsletterEntity::TYPE_AUTOMATIC ? $this->automaticEmailSegmentOption : $this->welcomeEmailSegmentOption,
(string)$segment->getId()
);
} else {
$newsletterSegment = new NewsletterSegmentEntity($newsletter, $segment);
$newsletter->getNewsletterSegments()->add($newsletterSegment);
$this->entityManager->persist($newsletterSegment);
$this->entityManager->flush();
}
}
private function createQueueWithTaskAndSegment(NewsletterEntity $newsletter, $status = ScheduledTaskEntity::STATUS_SCHEDULED): SendingQueueEntity {
$task = new ScheduledTaskEntity();
$task->setType(SendingTask::TASK_TYPE);
$task->setStatus($status);
$this->entityManager->persist($task);
$queue = new SendingQueueEntity();
$queue->setNewsletter($newsletter);
$queue->setTask($task);
$this->entityManager->persist($queue);
$newsletter->getQueues()->add($queue);
$this->entityManager->flush();
return $queue;
}
private function createNewsletterOptionField(string $newsletterType, string $name): NewsletterOptionFieldEntity {
$newsletterOptionField = new NewsletterOptionFieldEntity();
$newsletterOptionField->setNewsletterType($newsletterType);
$newsletterOptionField->setName($name);
$this->entityManager->persist($newsletterOptionField);
$this->entityManager->flush();
return $newsletterOptionField;
}
private function createNewsletterOption(NewsletterEntity $newsletter, NewsletterOptionFieldEntity $field, $value): NewsletterOptionEntity {
$option = new NewsletterOptionEntity($newsletter, $field);
$option->setValue($value);
$this->entityManager->persist($option);
$this->entityManager->flush();
return $option;
}
private function cleanup() {
$this->truncateEntity(NewsletterEntity::class);
$this->truncateEntity(ScheduledTaskEntity::class);
$this->truncateEntity(SendingQueueEntity::class);
$this->truncateEntity(NewsletterSegmentEntity::class);
$this->truncateEntity(SegmentEntity::class);
$this->truncateEntity(NewsletterOptionFieldEntity::class);
$this->truncateEntity(NewsletterOptionEntity::class);
}
}

View File

@ -89,7 +89,7 @@ class SegmentsRepositoryTest extends \MailPoetTest {
private function addActiveNewsletterToSegment(SegmentEntity $segmentEntity) {
$newsletter = new NewsletterEntity();
$newsletter->setSubject('Subject');
$newsletter->setType(NewsletterEntity::TYPE_WELCOME);
$newsletter->setType(NewsletterEntity::TYPE_NOTIFICATION);
$newsletter->setStatus(NewsletterEntity::STATUS_ACTIVE);
$newsletterSegment = new NewsletterSegmentEntity($newsletter, $segmentEntity);
$this->entityManager->persist($newsletter);