Use Doctrine in bulk actions for Segments

[MAILPOET-3169]
This commit is contained in:
Jan Lysý
2021-01-29 19:47:36 +01:00
committed by Veljko V
parent 1059f8d145
commit aff7de4659
2 changed files with 74 additions and 12 deletions

View File

@ -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 {

View File

@ -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<SegmentEntity>
@ -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;
}
}