From 5c20af3384ea9f08760672debdbac8d35120c03c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lys=C3=BD?= Date: Wed, 2 Dec 2020 09:59:48 +0100 Subject: [PATCH] Move and restore subscribers from WP Users list [MAILPOET-3142] --- lib/API/JSON/v1/Segments.php | 25 +++++++++++++++++++++++ lib/Subscribers/SubscribersRepository.php | 24 ++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/lib/API/JSON/v1/Segments.php b/lib/API/JSON/v1/Segments.php index bd1fe7aa2f..76fd9687f0 100644 --- a/lib/API/JSON/v1/Segments.php +++ b/lib/API/JSON/v1/Segments.php @@ -9,12 +9,14 @@ use MailPoet\API\JSON\ResponseBuilders\SegmentsResponseBuilder; use MailPoet\Config\AccessControl; use MailPoet\Doctrine\Validator\ValidationException; use MailPoet\Entities\SegmentEntity; +use MailPoet\Entities\SubscriberEntity; use MailPoet\Listing; use MailPoet\Models\Segment; use MailPoet\Segments\SegmentSaveController; use MailPoet\Segments\SegmentsRepository; use MailPoet\Segments\WooCommerce; use MailPoet\Segments\WP; +use MailPoet\Subscribers\SubscribersRepository; use MailPoet\WP\Functions as WPFunctions; class Segments extends APIEndpoint { @@ -37,6 +39,9 @@ class Segments extends APIEndpoint { /** @var SegmentSaveController */ private $segmentSavecontroller; + /** @var SubscribersRepository */ + private $subscribersRepository; + /** @var WooCommerce */ private $wooCommerceSync; @@ -49,6 +54,7 @@ class Segments extends APIEndpoint { SegmentsRepository $segmentsRepository, SegmentsResponseBuilder $segmentsResponseBuilder, SegmentSaveController $segmentSavecontroller, + SubscribersRepository $subscribersRepository, WooCommerce $wooCommerce, WP $wpSegment ) { @@ -58,6 +64,7 @@ class Segments extends APIEndpoint { $this->segmentsRepository = $segmentsRepository; $this->segmentsResponseBuilder = $segmentsResponseBuilder; $this->segmentSavecontroller = $segmentSavecontroller; + $this->subscribersRepository = $subscribersRepository; $this->wpSegment = $wpSegment; } @@ -115,6 +122,15 @@ class Segments extends APIEndpoint { $id = (isset($data['id']) ? (int)$data['id'] : false); $segment = Segment::findOne($id); if ($segment instanceof Segment) { + // When the segment is of type WP_USERS we want to restore all its subscribers + if ($segment->type === SegmentEntity::TYPE_WP_USERS) { + $subscribers = $this->subscribersRepository->findBySegment((int)$segment->id); + $subscriberIds = array_map(function (SubscriberEntity $subscriberEntity): int { + return (int)$subscriberEntity->getId(); + }, $subscribers); + $this->subscribersRepository->bulkRestore($subscriberIds); + } + $segment->restore(); $segment = Segment::findOne($segment->id); if(!$segment instanceof Segment) return $this->errorResponse(); @@ -133,6 +149,15 @@ class Segments extends APIEndpoint { $id = (isset($data['id']) ? (int)$data['id'] : false); $segment = Segment::findOne($id); if ($segment instanceof Segment) { + // When the segment is of type WP_USERS we want to trash all subscribers who aren't subscribed in another list + if ($segment->type === SegmentEntity::TYPE_WP_USERS) { + $subscribers = $this->subscribersRepository->findExclusiveSubscribersBySegment((int)$segment->id); + $subscriberIds = array_map(function (SubscriberEntity $subscriberEntity): int { + return (int)$subscriberEntity->getId(); + }, $subscribers); + $this->subscribersRepository->bulkTrash($subscriberIds); + } + $segment->trash(); $segment = Segment::findOne($segment->id); if(!$segment instanceof Segment) return $this->errorResponse(); diff --git a/lib/Subscribers/SubscribersRepository.php b/lib/Subscribers/SubscribersRepository.php index 34c085e10e..bc89ae5624 100644 --- a/lib/Subscribers/SubscribersRepository.php +++ b/lib/Subscribers/SubscribersRepository.php @@ -55,6 +55,30 @@ class SubscribersRepository extends Repository { return (int)$query->getSingleScalarResult(); } + public function findBySegment(int $segmentId): array { + return $this->entityManager + ->createQueryBuilder() + ->select('s') + ->from(SubscriberEntity::class, 's') + ->join('s.subscriberSegments', 'ss', Join::WITH, 'ss.segment = :segment') + ->setParameter('segment', $segmentId) + ->getQuery()->getResult(); + } + + public function findExclusiveSubscribersBySegment(int $segmentId): array { + return $this->entityManager->createQueryBuilder() + ->select('s') + ->from(SubscriberEntity::class, 's') + ->join('s.subscriberSegments', 'ss', Join::WITH, 'ss.segment = :segment') + ->leftJoin('s.subscriberSegments', 'ss2', Join::WITH, 'ss2.segment <> :segment AND ss2.status = :subscribed') + ->leftJoin('ss2.segment', 'seg', Join::WITH, 'seg.deletedAt IS NULL') + ->groupBy('s.id') + ->andHaving('COUNT(seg.id) = 0') + ->setParameter('segment', $segmentId) + ->setParameter('subscribed', SubscriberEntity::STATUS_SUBSCRIBED) + ->getQuery()->getResult(); + } + /** * @return int - number of processed ids */