199 lines
7.8 KiB
PHP
199 lines
7.8 KiB
PHP
|
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
|
||
|
|
||
|
namespace MailPoet\API\JSON\ResponseBuilders;
|
||
|
|
||
|
if (!defined('ABSPATH')) exit;
|
||
|
|
||
|
|
||
|
use MailPoet\CustomFields\CustomFieldsRepository;
|
||
|
use MailPoet\Entities\NewsletterEntity;
|
||
|
use MailPoet\Entities\SegmentEntity;
|
||
|
use MailPoet\Entities\SubscriberCustomFieldEntity;
|
||
|
use MailPoet\Entities\SubscriberEntity;
|
||
|
use MailPoet\Statistics\StatisticsUnsubscribesRepository;
|
||
|
use MailPoet\Subscribers\SubscriberCustomFieldRepository;
|
||
|
use MailPoetVendor\Doctrine\ORM\EntityManager;
|
||
|
|
||
|
class SubscribersResponseBuilder {
|
||
|
const DATE_FORMAT = 'Y-m-d H:i:s';
|
||
|
|
||
|
/** @var StatisticsUnsubscribesRepository */
|
||
|
private $statisticsUnsubscribesRepository;
|
||
|
|
||
|
/** @var CustomFieldsRepository */
|
||
|
private $customFieldsRepository;
|
||
|
|
||
|
/** @var SubscriberCustomFieldRepository */
|
||
|
private $subscriberCustomFieldRepository;
|
||
|
|
||
|
/** @var EntityManager */
|
||
|
private $entityManager;
|
||
|
|
||
|
public function __construct(
|
||
|
EntityManager $entityManager,
|
||
|
CustomFieldsRepository $customFieldsRepository,
|
||
|
SubscriberCustomFieldRepository $subscriberCustomFieldRepository,
|
||
|
StatisticsUnsubscribesRepository $statisticsUnsubscribesRepository
|
||
|
) {
|
||
|
$this->statisticsUnsubscribesRepository = $statisticsUnsubscribesRepository;
|
||
|
$this->customFieldsRepository = $customFieldsRepository;
|
||
|
$this->subscriberCustomFieldRepository = $subscriberCustomFieldRepository;
|
||
|
$this->entityManager = $entityManager;
|
||
|
}
|
||
|
|
||
|
public function buildForListing(array $subscribers): array {
|
||
|
$this->prefetchRelations($subscribers);
|
||
|
$data = [];
|
||
|
foreach ($subscribers as $subscriber) {
|
||
|
$data[] = $this->buildListingItem($subscriber);
|
||
|
}
|
||
|
return $data;
|
||
|
}
|
||
|
|
||
|
private function buildListingItem(SubscriberEntity $subscriber): array {
|
||
|
return [
|
||
|
'id' => (string)$subscriber->getId(), // (string) for BC
|
||
|
'email' => $subscriber->getEmail(),
|
||
|
'first_name' => $subscriber->getFirstName(),
|
||
|
'last_name' => $subscriber->getLastName(),
|
||
|
'subscriptions' => $this->buildSubscriptions($subscriber),
|
||
|
'status' => $subscriber->getStatus(),
|
||
|
'count_confirmations' => $subscriber->getConfirmationsCount(),
|
||
|
'wp_user_id' => $subscriber->getWpUserId(),
|
||
|
'is_woocommerce_user' => $subscriber->getIsWoocommerceUser(),
|
||
|
'created_at' => ($createdAt = $subscriber->getCreatedAt()) ? $createdAt->format(self::DATE_FORMAT) : null,
|
||
|
'engagement_score' => $subscriber->getEngagementScore(),
|
||
|
'tags' => $this->buildTags($subscriber),
|
||
|
];
|
||
|
}
|
||
|
|
||
|
public function build(SubscriberEntity $subscriberEntity): array {
|
||
|
$data = [
|
||
|
'id' => (string)$subscriberEntity->getId(),
|
||
|
'wp_user_id' => $subscriberEntity->getWpUserId(),
|
||
|
'is_woocommerce_user' => $subscriberEntity->getIsWoocommerceUser(),
|
||
|
'subscriptions' => $this->buildSubscriptions($subscriberEntity),
|
||
|
'unsubscribes' => $this->buildUnsubscribes($subscriberEntity),
|
||
|
'status' => $subscriberEntity->getStatus(),
|
||
|
'last_name' => $subscriberEntity->getLastName(),
|
||
|
'first_name' => $subscriberEntity->getFirstName(),
|
||
|
'email' => $subscriberEntity->getEmail(),
|
||
|
'created_at' => ($createdAt = $subscriberEntity->getCreatedAt()) ? $createdAt->format(self::DATE_FORMAT) : null,
|
||
|
'updated_at' => $subscriberEntity->getUpdatedAt()->format(self::DATE_FORMAT),
|
||
|
'deleted_at' => ($deletedAt = $subscriberEntity->getDeletedAt()) ? $deletedAt->format(self::DATE_FORMAT) : null,
|
||
|
'subscribed_ip' => $subscriberEntity->getSubscribedIp(),
|
||
|
'confirmed_ip' => $subscriberEntity->getConfirmedIp(),
|
||
|
'confirmed_at' => ($confirmedAt = $subscriberEntity->getConfirmedAt()) ? $confirmedAt->format(self::DATE_FORMAT) : null,
|
||
|
'last_subscribed_at' => ($lastSubscribedAt = $subscriberEntity->getLastSubscribedAt()) ? $lastSubscribedAt->format(self::DATE_FORMAT) : null,
|
||
|
'unconfirmed_data' => $subscriberEntity->getUnconfirmedData(),
|
||
|
'source' => $subscriberEntity->getSource(),
|
||
|
'count_confirmations' => $subscriberEntity->getConfirmationsCount(),
|
||
|
'unsubscribe_token' => $subscriberEntity->getUnsubscribeToken(),
|
||
|
'link_token' => $subscriberEntity->getLinkToken(),
|
||
|
'tags' => $this->buildTags($subscriberEntity),
|
||
|
];
|
||
|
|
||
|
return $this->buildCustomFields($subscriberEntity, $data);
|
||
|
}
|
||
|
|
||
|
private function buildSubscriptions(SubscriberEntity $subscriberEntity): array {
|
||
|
$result = [];
|
||
|
foreach ($subscriberEntity->getSubscriberSegments() as $subscriberSegment) {
|
||
|
$segment = $subscriberSegment->getSegment();
|
||
|
if ($segment instanceof SegmentEntity) {
|
||
|
$result[] = [
|
||
|
'id' => $subscriberSegment->getId(),
|
||
|
'subscriber_id' => (string)$subscriberEntity->getId(),
|
||
|
'created_at' => ($createdAt = $subscriberSegment->getCreatedAt()) ? $createdAt->format(self::DATE_FORMAT) : null,
|
||
|
'segment_id' => (string)$segment->getId(),
|
||
|
'status' => $subscriberSegment->getStatus(),
|
||
|
'updated_at' => $subscriberSegment->getUpdatedAt()->format(self::DATE_FORMAT),
|
||
|
];
|
||
|
}
|
||
|
}
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
private function buildUnsubscribes(SubscriberEntity $subscriberEntity): array {
|
||
|
$unsubscribes = $this->statisticsUnsubscribesRepository->findBy([
|
||
|
'subscriber' => $subscriberEntity,
|
||
|
], [
|
||
|
'createdAt' => 'desc',
|
||
|
]);
|
||
|
$result = [];
|
||
|
foreach ($unsubscribes as $unsubscribe) {
|
||
|
$mapped = [
|
||
|
'source' => $unsubscribe->getSource(),
|
||
|
'meta' => $unsubscribe->getMeta(),
|
||
|
'createdAt' => $unsubscribe->getCreatedAt(),
|
||
|
];
|
||
|
$newsletter = $unsubscribe->getNewsletter();
|
||
|
if ($newsletter instanceof NewsletterEntity) {
|
||
|
$mapped['newsletterId'] = $newsletter->getId();
|
||
|
$mapped['newsletterSubject'] = $newsletter->getSubject();
|
||
|
}
|
||
|
$result[] = $mapped;
|
||
|
}
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
private function buildCustomFields(SubscriberEntity $subscriberEntity, array $data): array {
|
||
|
$customFields = $this->customFieldsRepository->findAll();
|
||
|
|
||
|
foreach ($customFields as $customField) {
|
||
|
$subscriberCustomField = $this->subscriberCustomFieldRepository->findOneBy(
|
||
|
['subscriber' => $subscriberEntity, 'customField' => $customField]
|
||
|
);
|
||
|
if ($subscriberCustomField instanceof SubscriberCustomFieldEntity) {
|
||
|
$data['cf_' . $customField->getId()] = $subscriberCustomField->getValue();
|
||
|
}
|
||
|
}
|
||
|
return $data;
|
||
|
}
|
||
|
|
||
|
private function buildTags(SubscriberEntity $subscriber): array {
|
||
|
$result = [];
|
||
|
foreach ($subscriber->getSubscriberTags() as $subscriberTag) {
|
||
|
$tag = $subscriberTag->getTag();
|
||
|
if (!$tag) {
|
||
|
continue;
|
||
|
}
|
||
|
$result[] = [
|
||
|
'id' => $subscriberTag->getId(),
|
||
|
'subscriber_id' => (string)$subscriber->getId(),
|
||
|
'tag_id' => (string)$tag->getId(),
|
||
|
'created_at' => ($createdAt = $subscriberTag->getCreatedAt()) ? $createdAt->format(self::DATE_FORMAT) : null,
|
||
|
'updated_at' => $subscriberTag->getUpdatedAt()->format(self::DATE_FORMAT),
|
||
|
'name' => $tag->getName(),
|
||
|
];
|
||
|
}
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param SubscriberEntity[] $subscribers
|
||
|
*/
|
||
|
private function prefetchRelations(array $subscribers): void {
|
||
|
// Prefetch subscriptions
|
||
|
$this->entityManager->createQueryBuilder()
|
||
|
->select('PARTIAL s.{id}, ssg, sg')
|
||
|
->from(SubscriberEntity::class, 's')
|
||
|
->leftJoin('s.subscriberSegments', 'ssg')
|
||
|
->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)')
|
||
|
->setParameter('subscribers', $subscribers)
|
||
|
->getQuery()
|
||
|
->getResult();
|
||
|
}
|
||
|
}
|