oont-contents/plugins/mailpoet-premium/lib/Subscriber/Stats/SubscriberNewsletterStatsRepository.php
2025-02-08 15:10:23 +01:00

120 lines
3.7 KiB
PHP

<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Premium\Subscriber\Stats;
if (!defined('ABSPATH')) exit;
use MailPoet\Entities\NewsletterEntity;
use MailPoet\Entities\StatisticsClickEntity;
use MailPoet\Entities\StatisticsOpenEntity;
use MailPoet\Listing\ListingDefinition;
use MailPoet\Listing\ListingRepository;
use MailPoetVendor\Doctrine\ORM\QueryBuilder;
class SubscriberNewsletterStatsRepository extends ListingRepository {
/**
* @return SubscriberNewsletterStats[]
*/
public function getData(ListingDefinition $definition): array {
$opens = parent::getData($definition);
$subscriberId = $definition->getParameters()['id'] ?? null;
$newsletterIds = [];
foreach ($opens as $open) {
$newsletter = $open->getNewsletter();
if (!$newsletter instanceof NewsletterEntity) {
continue;
}
$newsletterIds[] = $newsletter->getId();
}
$queryBuilder = clone $this->queryBuilder;
/** @var StatisticsClickEntity[] $clicks */
$clicks = $queryBuilder
->select('c, l, wp')
->from(StatisticsClickEntity::class, 'c')
->join('c.link', 'l')
->leftJoin('c.wooCommercePurchases', 'wp')
->where('c.subscriber = :subscriber')
->andWhere('c.newsletter IN (:newsletters)')
->setParameter('subscriber', $subscriberId)
->setParameter('newsletters', $newsletterIds)
->orderBy('c.createdAt', 'asc')
->getQuery()
->getResult();
$clicksMap = [];
foreach ($clicks as $click) {
$newsletter = $click->getNewsletter();
if (!$newsletter instanceof NewsletterEntity) {
continue;
}
if (!isset($clicksMap[$newsletter->getId()])) {
$clicksMap[$newsletter->getId()] = [];
}
$clicksMap[$newsletter->getId()][] = $click;
}
$result = [];
foreach ($opens as $open) {
$newsletter = $open->getNewsletter();
if (!$newsletter instanceof NewsletterEntity) {
continue;
}
$result[] = new SubscriberNewsletterStats($newsletter, $open, $clicksMap[$newsletter->getId()] ?? []);
}
return $result;
}
protected function applySelectClause(QueryBuilder $queryBuilder) {
$queryBuilder->select('o, n');
}
protected function applyFromClause(QueryBuilder $queryBuilder) {
$queryBuilder->from(StatisticsOpenEntity::class, 'o')
->join('o.newsletter', 'n');
}
protected function applyGroup(QueryBuilder $queryBuilder, string $group) {
// No groups for this listing
}
/**
* Apply search term to the query
* @param QueryBuilder $queryBuilder
* @param string $search
* @param array<mixed> $parameters
* @return void
*/
protected function applySearch(QueryBuilder $queryBuilder, string $search, array $parameters = []) {
$search = str_replace(['\\', '%', '_'], ['\\\\', '\\%', '\\_'], $search); // escape for 'LIKE'
$queryBuilder
->andWhere('n.subject LIKE :search')
->setParameter('search', "%$search%");
}
/**
* @param QueryBuilder $queryBuilder
* @param array<int|string> $filters
*/
protected function applyFilters(QueryBuilder $queryBuilder, array $filters) {
// No filters for this listing
}
/**
* @param QueryBuilder $queryBuilder
* @param array<int|string> $parameters
*/
protected function applyParameters(QueryBuilder $queryBuilder, array $parameters) {
$subscriberId = $parameters['id'] ?? null;
if ($subscriberId) {
$queryBuilder
->andWhere('o.subscriber = :subscriber')
->setParameter('subscriber', $subscriberId);
}
}
protected function applySorting(QueryBuilder $queryBuilder, string $sortBy, string $sortOrder) {
$queryBuilder->addOrderBy('n.sentAt', 'desc');
}
}