AccessControl::PERMISSION_MANAGE_EMAILS, ]; /** @var CampaignStats\PurchasedProducts */ private $purchasedProducts; /** @var NewslettersRepository */ private $newslettersRepository; /** @var NewsletterStatisticsRepository */ private $newsletterStatisticsRepository; /** @var StatsResponseBuilder */ private $statsResponseBuilder; /** @var StatisticsClicksRepository */ private $statisticsClicksRepository; /** @var SubscriberEngagement */ private $listings; /** @var NewsletterUrl */ private $newsletterUrl; public function __construct( CampaignStats\PurchasedProducts $purchasedProducts, NewslettersRepository $newslettersRepository, StatsResponseBuilder $statsResponseBuilder, StatisticsClicksRepository $statisticsClicksRepository, SubscriberEngagement $listings, NewsletterStatisticsRepository $newsletterStatisticsRepository, NewsletterUrl $newsletterUrl ) { $this->purchasedProducts = $purchasedProducts; $this->newslettersRepository = $newslettersRepository; $this->newsletterStatisticsRepository = $newsletterStatisticsRepository; $this->statsResponseBuilder = $statsResponseBuilder; $this->statisticsClicksRepository = $statisticsClicksRepository; $this->listings = $listings; $this->newsletterUrl = $newsletterUrl; } public function get($data = []) { $newsletter = isset($data['id']) ? $this->newslettersRepository->findOneById((int)$data['id']) : null; if (!$newsletter instanceof NewsletterEntity) { return $this->errorResponse( [ APIError::NOT_FOUND => __('This newsletter does not exist.', 'mailpoet-premium'), ] ); } $allowAllNewsletterTypes = isset($data['accept']) && strtolower($data['accept']) === 'all'; $isNewsletterSent = $this->isNewsletterSent($newsletter); $statistics = $this->newsletterStatisticsRepository->getStatistics($newsletter); if (!$allowAllNewsletterTypes && !$isNewsletterSent) { return $this->errorResponse( [ APIError::NOT_FOUND => __('This newsletter is not sent yet.', 'mailpoet-premium'), ] ); } $clickedLinks = $isNewsletterSent ? $this->statisticsClicksRepository->getClickedLinks($newsletter) : []; $clickedLinksWithAggregatedUnsubscribes = $isNewsletterSent ? $this->getClickedLinksWithAggregatedUnsubscribes($clickedLinks) : []; return $this->successResponse( $this->statsResponseBuilder->build( $newsletter, $statistics, $clickedLinksWithAggregatedUnsubscribes, $this->newsletterUrl ) ); } public function listing($data = []) { $newsletter = isset($data['params']['id']) ? $this->newslettersRepository->findOneById((int)$data['params']['id']) : null; if (!$newsletter instanceof NewsletterEntity) { return $this->errorResponse([ APIError::NOT_FOUND => __('This newsletter does not exist.', 'mailpoet-premium'), ]); } if (!$this->isNewsletterSent($newsletter)) { return $this->errorResponse( [ APIError::NOT_FOUND => __('This newsletter is not sent yet.', 'mailpoet-premium'), ] ); } $listingData = $this->listings->get($data); foreach ($listingData['items'] as &$item) { $item['subscriber_url'] = WPFunctions::get()->adminUrl( 'admin.php?page=mailpoet-subscribers#/edit/' . $item['subscriber_id'] ); } unset($item); return $this->successResponse($listingData['items'], [ 'count' => (int)$listingData['count'], 'filters' => $listingData['filters'], 'groups' => $listingData['groups'], ]); } public function isNewsletterSent(NewsletterEntity $newsletter): bool { // for statistics purposes, newsletter (except for welcome notifications) is sent // when it has a queue record and it's status is not scheduled $queue = $newsletter->getLatestQueue(); if (!$queue) return false; $task = $queue->getTask(); if (!$task) return false; if ( ($newsletter->getType() === NewsletterEntity::TYPE_WELCOME) || ($newsletter->getType() === NewsletterEntity::TYPE_AUTOMATIC) ) return true; return $task->getStatus() !== ScheduledTaskEntity::STATUS_SCHEDULED; } /** * @param array $data * * @return \MailPoet\API\JSON\SuccessResponse */ public function getProducts(array $data = []) { $id = (isset($data['newsletter_id']) ? (int)$data['newsletter_id'] : false); return $this->successResponse($this->purchasedProducts->getStats($id)); } /** * @param array $clickedLinks * @return array */ private function getClickedLinksWithAggregatedUnsubscribes(array $clickedLinks): array { $associativeClickedLinks = array_reduce($clickedLinks, function ($allCounts, $item) { if (in_array($item['url'], NewsletterLinkEntity::UNSUBSCRIBE_LINK_SHORTCODES)) { $cnt = $item['cnt'] + (isset($allCounts[NewsletterLinkEntity::UNSUBSCRIBE_LINK_SHORT_CODE]) ? $allCounts[NewsletterLinkEntity::UNSUBSCRIBE_LINK_SHORT_CODE]['cnt'] : 0); $allCounts[NewsletterLinkEntity::UNSUBSCRIBE_LINK_SHORT_CODE] = [ 'cnt' => $cnt, 'url' => NewsletterLinkEntity::UNSUBSCRIBE_LINK_SHORT_CODE, ]; } else { $allCounts[] = $item; } return $allCounts; }, []); usort($associativeClickedLinks, function ($a, $b) { return $a['cnt'] > $b['cnt'] ? -1 : 1; }); return array_values($associativeClickedLinks); } }