Use transient cache for count of subscribers in lists
[MAILPOET-3646]
This commit is contained in:
@ -1,7 +1,8 @@
|
|||||||
<?php
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
namespace MailPoet\Segments;
|
namespace MailPoet\Segments;
|
||||||
|
|
||||||
|
use MailPoet\Cache\TransientCache;
|
||||||
use MailPoet\Entities\DynamicSegmentFilterData;
|
use MailPoet\Entities\DynamicSegmentFilterData;
|
||||||
use MailPoet\Entities\DynamicSegmentFilterEntity;
|
use MailPoet\Entities\DynamicSegmentFilterEntity;
|
||||||
use MailPoet\Entities\SegmentEntity;
|
use MailPoet\Entities\SegmentEntity;
|
||||||
@ -24,12 +25,17 @@ class SegmentSubscribersRepository {
|
|||||||
/** @var FilterHandler */
|
/** @var FilterHandler */
|
||||||
private $filterHandler;
|
private $filterHandler;
|
||||||
|
|
||||||
|
/** @var TransientCache */
|
||||||
|
private $transientCache;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
EntityManager $entityManager,
|
EntityManager $entityManager,
|
||||||
FilterHandler $filterHandler
|
FilterHandler $filterHandler,
|
||||||
|
TransientCache $transientCache
|
||||||
) {
|
) {
|
||||||
$this->entityManager = $entityManager;
|
$this->entityManager = $entityManager;
|
||||||
$this->filterHandler = $filterHandler;
|
$this->filterHandler = $filterHandler;
|
||||||
|
$this->transientCache = $transientCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function findSubscribersIdsInSegment(int $segmentId, array $candidateIds = null): array {
|
public function findSubscribersIdsInSegment(int $segmentId, array $candidateIds = null): array {
|
||||||
@ -42,16 +48,8 @@ class SegmentSubscribersRepository {
|
|||||||
|
|
||||||
public function getSubscribersCount(int $segmentId, string $status = null): int {
|
public function getSubscribersCount(int $segmentId, string $status = null): int {
|
||||||
$segment = $this->getSegment($segmentId);
|
$segment = $this->getSegment($segmentId);
|
||||||
$queryBuilder = $this->createCountQueryBuilder();
|
$result = $this->getSubscribersStatisticsCount($segment);
|
||||||
|
return (int)$result[$status ?: 'all'];
|
||||||
if ($segment->isStatic()) {
|
|
||||||
$queryBuilder = $this->filterSubscribersInStaticSegment($queryBuilder, $segment, $status);
|
|
||||||
} else {
|
|
||||||
$queryBuilder = $this->filterSubscribersInDynamicSegment($queryBuilder, $segment, $status);
|
|
||||||
}
|
|
||||||
$statement = $this->executeQuery($queryBuilder);
|
|
||||||
$result = $statement->fetchColumn();
|
|
||||||
return (int)$result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubscribersCountBySegmentIds(array $segmentIds, string $status = null): int {
|
public function getSubscribersCountBySegmentIds(array $segmentIds, string $status = null): int {
|
||||||
@ -101,11 +99,11 @@ class SegmentSubscribersRepository {
|
|||||||
foreach ($filters as $filter) {
|
foreach ($filters as $filter) {
|
||||||
$segment->addDynamicFilter(new DynamicSegmentFilterEntity($segment, $filter));
|
$segment->addDynamicFilter(new DynamicSegmentFilterEntity($segment, $filter));
|
||||||
}
|
}
|
||||||
$queryBuilder = $this->createCountQueryBuilder();
|
$queryBuilder = $this->createDynamicStatisticsQueryBuilder();
|
||||||
$queryBuilder = $this->filterSubscribersInDynamicSegment($queryBuilder, $segment, null);
|
$queryBuilder = $this->filterSubscribersInDynamicSegment($queryBuilder, $segment, null);
|
||||||
$statement = $this->executeQuery($queryBuilder);
|
$statement = $this->executeQuery($queryBuilder);
|
||||||
$result = $statement->fetchColumn();
|
$result = $statement->fetch();
|
||||||
return (int)$result;
|
return (int)$result['all'];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createCountQueryBuilder(): QueryBuilder {
|
private function createCountQueryBuilder(): QueryBuilder {
|
||||||
@ -117,18 +115,140 @@ class SegmentSubscribersRepository {
|
|||||||
->from($subscribersTable);
|
->from($subscribersTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubscribersWithoutSegmentCount(): int {
|
private function createDynamicStatisticsQueryBuilder(): QueryBuilder {
|
||||||
$queryBuilder = $this->getSubscribersWithoutSegmentCountQuery();
|
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
|
||||||
return (int)$queryBuilder->getQuery()->getSingleScalarResult();
|
return $this->entityManager
|
||||||
|
->getConnection()
|
||||||
|
->createQueryBuilder()
|
||||||
|
->from($subscribersTable)
|
||||||
|
->andWhere("$subscribersTable.deleted_at IS NULL")
|
||||||
|
->addSelect("COUNT(DISTINCT $subscribersTable.id) as `all`")
|
||||||
|
->addSelect("SUM(
|
||||||
|
CASE WHEN $subscribersTable.status = :status_subscribed
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_subscribed")
|
||||||
|
->addSelect("SUM(
|
||||||
|
CASE WHEN $subscribersTable.status = :status_unsubscribed
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_unsubscribed")
|
||||||
|
->addSelect("SUM(
|
||||||
|
CASE WHEN $subscribersTable.status = :status_inactive
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_inactive")
|
||||||
|
->addSelect("SUM(
|
||||||
|
CASE WHEN $subscribersTable.status = :status_unconfirmed
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_unconfirmed")
|
||||||
|
->addSelect("SUM(
|
||||||
|
CASE WHEN $subscribersTable.status = :status_bounced
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_bounced")
|
||||||
|
->setParameter('status_subscribed', SubscriberEntity::STATUS_SUBSCRIBED)
|
||||||
|
->setParameter('status_unsubscribed', SubscriberEntity::STATUS_UNSUBSCRIBED)
|
||||||
|
->setParameter('status_inactive', SubscriberEntity::STATUS_INACTIVE)
|
||||||
|
->setParameter('status_unconfirmed', SubscriberEntity::STATUS_UNCONFIRMED)
|
||||||
|
->setParameter('status_bounced', SubscriberEntity::STATUS_BOUNCED);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubscribersWithoutSegmentCountQuery(): ORMQueryBuilder {
|
private function createStaticStatisticsQueryBuilder(SegmentEntity $segment): QueryBuilder {
|
||||||
|
$subscriberSegmentTable = $this->entityManager->getClassMetadata(SubscriberSegmentEntity::class)->getTableName();
|
||||||
|
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
|
||||||
|
$queryBuilder = $this->entityManager
|
||||||
|
->getConnection()
|
||||||
|
->createQueryBuilder()
|
||||||
|
->from($subscriberSegmentTable, 'subscriber_segment')
|
||||||
|
->where('subscriber_segment.segment_id = :segment_id')
|
||||||
|
->setParameter('segment_id', $segment->getId())
|
||||||
|
->andWhere('subscribers.deleted_at is null')
|
||||||
|
->join('subscriber_segment', $subscribersTable, 'subscribers', 'subscribers.id = subscriber_segment.subscriber_id')
|
||||||
|
->addSelect("COUNT(DISTINCT subscribers.id) as `all`")
|
||||||
|
->addSelect('SUM(
|
||||||
|
CASE WHEN subscribers.status = :status_subscribed AND subscriber_segment.status = :status_subscribed
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_subscribed')
|
||||||
|
->addSelect('SUM(
|
||||||
|
CASE WHEN subscribers.status = :status_unsubscribed OR subscriber_segment.status = :status_unsubscribed
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_unsubscribed')
|
||||||
|
->addSelect('SUM(
|
||||||
|
CASE WHEN subscribers.status = :status_inactive AND subscriber_segment.status != :status_unsubscribed
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_inactive')
|
||||||
|
->addSelect('SUM(
|
||||||
|
CASE WHEN subscribers.status = :status_unconfirmed AND subscriber_segment.status != :status_unsubscribed
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_unconfirmed')
|
||||||
|
->addSelect('SUM(
|
||||||
|
CASE WHEN subscribers.status = :status_bounced AND subscriber_segment.status != :status_unsubscribed
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_bounced')
|
||||||
|
->setParameter('status_subscribed', SubscriberEntity::STATUS_SUBSCRIBED)
|
||||||
|
->setParameter('status_unsubscribed', SubscriberEntity::STATUS_UNSUBSCRIBED)
|
||||||
|
->setParameter('status_inactive', SubscriberEntity::STATUS_INACTIVE)
|
||||||
|
->setParameter('status_unconfirmed', SubscriberEntity::STATUS_UNCONFIRMED)
|
||||||
|
->setParameter('status_bounced', SubscriberEntity::STATUS_BOUNCED);
|
||||||
|
return $queryBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSubscribersWithoutSegmentCount(): int {
|
||||||
$queryBuilder = $this->entityManager->createQueryBuilder();
|
$queryBuilder = $this->entityManager->createQueryBuilder();
|
||||||
$queryBuilder
|
$queryBuilder
|
||||||
->select('COUNT(DISTINCT s) AS subscribersCount')
|
->select('COUNT(DISTINCT s) AS subscribersCount')
|
||||||
->from(SubscriberEntity::class, 's');
|
->from(SubscriberEntity::class, 's');
|
||||||
$this->addConstraintsForSubscribersWithoutSegment($queryBuilder);
|
$this->addConstraintsForSubscribersWithoutSegment($queryBuilder);
|
||||||
return $queryBuilder;
|
return (int)$queryBuilder->getQuery()->getSingleScalarResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSubscribersWithoutSegmentStatisticsCount(): array {
|
||||||
|
$id = 0;
|
||||||
|
$result = $this->transientCache->getItem(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY, $id);
|
||||||
|
if (!$result) {
|
||||||
|
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
|
||||||
|
$queryBuilder = $this->entityManager
|
||||||
|
->getConnection()
|
||||||
|
->createQueryBuilder();
|
||||||
|
$queryBuilder
|
||||||
|
->addSelect("SUM(
|
||||||
|
CASE WHEN s.deleted_at IS NULL
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as `all`")
|
||||||
|
->addSelect("SUM(
|
||||||
|
CASE WHEN s.deleted_at IS NOT NULL
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as trash")
|
||||||
|
->addSelect("SUM(
|
||||||
|
CASE WHEN s.status = :status_subscribed AND s.deleted_at IS NULL
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_subscribed")
|
||||||
|
->addSelect("SUM(
|
||||||
|
CASE WHEN s.status = :status_unsubscribed AND s.deleted_at IS NULL
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_unsubscribed")
|
||||||
|
->addSelect("SUM(
|
||||||
|
CASE WHEN s.status = :status_inactive AND s.deleted_at IS NULL
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_inactive")
|
||||||
|
->addSelect("SUM(
|
||||||
|
CASE WHEN s.status = :status_unconfirmed AND s.deleted_at IS NULL
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_unconfirmed")
|
||||||
|
->addSelect("SUM(
|
||||||
|
CASE WHEN s.status = :status_bounced AND s.deleted_at IS NULL
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_bounced")
|
||||||
|
->from($subscribersTable, 's')
|
||||||
|
->setParameter('status_subscribed', SubscriberEntity::STATUS_SUBSCRIBED)
|
||||||
|
->setParameter('status_unsubscribed', SubscriberEntity::STATUS_UNSUBSCRIBED)
|
||||||
|
->setParameter('status_inactive', SubscriberEntity::STATUS_INACTIVE)
|
||||||
|
->setParameter('status_unconfirmed', SubscriberEntity::STATUS_UNCONFIRMED)
|
||||||
|
->setParameter('status_bounced', SubscriberEntity::STATUS_BOUNCED);
|
||||||
|
|
||||||
|
$this->addConstraintsForSubscribersWithoutSegmentToDBAL($queryBuilder);
|
||||||
|
$statement = $this->executeQuery($queryBuilder);
|
||||||
|
$result = $statement->fetch();
|
||||||
|
$this->transientCache->setItem(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY, $result, $id);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addConstraintsForSubscribersWithoutSegment(ORMQueryBuilder $queryBuilder): void {
|
public function addConstraintsForSubscribersWithoutSegment(ORMQueryBuilder $queryBuilder): void {
|
||||||
@ -149,6 +269,24 @@ class SegmentSubscribersRepository {
|
|||||||
->setParameter('statusSubscribed', SubscriberEntity::STATUS_SUBSCRIBED);
|
->setParameter('statusSubscribed', SubscriberEntity::STATUS_SUBSCRIBED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addConstraintsForSubscribersWithoutSegmentToDBAL(QueryBuilder $queryBuilder): void {
|
||||||
|
$deletedSegmentsQueryBuilder = $this->entityManager->createQueryBuilder();
|
||||||
|
$subscribersSegmentTable = $this->entityManager->getClassMetadata(SubscriberSegmentEntity::class)->getTableName();
|
||||||
|
$deletedSegmentsQueryBuilder->select('sg.id')
|
||||||
|
->from(SegmentEntity::class, 'sg')
|
||||||
|
->where($deletedSegmentsQueryBuilder->expr()->isNotNull('sg.deletedAt'));
|
||||||
|
|
||||||
|
$queryBuilder
|
||||||
|
->leftJoin('s', $subscribersSegmentTable, 'ssg',
|
||||||
|
(string)$queryBuilder->expr()->andX(
|
||||||
|
$queryBuilder->expr()->eq('ssg.subscriber_id', 's.id'),
|
||||||
|
$queryBuilder->expr()->eq('ssg.status', ':statusSubscribed'),
|
||||||
|
$queryBuilder->expr()->notIn('ssg.segment_id', $deletedSegmentsQueryBuilder->getQuery()->getSQL())
|
||||||
|
))
|
||||||
|
->andWhere('ssg.id IS NULL')
|
||||||
|
->setParameter('statusSubscribed', SubscriberEntity::STATUS_SUBSCRIBED);
|
||||||
|
}
|
||||||
|
|
||||||
private function loadSubscriberIdsInSegment(int $segmentId, array $candidateIds = null): array {
|
private function loadSubscriberIdsInSegment(int $segmentId, array $candidateIds = null): array {
|
||||||
$segment = $this->getSegment($segmentId);
|
$segment = $this->getSegment($segmentId);
|
||||||
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
|
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
|
||||||
@ -242,45 +380,23 @@ class SegmentSubscribersRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getSubscribersStatisticsCount(SegmentEntity $segment) {
|
public function getSubscribersStatisticsCount(SegmentEntity $segment) {
|
||||||
$subscriberSegmentTable = $this->entityManager->getClassMetadata(SubscriberSegmentEntity::class)->getTableName();
|
$result = $this->transientCache->getItem(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY, (int)$segment->getId());
|
||||||
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
|
if (!$result) {
|
||||||
$queryBuilder = $this->entityManager
|
if ($segment->isStatic()) {
|
||||||
->getConnection()
|
$queryBuilder = $this->createStaticStatisticsQueryBuilder($segment);
|
||||||
->createQueryBuilder()
|
} else {
|
||||||
->from($subscriberSegmentTable, 'subscriber_segment')
|
$queryBuilder = $this->createDynamicStatisticsQueryBuilder();
|
||||||
->where('subscriber_segment.segment_id = :segment_id')
|
$this->filterSubscribersInDynamicSegment($queryBuilder, $segment);
|
||||||
->setParameter('segment_id', $segment->getId())
|
}
|
||||||
->andWhere('subscribers.deleted_at is null')
|
|
||||||
->join('subscriber_segment', $subscribersTable, 'subscribers', 'subscribers.id = subscriber_segment.subscriber_id')
|
|
||||||
->addSelect('SUM(
|
|
||||||
CASE WHEN subscribers.status = :status_subscribed AND subscriber_segment.status = :status_subscribed
|
|
||||||
THEN 1 ELSE 0 END
|
|
||||||
) as :status_subscribed')
|
|
||||||
->addSelect('SUM(
|
|
||||||
CASE WHEN subscribers.status = :status_unsubscribed OR subscriber_segment.status = :status_unsubscribed
|
|
||||||
THEN 1 ELSE 0 END
|
|
||||||
) as :status_unsubscribed')
|
|
||||||
->addSelect('SUM(
|
|
||||||
CASE WHEN subscribers.status = :status_inactive AND subscriber_segment.status != :status_unsubscribed
|
|
||||||
THEN 1 ELSE 0 END
|
|
||||||
) as :status_inactive')
|
|
||||||
->addSelect('SUM(
|
|
||||||
CASE WHEN subscribers.status = :status_unconfirmed AND subscriber_segment.status != :status_unsubscribed
|
|
||||||
THEN 1 ELSE 0 END
|
|
||||||
) as :status_unconfirmed')
|
|
||||||
->addSelect('SUM(
|
|
||||||
CASE WHEN subscribers.status = :status_bounced AND subscriber_segment.status != :status_unsubscribed
|
|
||||||
THEN 1 ELSE 0 END
|
|
||||||
) as :status_bounced')
|
|
||||||
|
|
||||||
->setParameter('status_subscribed', SubscriberEntity::STATUS_SUBSCRIBED)
|
$statement = $this->executeQuery($queryBuilder);
|
||||||
->setParameter('status_unsubscribed', SubscriberEntity::STATUS_UNSUBSCRIBED)
|
$result = $statement->fetch();
|
||||||
->setParameter('status_inactive', SubscriberEntity::STATUS_INACTIVE)
|
$this->transientCache->setItem(
|
||||||
->setParameter('status_unconfirmed', SubscriberEntity::STATUS_UNCONFIRMED)
|
TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY,
|
||||||
->setParameter('status_bounced', SubscriberEntity::STATUS_BOUNCED);
|
$result,
|
||||||
|
(int)$segment->getId()
|
||||||
$statement = $this->executeQuery($queryBuilder);
|
);
|
||||||
$result = $statement->fetch();
|
}
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,11 +51,12 @@ class SegmentsSimpleListRepository {
|
|||||||
* @return array<array{id: string, name: string, type: string, subscribers: int}>
|
* @return array<array{id: string, name: string, type: string, subscribers: int}>
|
||||||
*/
|
*/
|
||||||
public function addVirtualSubscribersWithoutListSegment(array $segments): array {
|
public function addVirtualSubscribersWithoutListSegment(array $segments): array {
|
||||||
|
$withoutSegmentStats = $this->segmentsSubscriberRepository->getSubscribersWithoutSegmentStatisticsCount();
|
||||||
$segments[] = [
|
$segments[] = [
|
||||||
'id' => '0',
|
'id' => '0',
|
||||||
'type' => SegmentEntity::TYPE_WITHOUT_LIST,
|
'type' => SegmentEntity::TYPE_WITHOUT_LIST,
|
||||||
'name' => __('Subscribers without a list', 'mailpoet'),
|
'name' => __('Subscribers without a list', 'mailpoet'),
|
||||||
'subscribers' => $this->segmentsSubscriberRepository->getSubscribersWithoutSegmentCount(),
|
'subscribers' => $withoutSegmentStats['all'],
|
||||||
];
|
];
|
||||||
return $segments;
|
return $segments;
|
||||||
}
|
}
|
||||||
|
@ -223,29 +223,24 @@ class SubscriberListingRepository extends ListingRepository {
|
|||||||
public function getFilters(ListingDefinition $definition): array {
|
public function getFilters(ListingDefinition $definition): array {
|
||||||
$group = $definition->getGroup();
|
$group = $definition->getGroup();
|
||||||
|
|
||||||
$queryBuilder = clone $this->queryBuilder;
|
$subscribersWithoutSegmentStats = $this->segmentSubscribersRepository->getSubscribersWithoutSegmentStatisticsCount();
|
||||||
$this->applyFromClause($queryBuilder);
|
$key = $group ?: 'all';
|
||||||
$subscribersWithoutSegmentQuery = $this->segmentSubscribersRepository->getSubscribersWithoutSegmentCountQuery();
|
$subscribersWithoutSegmentCount = $subscribersWithoutSegmentStats[$key];
|
||||||
|
|
||||||
if ($group) {
|
|
||||||
$this->applyGroup($queryBuilder, $group);
|
|
||||||
$this->applyGroup($subscribersWithoutSegmentQuery, $group);
|
|
||||||
}
|
|
||||||
|
|
||||||
$subscribersWithoutSegment = $subscribersWithoutSegmentQuery->getQuery()->getSingleScalarResult();
|
|
||||||
$subscribersWithoutSegmentLabel = sprintf(
|
$subscribersWithoutSegmentLabel = sprintf(
|
||||||
WPFunctions::get()->__('Subscribers without a list (~%s)', 'mailpoet'),
|
WPFunctions::get()->__('Subscribers without a list (~%s)', 'mailpoet'),
|
||||||
number_format((float)$subscribersWithoutSegment)
|
number_format((float)$subscribersWithoutSegmentCount)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$queryBuilder = clone $this->queryBuilder;
|
||||||
$queryBuilder
|
$queryBuilder
|
||||||
->select('sg.id, sg.name, COUNT(s) AS subscribersCount')
|
->select('s')
|
||||||
->leftJoin('s.subscriberSegments', 'ssg')
|
->from(SegmentEntity::class, 's');
|
||||||
->join('ssg.segment', 'sg')
|
if ($group === 'trash') {
|
||||||
->groupBy('sg.id')
|
$queryBuilder->andWhere('s.deletedAt IS NOT NULL');
|
||||||
->andWhere('sg.deletedAt IS NULL')
|
} else {
|
||||||
->andWhere('s.deletedAt IS NULL')
|
$queryBuilder->andWhere('s.deletedAt IS NULL');
|
||||||
->having('subscribersCount > 0');
|
}
|
||||||
|
|
||||||
// format segment list
|
// format segment list
|
||||||
$allSubscribersList = [
|
$allSubscribersList = [
|
||||||
@ -259,32 +254,19 @@ class SubscriberListingRepository extends ListingRepository {
|
|||||||
];
|
];
|
||||||
|
|
||||||
$segmentList = [];
|
$segmentList = [];
|
||||||
foreach ($queryBuilder->getQuery()->getResult() as $item) {
|
|
||||||
$segmentList[] = [
|
|
||||||
'label' => sprintf('%s (~%s)', $item['name'], number_format((float)$item['subscribersCount'])),
|
|
||||||
'value' => $item['id'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$queryBuilder = clone $this->queryBuilder;
|
|
||||||
// Load dynamic segments with some subscribers
|
|
||||||
$queryBuilder
|
|
||||||
->select('s')
|
|
||||||
->from(SegmentEntity::class, 's')
|
|
||||||
->andWhere('s.type = :dynamicType')
|
|
||||||
->andWhere('s.deletedAt IS NULL')
|
|
||||||
->setParameter('dynamicType', SegmentEntity::TYPE_DYNAMIC);
|
|
||||||
|
|
||||||
foreach ($queryBuilder->getQuery()->getResult() as $segment) {
|
foreach ($queryBuilder->getQuery()->getResult() as $segment) {
|
||||||
$count = $this->segmentSubscribersRepository->getSubscribersCount($segment->getId());
|
$key = $group ?: 'all';
|
||||||
if (!$count) {
|
$count = $this->segmentSubscribersRepository->getSubscribersStatisticsCount($segment);
|
||||||
|
if (!$count[$key]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$segmentList[] = [
|
$segmentList[] = [
|
||||||
'label' => sprintf('%s (~%s)', $segment->getName(), number_format((float)$count)),
|
'label' => sprintf('%s (~%s)', $segment->getName(), number_format((float)$count[$key])),
|
||||||
'value' => $segment->getId(),
|
'value' => $segment->getId(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
usort($segmentList, function($a, $b) {
|
usort($segmentList, function($a, $b) {
|
||||||
return strcasecmp($a['label'], $b['label']);
|
return strcasecmp($a['label'], $b['label']);
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user