Disallow trashing single dynamic segment with active email
[MAILPOET-3463]
This commit is contained in:
committed by
Veljko V
parent
9ffc3372e6
commit
f066bc8fdd
@ -10,6 +10,7 @@ use MailPoet\API\JSON\ResponseBuilders\DynamicSegmentsResponseBuilder;
|
|||||||
use MailPoet\Config\AccessControl;
|
use MailPoet\Config\AccessControl;
|
||||||
use MailPoet\Entities\SegmentEntity;
|
use MailPoet\Entities\SegmentEntity;
|
||||||
use MailPoet\Listing\Handler;
|
use MailPoet\Listing\Handler;
|
||||||
|
use MailPoet\Newsletter\Segment\NewsletterSegmentRepository;
|
||||||
use MailPoet\Segments\DynamicSegments\DynamicSegmentsListingRepository;
|
use MailPoet\Segments\DynamicSegments\DynamicSegmentsListingRepository;
|
||||||
use MailPoet\Segments\DynamicSegments\Exceptions\InvalidFilterException;
|
use MailPoet\Segments\DynamicSegments\Exceptions\InvalidFilterException;
|
||||||
use MailPoet\Segments\DynamicSegments\FilterDataMapper;
|
use MailPoet\Segments\DynamicSegments\FilterDataMapper;
|
||||||
@ -46,6 +47,9 @@ class DynamicSegments extends APIEndpoint {
|
|||||||
/** @var FilterDataMapper */
|
/** @var FilterDataMapper */
|
||||||
private $filterDataMapper;
|
private $filterDataMapper;
|
||||||
|
|
||||||
|
/** @var NewsletterSegmentRepository */
|
||||||
|
private $newsletterSegmentRepository;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
Handler $handler,
|
Handler $handler,
|
||||||
DynamicSegmentsListingRepository $dynamicSegmentsListingRepository,
|
DynamicSegmentsListingRepository $dynamicSegmentsListingRepository,
|
||||||
@ -53,7 +57,8 @@ class DynamicSegments extends APIEndpoint {
|
|||||||
SegmentsRepository $segmentsRepository,
|
SegmentsRepository $segmentsRepository,
|
||||||
SegmentSubscribersRepository $segmentSubscribersRepository,
|
SegmentSubscribersRepository $segmentSubscribersRepository,
|
||||||
FilterDataMapper $filterDataMapper,
|
FilterDataMapper $filterDataMapper,
|
||||||
SegmentSaveController $saveController
|
SegmentSaveController $saveController,
|
||||||
|
NewsletterSegmentRepository $newsletterSegmentRepository
|
||||||
) {
|
) {
|
||||||
$this->listingHandler = $handler;
|
$this->listingHandler = $handler;
|
||||||
$this->dynamicSegmentsListingRepository = $dynamicSegmentsListingRepository;
|
$this->dynamicSegmentsListingRepository = $dynamicSegmentsListingRepository;
|
||||||
@ -62,6 +67,7 @@ class DynamicSegments extends APIEndpoint {
|
|||||||
$this->saveController = $saveController;
|
$this->saveController = $saveController;
|
||||||
$this->segmentSubscribersRepository = $segmentSubscribersRepository;
|
$this->segmentSubscribersRepository = $segmentSubscribersRepository;
|
||||||
$this->filterDataMapper = $filterDataMapper;
|
$this->filterDataMapper = $filterDataMapper;
|
||||||
|
$this->newsletterSegmentRepository = $newsletterSegmentRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get($data = []) {
|
public function get($data = []) {
|
||||||
@ -148,6 +154,17 @@ class DynamicSegments extends APIEndpoint {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$activelyUsedNewslettersSubjects = $this->newsletterSegmentRepository->getSubjectsOfActivelyUsedEmailsForSegments([$segment->getId()]);
|
||||||
|
if (isset($activelyUsedNewslettersSubjects[$segment->getId()])) {
|
||||||
|
return $this->badRequest([
|
||||||
|
Error::BAD_REQUEST => str_replace(
|
||||||
|
'%$1s',
|
||||||
|
$activelyUsedNewslettersSubjects[$segment->getId()][0],
|
||||||
|
_x('List cannot be deleted because it’s used for %$1s email', 'Alert shown when trying to delete segment, which is assigned to any automatic emails.')
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
$this->segmentsRepository->bulkTrash([$segment->getId()], SegmentEntity::TYPE_DYNAMIC);
|
$this->segmentsRepository->bulkTrash([$segment->getId()], SegmentEntity::TYPE_DYNAMIC);
|
||||||
return $this->successResponse(
|
return $this->successResponse(
|
||||||
$this->segmentsResponseBuilder->build($segment),
|
$this->segmentsResponseBuilder->build($segment),
|
||||||
|
@ -14,6 +14,32 @@ class NewsletterSegmentRepository extends Repository {
|
|||||||
return NewsletterSegmentEntity::class;
|
return NewsletterSegmentEntity::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getSubjectsOfActivelyUsedEmailsForSegments(array $segmentIds): array {
|
||||||
|
$results = $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))')
|
||||||
|
->andWhere('ns.segment IN (:segmentIds)')
|
||||||
|
->setParameter('types', [
|
||||||
|
NewsletterEntity::TYPE_AUTOMATIC,
|
||||||
|
NewsletterEntity::TYPE_WELCOME,
|
||||||
|
NewsletterEntity::TYPE_NOTIFICATION,
|
||||||
|
])
|
||||||
|
->setParameter('segmentIds', $segmentIds)
|
||||||
|
->setParameter('scheduled', NewsletterEntity::STATUS_SCHEDULED)
|
||||||
|
->addGroupBy('n.id, q.id, t.id')
|
||||||
|
->getQuery()
|
||||||
|
->getResult();
|
||||||
|
|
||||||
|
$nameMap = [];
|
||||||
|
foreach ($results as $result) {
|
||||||
|
$nameMap[(string)$result['segment_id']][] = $result['subject'];
|
||||||
|
}
|
||||||
|
return $nameMap;
|
||||||
|
}
|
||||||
|
|
||||||
public function getAutomatedEmailSubjectsBySegmentIds(array $segmentIds): array {
|
public function getAutomatedEmailSubjectsBySegmentIds(array $segmentIds): array {
|
||||||
$results = $this->doctrineRepository->createQueryBuilder('ns')
|
$results = $this->doctrineRepository->createQueryBuilder('ns')
|
||||||
->join('ns.newsletter', 'n')
|
->join('ns.newsletter', 'n')
|
||||||
|
@ -2,9 +2,12 @@
|
|||||||
|
|
||||||
namespace MailPoet\API\JSON\v1;
|
namespace MailPoet\API\JSON\v1;
|
||||||
|
|
||||||
|
use MailPoet\API\JSON\Response as APIResponse;
|
||||||
use MailPoet\DI\ContainerWrapper;
|
use MailPoet\DI\ContainerWrapper;
|
||||||
use MailPoet\Entities\DynamicSegmentFilterData;
|
use MailPoet\Entities\DynamicSegmentFilterData;
|
||||||
use MailPoet\Entities\DynamicSegmentFilterEntity;
|
use MailPoet\Entities\DynamicSegmentFilterEntity;
|
||||||
|
use MailPoet\Entities\NewsletterEntity;
|
||||||
|
use MailPoet\Entities\NewsletterSegmentEntity;
|
||||||
use MailPoet\Entities\SegmentEntity;
|
use MailPoet\Entities\SegmentEntity;
|
||||||
|
|
||||||
class DynamicSegmentsTest extends \MailPoetTest {
|
class DynamicSegmentsTest extends \MailPoetTest {
|
||||||
@ -83,6 +86,22 @@ class DynamicSegmentsTest extends \MailPoetTest {
|
|||||||
expect($dynamicSegment->getDeletedAt())->notNull();
|
expect($dynamicSegment->getDeletedAt())->notNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testItReturnsErrorWhenTrashingSegmentWithActiveNewsletter() {
|
||||||
|
$dynamicSegment = $this->createDynamicSegmentEntity('Trash test 2', 'description');
|
||||||
|
$newsletter = new NewsletterEntity();
|
||||||
|
$newsletter->setSubject('Subject');
|
||||||
|
$newsletter->setType(NewsletterEntity::TYPE_WELCOME);
|
||||||
|
$newsletterSegment = new NewsletterSegmentEntity($newsletter, $dynamicSegment);
|
||||||
|
$this->entityManager->persist($newsletter);
|
||||||
|
$this->entityManager->persist($newsletterSegment);
|
||||||
|
$this->entityManager->flush();
|
||||||
|
|
||||||
|
$response = $this->endpoint->trash(['id' => $dynamicSegment->getId()]);
|
||||||
|
$this->entityManager->refresh($dynamicSegment);
|
||||||
|
expect($response->status)->equals(APIResponse::STATUS_BAD_REQUEST);
|
||||||
|
expect($response->errors[0]['message'])->equals("List cannot be deleted because it’s used for 'Subject' email");
|
||||||
|
}
|
||||||
|
|
||||||
public function testItCanRestoreASegment() {
|
public function testItCanRestoreASegment() {
|
||||||
$dynamicSegment = $this->createDynamicSegmentEntity('Trash test', 'description');
|
$dynamicSegment = $this->createDynamicSegmentEntity('Trash test', 'description');
|
||||||
|
|
||||||
@ -187,5 +206,7 @@ class DynamicSegmentsTest extends \MailPoetTest {
|
|||||||
parent::_after();
|
parent::_after();
|
||||||
$this->truncateEntity(SegmentEntity::class);
|
$this->truncateEntity(SegmentEntity::class);
|
||||||
$this->truncateEntity(DynamicSegmentFilterEntity::class);
|
$this->truncateEntity(DynamicSegmentFilterEntity::class);
|
||||||
|
$this->truncateEntity(NewsletterSegmentEntity::class);
|
||||||
|
$this->truncateEntity(NewsletterEntity::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user