Нет описания

SubscribersResponseBuilder.php 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <?php
  2. namespace MailPoet\API\JSON\ResponseBuilders;
  3. if (!defined('ABSPATH')) exit;
  4. use MailPoet\CustomFields\CustomFieldsRepository;
  5. use MailPoet\Entities\NewsletterEntity;
  6. use MailPoet\Entities\SegmentEntity;
  7. use MailPoet\Entities\SubscriberCustomFieldEntity;
  8. use MailPoet\Entities\SubscriberEntity;
  9. use MailPoet\Statistics\StatisticsUnsubscribesRepository;
  10. use MailPoet\Subscribers\SubscriberCustomFieldRepository;
  11. use MailPoet\Subscribers\SubscriberSegmentRepository;
  12. use MailPoetVendor\Doctrine\ORM\EntityManager;
  13. class SubscribersResponseBuilder {
  14. const DATE_FORMAT = 'Y-m-d H:i:s';
  15. /** @var SubscriberSegmentRepository */
  16. private $subscriberSegmentRepository;
  17. /** @var StatisticsUnsubscribesRepository */
  18. private $statisticsUnsubscribesRepository;
  19. /** @var CustomFieldsRepository */
  20. private $customFieldsRepository;
  21. /** @var SubscriberCustomFieldRepository */
  22. private $subscriberCustomFieldRepository;
  23. /** @var EntityManager */
  24. private $entityManager;
  25. public function __construct(
  26. EntityManager $entityManager,
  27. SubscriberSegmentRepository $subscriberSegmentRepository,
  28. CustomFieldsRepository $customFieldsRepository,
  29. SubscriberCustomFieldRepository $subscriberCustomFieldRepository,
  30. StatisticsUnsubscribesRepository $statisticsUnsubscribesRepository
  31. ) {
  32. $this->subscriberSegmentRepository = $subscriberSegmentRepository;
  33. $this->statisticsUnsubscribesRepository = $statisticsUnsubscribesRepository;
  34. $this->customFieldsRepository = $customFieldsRepository;
  35. $this->subscriberCustomFieldRepository = $subscriberCustomFieldRepository;
  36. $this->entityManager = $entityManager;
  37. }
  38. public function buildForListing(array $subscribers): array {
  39. $this->prefetchSegments($subscribers);
  40. $data = [];
  41. foreach ($subscribers as $subscriber) {
  42. $data[] = $this->buildListingItem($subscriber);
  43. }
  44. return $data;
  45. }
  46. private function buildListingItem(SubscriberEntity $subscriber): array {
  47. return [
  48. 'id' => (string)$subscriber->getId(), // (string) for BC
  49. 'email' => $subscriber->getEmail(),
  50. 'first_name' => $subscriber->getFirstName(),
  51. 'last_name' => $subscriber->getLastName(),
  52. 'subscriptions' => $this->buildSubscriptions($subscriber),
  53. 'status' => $subscriber->getStatus(),
  54. 'count_confirmations' => $subscriber->getConfirmationsCount(),
  55. 'wp_user_id' => $subscriber->getWpUserId(),
  56. 'is_woocommerce_user' => $subscriber->getIsWoocommerceUser(),
  57. 'created_at' => $subscriber->getCreatedAt()->format(self::DATE_FORMAT),
  58. 'engagement_score' => $subscriber->getEngagementScore(),
  59. ];
  60. }
  61. public function build(SubscriberEntity $subscriberEntity): array {
  62. $data = [
  63. 'id' => (string)$subscriberEntity->getId(),
  64. 'wp_user_id' => $subscriberEntity->getWpUserId(),
  65. 'is_woocommerce_user' => $subscriberEntity->getIsWoocommerceUser(),
  66. 'subscriptions' => $this->buildSubscriptions($subscriberEntity),
  67. 'unsubscribes' => $this->buildUnsubscribes($subscriberEntity),
  68. 'status' => $subscriberEntity->getStatus(),
  69. 'last_name' => $subscriberEntity->getLastName(),
  70. 'first_name' => $subscriberEntity->getFirstName(),
  71. 'email' => $subscriberEntity->getEmail(),
  72. 'created_at' => $subscriberEntity->getCreatedAt()->format(self::DATE_FORMAT),
  73. 'updated_at' => $subscriberEntity->getUpdatedAt()->format(self::DATE_FORMAT),
  74. 'deleted_at' => ($deletedAt = $subscriberEntity->getDeletedAt()) ? $deletedAt->format(self::DATE_FORMAT) : null,
  75. 'subscribed_ip' => $subscriberEntity->getSubscribedIp(),
  76. 'confirmed_ip' => $subscriberEntity->getConfirmedIp(),
  77. 'confirmed_at' => ($confirmedAt = $subscriberEntity->getConfirmedAt()) ? $confirmedAt->format(self::DATE_FORMAT) : null,
  78. 'last_subscribed_at' => ($lastSubscribedAt = $subscriberEntity->getLastSubscribedAt()) ? $lastSubscribedAt->format(self::DATE_FORMAT) : null,
  79. 'unconfirmed_data' => $subscriberEntity->getUnconfirmedData(),
  80. 'source' => $subscriberEntity->getSource(),
  81. 'count_confirmations' => $subscriberEntity->getConfirmationsCount(),
  82. 'unsubscribe_token' => $subscriberEntity->getUnsubscribeToken(),
  83. 'link_token' => $subscriberEntity->getLinkToken(),
  84. ];
  85. $data = $this->buildCustomFields($subscriberEntity, $data);
  86. return $data;
  87. }
  88. private function buildSubscriptions(SubscriberEntity $subscriberEntity): array {
  89. $result = [];
  90. $subscriptions = $this->subscriberSegmentRepository->findBy(['subscriber' => $subscriberEntity]);
  91. foreach ($subscriptions as $subscription) {
  92. $segment = $subscription->getSegment();
  93. if ($segment instanceof SegmentEntity) {
  94. $result[] = [
  95. 'segment_id' => (string)$segment->getId(),
  96. 'status' => $subscription->getStatus(),
  97. 'updated_at' => $subscription->getUpdatedAt()->format(self::DATE_FORMAT),
  98. ];
  99. }
  100. }
  101. return $result;
  102. }
  103. private function buildUnsubscribes(SubscriberEntity $subscriberEntity): array {
  104. $unsubscribes = $this->statisticsUnsubscribesRepository->findBy([
  105. 'subscriber' => $subscriberEntity,
  106. ], [
  107. 'createdAt' => 'desc',
  108. ]);
  109. $result = [];
  110. foreach ($unsubscribes as $unsubscribe) {
  111. $mapped = [
  112. 'source' => $unsubscribe->getSource(),
  113. 'meta' => $unsubscribe->getMeta(),
  114. 'createdAt' => $unsubscribe->getCreatedAt(),
  115. ];
  116. $newsletter = $unsubscribe->getNewsletter();
  117. if ($newsletter instanceof NewsletterEntity) {
  118. $mapped['newsletterId'] = $newsletter->getId();
  119. $mapped['newsletterSubject'] = $newsletter->getSubject();
  120. }
  121. $result[] = $mapped;
  122. }
  123. return $result;
  124. }
  125. private function buildCustomFields(SubscriberEntity $subscriberEntity, array $data): array {
  126. $customFields = $this->customFieldsRepository->findAll();
  127. foreach ($customFields as $customField) {
  128. $subscriberCustomField = $this->subscriberCustomFieldRepository->findOneBy(
  129. ['subscriber' => $subscriberEntity, 'customField' => $customField]
  130. );
  131. if ($subscriberCustomField instanceof SubscriberCustomFieldEntity) {
  132. $data['cf_' . $customField->getId()] = $subscriberCustomField->getValue();
  133. }
  134. }
  135. return $data;
  136. }
  137. /**
  138. * @param SubscriberEntity[] $subscribers
  139. */
  140. private function prefetchSegments(array $subscribers) {
  141. $this->entityManager->createQueryBuilder()
  142. ->select('PARTIAL s.{id}, ssg, sg')
  143. ->from(SubscriberEntity::class, 's')
  144. ->join('s.subscriberSegments', 'ssg')
  145. ->join('ssg.segment', 'sg')
  146. ->where('s.id IN (:subscribers)')
  147. ->setParameter('subscribers', $subscribers)
  148. ->getQuery()
  149. ->getResult();
  150. }
  151. }