Fix prefetching subscriber relations

[MAILPOET-4501]
This commit is contained in:
Jan Lysý
2022-08-03 13:13:19 +02:00
committed by Veljko V
parent f899eb1c16
commit 98d9952a44

View File

@ -9,15 +9,11 @@ use MailPoet\Entities\SubscriberCustomFieldEntity;
use MailPoet\Entities\SubscriberEntity; use MailPoet\Entities\SubscriberEntity;
use MailPoet\Statistics\StatisticsUnsubscribesRepository; use MailPoet\Statistics\StatisticsUnsubscribesRepository;
use MailPoet\Subscribers\SubscriberCustomFieldRepository; use MailPoet\Subscribers\SubscriberCustomFieldRepository;
use MailPoet\Subscribers\SubscriberSegmentRepository;
use MailPoetVendor\Doctrine\ORM\EntityManager; use MailPoetVendor\Doctrine\ORM\EntityManager;
class SubscribersResponseBuilder { class SubscribersResponseBuilder {
const DATE_FORMAT = 'Y-m-d H:i:s'; const DATE_FORMAT = 'Y-m-d H:i:s';
/** @var SubscriberSegmentRepository */
private $subscriberSegmentRepository;
/** @var StatisticsUnsubscribesRepository */ /** @var StatisticsUnsubscribesRepository */
private $statisticsUnsubscribesRepository; private $statisticsUnsubscribesRepository;
@ -32,12 +28,10 @@ class SubscribersResponseBuilder {
public function __construct( public function __construct(
EntityManager $entityManager, EntityManager $entityManager,
SubscriberSegmentRepository $subscriberSegmentRepository,
CustomFieldsRepository $customFieldsRepository, CustomFieldsRepository $customFieldsRepository,
SubscriberCustomFieldRepository $subscriberCustomFieldRepository, SubscriberCustomFieldRepository $subscriberCustomFieldRepository,
StatisticsUnsubscribesRepository $statisticsUnsubscribesRepository StatisticsUnsubscribesRepository $statisticsUnsubscribesRepository
) { ) {
$this->subscriberSegmentRepository = $subscriberSegmentRepository;
$this->statisticsUnsubscribesRepository = $statisticsUnsubscribesRepository; $this->statisticsUnsubscribesRepository = $statisticsUnsubscribesRepository;
$this->customFieldsRepository = $customFieldsRepository; $this->customFieldsRepository = $customFieldsRepository;
$this->subscriberCustomFieldRepository = $subscriberCustomFieldRepository; $this->subscriberCustomFieldRepository = $subscriberCustomFieldRepository;
@ -45,7 +39,7 @@ class SubscribersResponseBuilder {
} }
public function buildForListing(array $subscribers): array { public function buildForListing(array $subscribers): array {
$this->prefetchSegments($subscribers); $this->prefetchRelations($subscribers);
$data = []; $data = [];
foreach ($subscribers as $subscriber) { foreach ($subscribers as $subscriber) {
$data[] = $this->buildListingItem($subscriber); $data[] = $this->buildListingItem($subscriber);
@ -101,17 +95,16 @@ class SubscribersResponseBuilder {
private function buildSubscriptions(SubscriberEntity $subscriberEntity): array { private function buildSubscriptions(SubscriberEntity $subscriberEntity): array {
$result = []; $result = [];
$subscriptions = $this->subscriberSegmentRepository->findBy(['subscriber' => $subscriberEntity]); foreach ($subscriberEntity->getSubscriberSegments() as $subscriberSegment) {
foreach ($subscriptions as $subscription) { $segment = $subscriberSegment->getSegment();
$segment = $subscription->getSegment();
if ($segment instanceof SegmentEntity) { if ($segment instanceof SegmentEntity) {
$result[] = [ $result[] = [
'id' => $subscription->getId(), 'id' => $subscriberSegment->getId(),
'subscriber_id' => (string)$subscriberEntity->getId(), 'subscriber_id' => (string)$subscriberEntity->getId(),
'created_at' => ($createdAt = $subscription->getCreatedAt()) ? $createdAt->format(self::DATE_FORMAT) : null, 'created_at' => ($createdAt = $subscriberSegment->getCreatedAt()) ? $createdAt->format(self::DATE_FORMAT) : null,
'segment_id' => (string)$segment->getId(), 'segment_id' => (string)$segment->getId(),
'status' => $subscription->getStatus(), 'status' => $subscriberSegment->getStatus(),
'updated_at' => $subscription->getUpdatedAt()->format(self::DATE_FORMAT), 'updated_at' => $subscriberSegment->getUpdatedAt()->format(self::DATE_FORMAT),
]; ];
} }
} }
@ -177,12 +170,23 @@ class SubscribersResponseBuilder {
/** /**
* @param SubscriberEntity[] $subscribers * @param SubscriberEntity[] $subscribers
*/ */
private function prefetchSegments(array $subscribers) { private function prefetchRelations(array $subscribers): void {
// Prefetch subscriptions
$this->entityManager->createQueryBuilder() $this->entityManager->createQueryBuilder()
->select('PARTIAL s.{id}, ssg, sg') ->select('PARTIAL s.{id}, ssg, sg')
->from(SubscriberEntity::class, 's') ->from(SubscriberEntity::class, 's')
->join('s.subscriberSegments', 'ssg') ->leftJoin('s.subscriberSegments', 'ssg')
->join('ssg.segment', 'sg') ->leftJoin('ssg.segment', 'sg')
->where('s.id IN (:subscribers)')
->setParameter('subscribers', $subscribers)
->getQuery()
->getResult();
// Prefetch tags
$this->entityManager->createQueryBuilder()
->select('PARTIAL s.{id}, st, t')
->from(SubscriberEntity::class, 's')
->leftJoin('s.subscriberTags', 'st')
->leftJoin('st.tag', 't')
->where('s.id IN (:subscribers)') ->where('s.id IN (:subscribers)')
->setParameter('subscribers', $subscribers) ->setParameter('subscribers', $subscribers)
->getQuery() ->getQuery()