diff --git a/lib/API/JSON/v1/Segments.php b/lib/API/JSON/v1/Segments.php index 9da640d144..7dbed1a000 100644 --- a/lib/API/JSON/v1/Segments.php +++ b/lib/API/JSON/v1/Segments.php @@ -20,6 +20,7 @@ use MailPoet\Segments\SegmentsRepository; use MailPoet\Segments\WooCommerce; use MailPoet\Segments\WP; use MailPoet\Subscribers\SubscribersRepository; +use MailPoet\UnexpectedValueException; use MailPoet\WP\Functions as WPFunctions; class Segments extends APIEndpoint { @@ -27,9 +28,6 @@ class Segments extends APIEndpoint { 'global' => AccessControl::PERMISSION_MANAGE_SEGMENTS, ]; - /** @var Listing\BulkActionController */ - private $bulkAction; - /** @var Listing\Handler */ private $listingHandler; @@ -55,7 +53,6 @@ class Segments extends APIEndpoint { private $segmentListingRepository; public function __construct( - Listing\BulkActionController $bulkAction, Listing\Handler $listingHandler, SegmentsRepository $segmentsRepository, SegmentListingRepository $segmentListingRepository, @@ -65,7 +62,6 @@ class Segments extends APIEndpoint { WooCommerce $wooCommerce, WP $wpSegment ) { - $this->bulkAction = $bulkAction; $this->listingHandler = $listingHandler; $this->wooCommerceSync = $wooCommerce; $this->segmentsRepository = $segmentsRepository; @@ -225,14 +221,20 @@ class Segments extends APIEndpoint { } public function bulkAction($data = []) { - try { - $meta = $this->bulkAction->apply('\MailPoet\Models\Segment', $data); - return $this->successResponse(null, $meta); - } catch (\Exception $e) { - return $this->errorResponse([ - $e->getCode() => $e->getMessage(), - ]); + $definition = $this->listingHandler->getListingDefinition($data['listing']); + $ids = $this->segmentListingRepository->getActionableIds($definition); + $count = 0; + if ($data['action'] === 'trash') { + $count = $this->segmentsRepository->bulkTrash($ids); + } elseif ($data['action'] === 'restore') { + $count = $this->segmentsRepository->bulkRestore($ids); + } elseif ($data['action'] === 'delete') { + $count = $this->segmentsRepository->bulkDelete($ids); + } else { + throw UnexpectedValueException::create() + ->withErrors([APIError::BAD_REQUEST => "Invalid bulk action '{$data['action']}' provided."]); } + return $this->successResponse(null, ['count' => $count]); } private function getSegment(array $data): ?SegmentEntity { diff --git a/lib/Segments/SegmentsRepository.php b/lib/Segments/SegmentsRepository.php index 9be5fa929f..dd70b166fb 100644 --- a/lib/Segments/SegmentsRepository.php +++ b/lib/Segments/SegmentsRepository.php @@ -2,9 +2,14 @@ namespace MailPoet\Segments; +use Carbon\Carbon; +use DateTime; use MailPoet\Doctrine\Repository; use MailPoet\Entities\SegmentEntity; +use MailPoet\Entities\SubscriberSegmentEntity; use MailPoet\NotFoundException; +use MailPoetVendor\Doctrine\DBAL\Connection; +use MailPoetVendor\Doctrine\ORM\EntityManager; /** * @extends Repository @@ -69,4 +74,59 @@ class SegmentsRepository extends Repository { $this->flush(); return $segment; } + + public function bulkDelete(array $ids) { + if (empty($ids)) { + return 0; + } + + return $this->entityManager->transactional(function (EntityManager $entityManager) use ($ids) { + $subscriberSegmentTable = $entityManager->getClassMetadata(SubscriberSegmentEntity::class)->getTableName(); + $segmentTable = $entityManager->getClassMetadata(SegmentEntity::class)->getTableName(); + + $entityManager->getConnection()->executeUpdate(" + DELETE ss FROM $subscriberSegmentTable ss + JOIN $segmentTable s ON ss.`segment_id` = s.`id` + WHERE ss.`segment_id` IN (:ids) + AND s.`type` = :typeDefault + ", [ + 'ids' => $ids, + 'typeDefault' => SegmentEntity::TYPE_DEFAULT, + ], ['ids' => Connection::PARAM_INT_ARRAY]); + + return $entityManager->getConnection()->executeUpdate(" + DELETE s FROM $segmentTable s + WHERE s.`id` IN (:ids) + AND s.`type` = :typeDefault + ", [ + 'ids' => $ids, + 'typeDefault' => SegmentEntity::TYPE_DEFAULT, + ], ['ids' => Connection::PARAM_INT_ARRAY]); + }); + } + + public function bulkTrash(array $ids): int { + return $this->updateDeletedAt($ids, new Carbon()); + } + + public function bulkRestore(array $ids): int { + return $this->updateDeletedAt($ids, null); + } + + private function updateDeletedAt(array $ids, ?DateTime $deletedAt): int { + if (empty($ids)) { + return 0; + } + + $rows = $this->entityManager->createQueryBuilder()->update(SegmentEntity::class, 's') + ->set('s.deletedAt', ':deletedAt') + ->where('s.id IN (:ids)') + ->andWhere('s.type = :typeDefault') + ->setParameter('deletedAt', $deletedAt) + ->setParameter('ids', $ids) + ->setParameter('typeDefault', SegmentEntity::TYPE_DEFAULT) + ->getQuery()->execute(); + + return $rows; + } }