<?php declare(strict_types = 1);
namespace MailPoet\Subscribers;
if (!defined('ABSPATH')) exit;
use MailPoet\Cache\TransientCache;
use MailPoet\Entities\SegmentEntity;
use MailPoet\InvalidStateException;
use MailPoet\Segments\SegmentsRepository;
use MailPoet\Segments\SegmentSubscribersRepository;
use MailPoet\Tags\TagRepository;
class SubscribersCountsController {
/** @var SegmentsRepository */
private $segmentsRepository;
/** @var SegmentSubscribersRepository */
private $segmentSubscribersRepository;
/** @var TagRepository */
private $tagRepository;
/** @var TransientCache */
private $transientCache;
public function __construct(
SegmentsRepository $segmentsRepository,
SegmentSubscribersRepository $segmentSubscribersRepository,
TagRepository $subscriberTagRepository,
TransientCache $transientCache
) {
$this->segmentSubscribersRepository = $segmentSubscribersRepository;
$this->transientCache = $transientCache;
$this->segmentsRepository = $segmentsRepository;
$this->tagRepository = $subscriberTagRepository;
}
public function getSubscribersWithoutSegmentStatisticsCount(): array {
$result = $this->transientCache->getItem(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY, 0)['item'] ?? null;
if (!$result) {
$result = $this->recalculateSubscribersWithoutSegmentStatisticsCache();
}
return $result;
}
public function getSegmentStatisticsCount(SegmentEntity $segment): array {
$result = $this->transientCache->getItem(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY, (int)$segment->getId())['item'] ?? null;
if (!$result) {
$result = $this->recalculateSegmentStatisticsCache($segment);
}
return $result;
}
public function getSegmentGlobalStatusStatisticsCount(SegmentEntity $segment): array {
$result = $this->transientCache->getItem(TransientCache::SUBSCRIBERS_GLOBAL_STATUS_STATISTICS_COUNT_KEY, (int)$segment->getId())['item'] ?? null;
if (!$result) {
$result = $this->recalculateSegmentGlobalStatusStatisticsCache($segment);
}
return $result;
}
public function getSegmentStatisticsCountById(int $segmentId): array {
$result = $this->transientCache->getItem(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY, $segmentId)['item'] ?? null;
if (!$result) {
$segment = $this->segmentsRepository->findOneById($segmentId);
if (!$segment) {
throw new InvalidStateException();
}
$result = $this->recalculateSegmentStatisticsCache($segment);
}
return $result;
}
public function recalculateSegmentGlobalStatusStatisticsCache(SegmentEntity $segment): array {
$result = $this->segmentSubscribersRepository->getSubscribersGlobalStatusStatisticsCount($segment);
$this->transientCache->setItem(
TransientCache::SUBSCRIBERS_GLOBAL_STATUS_STATISTICS_COUNT_KEY,
$result,
(int)$segment->getId()
);
return $result;
}
public function recalculateSegmentStatisticsCache(SegmentEntity $segment): array {
$result = $this->segmentSubscribersRepository->getSubscribersStatisticsCount($segment);
$this->transientCache->setItem(
TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY,
$result,
(int)$segment->getId()
);
return $result;
}
public function recalculateSubscribersWithoutSegmentStatisticsCache(): array {
$result = $this->segmentSubscribersRepository->getSubscribersWithoutSegmentStatisticsCount();
$this->transientCache->setItem(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY, $result, 0);
return $result;
}
public function removeRedundancyFromStatisticsCache() {
$segments = $this->segmentsRepository->findAll();
$segmentIds = array_map(function (SegmentEntity $segment): int {
return (int)$segment->getId();
}, $segments);
foreach ($this->transientCache->getItems(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY) as $id => $item) {
if (!in_array($id, $segmentIds)) {
$this->transientCache->invalidateItem(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY, $id);
}
}
foreach ($this->transientCache->getItems(TransientCache::SUBSCRIBERS_GLOBAL_STATUS_STATISTICS_COUNT_KEY) as $id => $item) {
if (!in_array($id, $segmentIds)) {
$this->transientCache->invalidateItem(TransientCache::SUBSCRIBERS_GLOBAL_STATUS_STATISTICS_COUNT_KEY, $id);
}
}
}
/**
* @return array<int, array{id: int, name: string, subscribersCount: int}>
*/
public function getTagsStatisticsCount(?string $status, bool $isDeleted): array {
return $this->tagRepository->getSubscriberStatisticsCount($status, $isDeleted);
}
}