Use new controller with subscribers counts
[MAILPOET-3646]
This commit is contained in:
@ -6,6 +6,7 @@ use MailPoet\Entities\SegmentEntity;
|
|||||||
use MailPoet\Entities\SubscriberEntity;
|
use MailPoet\Entities\SubscriberEntity;
|
||||||
use MailPoet\Segments\SegmentDependencyValidator;
|
use MailPoet\Segments\SegmentDependencyValidator;
|
||||||
use MailPoet\Segments\SegmentSubscribersRepository;
|
use MailPoet\Segments\SegmentSubscribersRepository;
|
||||||
|
use MailPoet\Subscribers\SubscribersCountsController;
|
||||||
use MailPoet\WP\Functions;
|
use MailPoet\WP\Functions;
|
||||||
|
|
||||||
class DynamicSegmentsResponseBuilder {
|
class DynamicSegmentsResponseBuilder {
|
||||||
@ -23,16 +24,21 @@ class DynamicSegmentsResponseBuilder {
|
|||||||
/** @var SegmentDependencyValidator */
|
/** @var SegmentDependencyValidator */
|
||||||
private $segmentDependencyValidator;
|
private $segmentDependencyValidator;
|
||||||
|
|
||||||
|
/** @var SubscribersCountsController */
|
||||||
|
private $subscribersCountsController;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
Functions $wp,
|
Functions $wp,
|
||||||
SegmentSubscribersRepository $segmentSubscriberRepository,
|
SegmentSubscribersRepository $segmentSubscriberRepository,
|
||||||
SegmentsResponseBuilder $segmentsResponseBuilder,
|
SegmentsResponseBuilder $segmentsResponseBuilder,
|
||||||
SegmentDependencyValidator $segmentDependencyValidator
|
SegmentDependencyValidator $segmentDependencyValidator,
|
||||||
|
SubscribersCountsController $subscribersCountsController
|
||||||
) {
|
) {
|
||||||
$this->segmentsResponseBuilder = $segmentsResponseBuilder;
|
$this->segmentsResponseBuilder = $segmentsResponseBuilder;
|
||||||
$this->segmentSubscriberRepository = $segmentSubscriberRepository;
|
$this->segmentSubscriberRepository = $segmentSubscriberRepository;
|
||||||
$this->wp = $wp;
|
$this->wp = $wp;
|
||||||
$this->segmentDependencyValidator = $segmentDependencyValidator;
|
$this->segmentDependencyValidator = $segmentDependencyValidator;
|
||||||
|
$this->subscribersCountsController = $subscribersCountsController;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function build(SegmentEntity $segmentEntity) {
|
public function build(SegmentEntity $segmentEntity) {
|
||||||
@ -80,8 +86,9 @@ class DynamicSegmentsResponseBuilder {
|
|||||||
'admin.php?page=mailpoet-subscribers#/filter[segment=' . $segment->getId() . ']'
|
'admin.php?page=mailpoet-subscribers#/filter[segment=' . $segment->getId() . ']'
|
||||||
);
|
);
|
||||||
|
|
||||||
$data['count_all'] = $this->segmentSubscriberRepository->getSubscribersCount((int)$segment->getId());
|
$segmentStatisticsCount = $this->subscribersCountsController->getSegmentStatisticsCount($segment);
|
||||||
$data['count_subscribed'] = $this->segmentSubscriberRepository->getSubscribersCount((int)$segment->getId(), SubscriberEntity::STATUS_SUBSCRIBED);
|
$data['count_all'] = $segmentStatisticsCount['all'];
|
||||||
|
$data['count_subscribed'] = $segmentStatisticsCount[SubscriberEntity::STATUS_SUBSCRIBED];
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
namespace MailPoet\API\JSON\ResponseBuilders;
|
namespace MailPoet\API\JSON\ResponseBuilders;
|
||||||
|
|
||||||
use MailPoet\Entities\SegmentEntity;
|
use MailPoet\Entities\SegmentEntity;
|
||||||
use MailPoet\Segments\SegmentSubscribersRepository;
|
use MailPoet\Subscribers\SubscribersCountsController;
|
||||||
use MailPoet\WP\Functions;
|
use MailPoet\WP\Functions;
|
||||||
|
|
||||||
class SegmentsResponseBuilder {
|
class SegmentsResponseBuilder {
|
||||||
@ -12,15 +12,15 @@ class SegmentsResponseBuilder {
|
|||||||
/** @var Functions */
|
/** @var Functions */
|
||||||
private $wp;
|
private $wp;
|
||||||
|
|
||||||
/** @var SegmentSubscribersRepository */
|
/** @var SubscribersCountsController */
|
||||||
private $segmentSubscriberRepository;
|
private $subscribersCountsController;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
Functions $wp,
|
Functions $wp,
|
||||||
SegmentSubscribersRepository $segmentSubscriberRepository
|
SubscribersCountsController $subscribersCountsController
|
||||||
) {
|
) {
|
||||||
$this->wp = $wp;
|
$this->wp = $wp;
|
||||||
$this->segmentSubscriberRepository = $segmentSubscriberRepository;
|
$this->subscribersCountsController = $subscribersCountsController;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function build(SegmentEntity $segment): array {
|
public function build(SegmentEntity $segment): array {
|
||||||
@ -48,7 +48,7 @@ class SegmentsResponseBuilder {
|
|||||||
private function buildListingItem(SegmentEntity $segment): array {
|
private function buildListingItem(SegmentEntity $segment): array {
|
||||||
$data = $this->build($segment);
|
$data = $this->build($segment);
|
||||||
|
|
||||||
$data['subscribers_count'] = $this->segmentSubscriberRepository->getSubscribersStatisticsCount($segment);
|
$data['subscribers_count'] = $this->subscribersCountsController->getSegmentStatisticsCount($segment);
|
||||||
$data['subscribers_url'] = $this->wp->adminUrl(
|
$data['subscribers_url'] = $this->wp->adminUrl(
|
||||||
'admin.php?page=mailpoet-subscribers#/filter[segment=' . $segment->getId() . ']'
|
'admin.php?page=mailpoet-subscribers#/filter[segment=' . $segment->getId() . ']'
|
||||||
);
|
);
|
||||||
|
@ -4,7 +4,6 @@ namespace MailPoet\API\JSON\v1;
|
|||||||
|
|
||||||
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
use MailPoet\API\JSON\Endpoint as APIEndpoint;
|
||||||
use MailPoet\API\JSON\Error as APIError;
|
use MailPoet\API\JSON\Error as APIError;
|
||||||
use MailPoet\Cache\TransientCache;
|
|
||||||
use MailPoet\Config\AccessControl;
|
use MailPoet\Config\AccessControl;
|
||||||
use MailPoet\Config\ServicesChecker;
|
use MailPoet\Config\ServicesChecker;
|
||||||
use MailPoet\Cron\Workers\InactiveSubscribers;
|
use MailPoet\Cron\Workers\InactiveSubscribers;
|
||||||
@ -15,11 +14,11 @@ use MailPoet\Form\FormMessageController;
|
|||||||
use MailPoet\Mailer\MailerLog;
|
use MailPoet\Mailer\MailerLog;
|
||||||
use MailPoet\Newsletter\Sending\ScheduledTasksRepository;
|
use MailPoet\Newsletter\Sending\ScheduledTasksRepository;
|
||||||
use MailPoet\Segments\SegmentsRepository;
|
use MailPoet\Segments\SegmentsRepository;
|
||||||
use MailPoet\Segments\SegmentSubscribersRepository;
|
|
||||||
use MailPoet\Services\AuthorizedEmailsController;
|
use MailPoet\Services\AuthorizedEmailsController;
|
||||||
use MailPoet\Services\Bridge;
|
use MailPoet\Services\Bridge;
|
||||||
use MailPoet\Settings\SettingsController;
|
use MailPoet\Settings\SettingsController;
|
||||||
use MailPoet\Statistics\StatisticsOpensRepository;
|
use MailPoet\Statistics\StatisticsOpensRepository;
|
||||||
|
use MailPoet\Subscribers\SubscribersCountsController;
|
||||||
use MailPoet\WooCommerce\TransactionalEmails;
|
use MailPoet\WooCommerce\TransactionalEmails;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
use MailPoetVendor\Carbon\Carbon;
|
use MailPoetVendor\Carbon\Carbon;
|
||||||
@ -57,14 +56,11 @@ class Settings extends APIEndpoint {
|
|||||||
/** @var FormMessageController */
|
/** @var FormMessageController */
|
||||||
private $messageController;
|
private $messageController;
|
||||||
|
|
||||||
/** @var TransientCache */
|
|
||||||
private $transientCache;
|
|
||||||
|
|
||||||
/** @var SegmentsRepository */
|
/** @var SegmentsRepository */
|
||||||
private $segmentsRepository;
|
private $segmentsRepository;
|
||||||
|
|
||||||
/** @var SegmentSubscribersRepository */
|
/** @var SubscribersCountsController */
|
||||||
private $segmentSubscribersRepository;
|
private $subscribersCountsController;
|
||||||
|
|
||||||
public $permissions = [
|
public $permissions = [
|
||||||
'global' => AccessControl::PERMISSION_MANAGE_SETTINGS,
|
'global' => AccessControl::PERMISSION_MANAGE_SETTINGS,
|
||||||
@ -81,9 +77,8 @@ class Settings extends APIEndpoint {
|
|||||||
ScheduledTasksRepository $scheduledTasksRepository,
|
ScheduledTasksRepository $scheduledTasksRepository,
|
||||||
FormMessageController $messageController,
|
FormMessageController $messageController,
|
||||||
ServicesChecker $servicesChecker,
|
ServicesChecker $servicesChecker,
|
||||||
TransientCache $transientCache,
|
|
||||||
SegmentsRepository $segmentsRepository,
|
SegmentsRepository $segmentsRepository,
|
||||||
SegmentSubscribersRepository $segmentSubscribersRepository
|
SubscribersCountsController $subscribersCountsController
|
||||||
) {
|
) {
|
||||||
$this->settings = $settings;
|
$this->settings = $settings;
|
||||||
$this->bridge = $bridge;
|
$this->bridge = $bridge;
|
||||||
@ -95,9 +90,8 @@ class Settings extends APIEndpoint {
|
|||||||
$this->statisticsOpensRepository = $statisticsOpensRepository;
|
$this->statisticsOpensRepository = $statisticsOpensRepository;
|
||||||
$this->scheduledTasksRepository = $scheduledTasksRepository;
|
$this->scheduledTasksRepository = $scheduledTasksRepository;
|
||||||
$this->messageController = $messageController;
|
$this->messageController = $messageController;
|
||||||
$this->transientCache = $transientCache;
|
|
||||||
$this->segmentsRepository = $segmentsRepository;
|
$this->segmentsRepository = $segmentsRepository;
|
||||||
$this->segmentSubscribersRepository = $segmentSubscribersRepository;
|
$this->subscribersCountsController = $subscribersCountsController;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get() {
|
public function get() {
|
||||||
@ -257,12 +251,14 @@ class Settings extends APIEndpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function recalculateSubscribersCountsCache() {
|
public function recalculateSubscribersCountsCache() {
|
||||||
$this->transientCache->invalidateItems(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY);
|
|
||||||
$segments = $this->segmentsRepository->findAll();
|
$segments = $this->segmentsRepository->findAll();
|
||||||
foreach ($segments as $segment) {
|
foreach ($segments as $segment) {
|
||||||
$this->segmentSubscribersRepository->getSubscribersStatisticsCount($segment);
|
$this->subscribersCountsController->recalculateSegmentStatisticsCache($segment);
|
||||||
|
if ($segment->isStatic()) {
|
||||||
|
$this->subscribersCountsController->recalculateSegmentGlobalStatusStatisticsCache($segment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$this->segmentSubscribersRepository->getSubscribersWithoutSegmentStatisticsCount();
|
$this->subscribersCountsController->recalculateSubscribersWithoutSegmentStatisticsCache();
|
||||||
return $this->successResponse();
|
return $this->successResponse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ use MailPoetVendor\Carbon\Carbon;
|
|||||||
|
|
||||||
class TransientCache {
|
class TransientCache {
|
||||||
public const SUBSCRIBERS_STATISTICS_COUNT_KEY = 'mailpoet_subscribers_statistics_count_cache';
|
public const SUBSCRIBERS_STATISTICS_COUNT_KEY = 'mailpoet_subscribers_statistics_count_cache';
|
||||||
|
public const SUBSCRIBERS_GLOBAL_STATUS_STATISTICS_COUNT_KEY = 'mailpoet_subscribers_statistics_count_global_status_cache';
|
||||||
|
|
||||||
/** @var WPFunctions */
|
/** @var WPFunctions */
|
||||||
private $wp;
|
private $wp;
|
||||||
|
@ -6,7 +6,7 @@ use MailPoet\Cache\TransientCache;
|
|||||||
use MailPoet\Entities\SegmentEntity;
|
use MailPoet\Entities\SegmentEntity;
|
||||||
use MailPoet\Models\ScheduledTask;
|
use MailPoet\Models\ScheduledTask;
|
||||||
use MailPoet\Segments\SegmentsRepository;
|
use MailPoet\Segments\SegmentsRepository;
|
||||||
use MailPoet\Segments\SegmentSubscribersRepository;
|
use MailPoet\Subscribers\SubscribersCountsController;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
use MailPoetVendor\Carbon\Carbon;
|
use MailPoetVendor\Carbon\Carbon;
|
||||||
|
|
||||||
@ -22,19 +22,19 @@ class SubscribersCountCacheRecalculation extends SimpleWorker {
|
|||||||
/** @var SegmentsRepository */
|
/** @var SegmentsRepository */
|
||||||
private $segmentsRepository;
|
private $segmentsRepository;
|
||||||
|
|
||||||
/** @var SegmentSubscribersRepository */
|
/** @var SubscribersCountsController */
|
||||||
private $segmentSubscribersRepository;
|
private $subscribersCountsController;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
TransientCache $transientCache,
|
TransientCache $transientCache,
|
||||||
SegmentsRepository $segmentsRepository,
|
SegmentsRepository $segmentsRepository,
|
||||||
SegmentSubscribersRepository $segmentSubscribersRepository,
|
SubscribersCountsController $subscribersCountsController,
|
||||||
WPFunctions $wp
|
WPFunctions $wp
|
||||||
) {
|
) {
|
||||||
parent::__construct($wp);
|
parent::__construct($wp);
|
||||||
$this->transientCache = $transientCache;
|
$this->transientCache = $transientCache;
|
||||||
$this->segmentsRepository = $segmentsRepository;
|
$this->segmentsRepository = $segmentsRepository;
|
||||||
$this->segmentSubscribersRepository = $segmentSubscribersRepository;
|
$this->subscribersCountsController = $subscribersCountsController;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function processTaskStrategy(ScheduledTask $task, $timer) {
|
public function processTaskStrategy(ScheduledTask $task, $timer) {
|
||||||
@ -54,11 +54,13 @@ class SubscribersCountCacheRecalculation extends SimpleWorker {
|
|||||||
$now = Carbon::now();
|
$now = Carbon::now();
|
||||||
$item = $this->transientCache->getItem(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY, $segmentId);
|
$item = $this->transientCache->getItem(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY, $segmentId);
|
||||||
if ($item === null || !isset($item['created_at']) || $now->diffInMinutes($item['created_at']) > self::EXPIRATION_IN_MINUTES) {
|
if ($item === null || !isset($item['created_at']) || $now->diffInMinutes($item['created_at']) > self::EXPIRATION_IN_MINUTES) {
|
||||||
$this->transientCache->invalidateItem(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY, $segmentId);
|
|
||||||
if ($segment) {
|
if ($segment) {
|
||||||
$this->segmentSubscribersRepository->getSubscribersStatisticsCount($segment);
|
$this->subscribersCountsController->recalculateSegmentStatisticsCache($segment);
|
||||||
|
if ($segment->isStatic()) {
|
||||||
|
$this->subscribersCountsController->recalculateSegmentGlobalStatusStatisticsCache($segment);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->segmentSubscribersRepository->getSubscribersWithoutSegmentStatisticsCount();
|
$this->subscribersCountsController->recalculateSubscribersWithoutSegmentStatisticsCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
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;
|
||||||
@ -25,17 +24,12 @@ 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 {
|
||||||
@ -159,7 +153,7 @@ class SegmentSubscribersRepository {
|
|||||||
private function createStaticStatisticsQueryBuilder(SegmentEntity $segment): QueryBuilder {
|
private function createStaticStatisticsQueryBuilder(SegmentEntity $segment): QueryBuilder {
|
||||||
$subscriberSegmentTable = $this->entityManager->getClassMetadata(SubscriberSegmentEntity::class)->getTableName();
|
$subscriberSegmentTable = $this->entityManager->getClassMetadata(SubscriberSegmentEntity::class)->getTableName();
|
||||||
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
|
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
|
||||||
$queryBuilder = $this->entityManager
|
return $this->entityManager
|
||||||
->getConnection()
|
->getConnection()
|
||||||
->createQueryBuilder()
|
->createQueryBuilder()
|
||||||
->from($subscriberSegmentTable, 'subscriber_segment')
|
->from($subscriberSegmentTable, 'subscriber_segment')
|
||||||
@ -199,7 +193,51 @@ class SegmentSubscribersRepository {
|
|||||||
->setParameter('status_inactive', SubscriberEntity::STATUS_INACTIVE)
|
->setParameter('status_inactive', SubscriberEntity::STATUS_INACTIVE)
|
||||||
->setParameter('status_unconfirmed', SubscriberEntity::STATUS_UNCONFIRMED)
|
->setParameter('status_unconfirmed', SubscriberEntity::STATUS_UNCONFIRMED)
|
||||||
->setParameter('status_bounced', SubscriberEntity::STATUS_BOUNCED);
|
->setParameter('status_bounced', SubscriberEntity::STATUS_BOUNCED);
|
||||||
return $queryBuilder;
|
}
|
||||||
|
|
||||||
|
private function createStaticGlobalStatusStatisticsQueryBuilder(SegmentEntity $segment): QueryBuilder {
|
||||||
|
$subscriberSegmentTable = $this->entityManager->getClassMetadata(SubscriberSegmentEntity::class)->getTableName();
|
||||||
|
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
|
||||||
|
return $this->entityManager
|
||||||
|
->getConnection()
|
||||||
|
->createQueryBuilder()
|
||||||
|
->from($subscriberSegmentTable, 'subscriber_segment')
|
||||||
|
->where('subscriber_segment.segment_id = :segment_id')
|
||||||
|
->setParameter('segment_id', $segment->getId())
|
||||||
|
->join('subscriber_segment', $subscribersTable, 'subscribers', 'subscribers.id = subscriber_segment.subscriber_id')
|
||||||
|
->addSelect("SUM(
|
||||||
|
CASE WHEN subscribers.deleted_at IS NULL
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as `all`")
|
||||||
|
->addSelect("SUM(
|
||||||
|
CASE WHEN subscribers.deleted_at IS NOT NULL
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as trash")
|
||||||
|
->addSelect('SUM(
|
||||||
|
CASE WHEN subscribers.status = :status_subscribed AND subscribers.deleted_at IS NULL
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_subscribed')
|
||||||
|
->addSelect('SUM(
|
||||||
|
CASE WHEN subscribers.status = :status_unsubscribed AND subscribers.deleted_at IS NULL
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_unsubscribed')
|
||||||
|
->addSelect('SUM(
|
||||||
|
CASE WHEN subscribers.status = :status_inactive AND subscribers.deleted_at IS NULL
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_inactive')
|
||||||
|
->addSelect('SUM(
|
||||||
|
CASE WHEN subscribers.status = :status_unconfirmed AND subscribers.deleted_at IS NULL
|
||||||
|
THEN 1 ELSE 0 END
|
||||||
|
) as :status_unconfirmed')
|
||||||
|
->addSelect('SUM(
|
||||||
|
CASE WHEN subscribers.status = :status_bounced AND subscribers.deleted_at IS NULL
|
||||||
|
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 getSubscribersWithoutSegmentCount(): int {
|
public function getSubscribersWithoutSegmentCount(): int {
|
||||||
@ -212,54 +250,50 @@ class SegmentSubscribersRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getSubscribersWithoutSegmentStatisticsCount(): array {
|
public function getSubscribersWithoutSegmentStatisticsCount(): array {
|
||||||
$id = 0;
|
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
|
||||||
$result = $this->transientCache->getItem(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY, $id);
|
$queryBuilder = $this->entityManager
|
||||||
if (!$result) {
|
->getConnection()
|
||||||
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
|
->createQueryBuilder();
|
||||||
$queryBuilder = $this->entityManager
|
$queryBuilder
|
||||||
->getConnection()
|
->addSelect("SUM(
|
||||||
->createQueryBuilder();
|
CASE WHEN s.deleted_at IS NULL
|
||||||
$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
|
THEN 1 ELSE 0 END
|
||||||
) as :status_unsubscribed")
|
) as `all`")
|
||||||
->addSelect("SUM(
|
->addSelect("SUM(
|
||||||
CASE WHEN s.status = :status_inactive AND s.deleted_at IS NULL
|
CASE WHEN s.deleted_at IS NOT NULL
|
||||||
THEN 1 ELSE 0 END
|
THEN 1 ELSE 0 END
|
||||||
) as :status_inactive")
|
) as trash")
|
||||||
->addSelect("SUM(
|
->addSelect("SUM(
|
||||||
CASE WHEN s.status = :status_unconfirmed AND s.deleted_at IS NULL
|
CASE WHEN s.status = :status_subscribed AND s.deleted_at IS NULL
|
||||||
THEN 1 ELSE 0 END
|
THEN 1 ELSE 0 END
|
||||||
) as :status_unconfirmed")
|
) as :status_subscribed")
|
||||||
->addSelect("SUM(
|
->addSelect("SUM(
|
||||||
CASE WHEN s.status = :status_bounced AND s.deleted_at IS NULL
|
CASE WHEN s.status = :status_unsubscribed AND s.deleted_at IS NULL
|
||||||
THEN 1 ELSE 0 END
|
THEN 1 ELSE 0 END
|
||||||
) as :status_bounced")
|
) as :status_unsubscribed")
|
||||||
->from($subscribersTable, 's')
|
->addSelect("SUM(
|
||||||
->setParameter('status_subscribed', SubscriberEntity::STATUS_SUBSCRIBED)
|
CASE WHEN s.status = :status_inactive AND s.deleted_at IS NULL
|
||||||
->setParameter('status_unsubscribed', SubscriberEntity::STATUS_UNSUBSCRIBED)
|
THEN 1 ELSE 0 END
|
||||||
->setParameter('status_inactive', SubscriberEntity::STATUS_INACTIVE)
|
) as :status_inactive")
|
||||||
->setParameter('status_unconfirmed', SubscriberEntity::STATUS_UNCONFIRMED)
|
->addSelect("SUM(
|
||||||
->setParameter('status_bounced', SubscriberEntity::STATUS_BOUNCED);
|
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->addConstraintsForSubscribersWithoutSegmentToDBAL($queryBuilder);
|
|
||||||
$statement = $this->executeQuery($queryBuilder);
|
|
||||||
$result = $statement->fetch();
|
|
||||||
$this->transientCache->setItem(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY, $result, $id);
|
|
||||||
}
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,24 +425,27 @@ class SegmentSubscribersRepository {
|
|||||||
return $statement;
|
return $statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubscribersStatisticsCount(SegmentEntity $segment) {
|
public function getSubscribersGlobalStatusStatisticsCount(SegmentEntity $segment): array {
|
||||||
$result = $this->transientCache->getItem(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY, (int)$segment->getId());
|
if ($segment->isStatic()) {
|
||||||
if (!$result) {
|
$queryBuilder = $this->createStaticGlobalStatusStatisticsQueryBuilder($segment);
|
||||||
if ($segment->isStatic()) {
|
} else {
|
||||||
$queryBuilder = $this->createStaticStatisticsQueryBuilder($segment);
|
$queryBuilder = $this->createDynamicStatisticsQueryBuilder();
|
||||||
} else {
|
$this->filterSubscribersInDynamicSegment($queryBuilder, $segment);
|
||||||
$queryBuilder = $this->createDynamicStatisticsQueryBuilder();
|
|
||||||
$this->filterSubscribersInDynamicSegment($queryBuilder, $segment);
|
|
||||||
}
|
|
||||||
|
|
||||||
$statement = $this->executeQuery($queryBuilder);
|
|
||||||
$result = $statement->fetch();
|
|
||||||
$this->transientCache->setItem(
|
|
||||||
TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY,
|
|
||||||
$result,
|
|
||||||
(int)$segment->getId()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return $result;
|
|
||||||
|
$statement = $this->executeQuery($queryBuilder);
|
||||||
|
return $statement->fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSubscribersStatisticsCount(SegmentEntity $segment): array {
|
||||||
|
if ($segment->isStatic()) {
|
||||||
|
$queryBuilder = $this->createStaticStatisticsQueryBuilder($segment);
|
||||||
|
} else {
|
||||||
|
$queryBuilder = $this->createDynamicStatisticsQueryBuilder();
|
||||||
|
$this->filterSubscribersInDynamicSegment($queryBuilder, $segment);
|
||||||
|
}
|
||||||
|
|
||||||
|
$statement = $this->executeQuery($queryBuilder);
|
||||||
|
return $statement->fetch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ namespace MailPoet\Segments;
|
|||||||
use MailPoet\Entities\SegmentEntity;
|
use MailPoet\Entities\SegmentEntity;
|
||||||
use MailPoet\Entities\SubscriberEntity;
|
use MailPoet\Entities\SubscriberEntity;
|
||||||
use MailPoet\Entities\SubscriberSegmentEntity;
|
use MailPoet\Entities\SubscriberSegmentEntity;
|
||||||
|
use MailPoet\Subscribers\SubscribersCountsController;
|
||||||
use MailPoetVendor\Doctrine\DBAL\Connection;
|
use MailPoetVendor\Doctrine\DBAL\Connection;
|
||||||
use MailPoetVendor\Doctrine\DBAL\Driver\Statement;
|
use MailPoetVendor\Doctrine\DBAL\Driver\Statement;
|
||||||
use MailPoetVendor\Doctrine\ORM\EntityManager;
|
use MailPoetVendor\Doctrine\ORM\EntityManager;
|
||||||
@ -13,15 +14,15 @@ class SegmentsSimpleListRepository {
|
|||||||
/** @var EntityManager */
|
/** @var EntityManager */
|
||||||
private $entityManager;
|
private $entityManager;
|
||||||
|
|
||||||
/** @var SegmentSubscribersRepository */
|
/** @var SubscribersCountsController */
|
||||||
private $segmentsSubscriberRepository;
|
private $subscribersCountsController;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
EntityManager $entityManager,
|
EntityManager $entityManager,
|
||||||
SegmentSubscribersRepository $segmentsSubscriberRepository
|
SubscribersCountsController $subscribersCountsController
|
||||||
) {
|
) {
|
||||||
$this->entityManager = $entityManager;
|
$this->entityManager = $entityManager;
|
||||||
$this->segmentsSubscriberRepository = $segmentsSubscriberRepository;
|
$this->subscribersCountsController = $subscribersCountsController;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,7 +52,7 @@ 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();
|
$withoutSegmentStats = $this->subscribersCountsController->getSubscribersWithoutSegmentStatisticsCount();
|
||||||
$segments[] = [
|
$segments[] = [
|
||||||
'id' => '0',
|
'id' => '0',
|
||||||
'type' => SegmentEntity::TYPE_WITHOUT_LIST,
|
'type' => SegmentEntity::TYPE_WITHOUT_LIST,
|
||||||
@ -114,7 +115,8 @@ class SegmentsSimpleListRepository {
|
|||||||
// Fetch subscribers counts for dynamic segments and correct data types
|
// Fetch subscribers counts for dynamic segments and correct data types
|
||||||
foreach ($segments as $key => $segment) {
|
foreach ($segments as $key => $segment) {
|
||||||
if ($segment['type'] === SegmentEntity::TYPE_DYNAMIC) {
|
if ($segment['type'] === SegmentEntity::TYPE_DYNAMIC) {
|
||||||
$segments[$key]['subscribers'] = $this->segmentsSubscriberRepository->getSubscribersCount((int)$segment['id'], $subscriberGlobalStatus);
|
$statisticsKey = $subscriberGlobalStatus ?: 'all';
|
||||||
|
$segments[$key]['subscribers'] = (int)$this->subscribersCountsController->getSegmentStatisticsCountById($segment['id'])[$statisticsKey];
|
||||||
} else {
|
} else {
|
||||||
$segments[$key]['subscribers'] = (int)$segment['subscribers'];
|
$segments[$key]['subscribers'] = (int)$segment['subscribers'];
|
||||||
}
|
}
|
||||||
|
@ -38,15 +38,20 @@ class SubscriberListingRepository extends ListingRepository {
|
|||||||
/** @var SegmentSubscribersRepository */
|
/** @var SegmentSubscribersRepository */
|
||||||
private $segmentSubscribersRepository;
|
private $segmentSubscribersRepository;
|
||||||
|
|
||||||
|
/** @var SubscribersCountsController */
|
||||||
|
private $subscribersCountsController;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
EntityManager $entityManager,
|
EntityManager $entityManager,
|
||||||
FilterHandler $dynamicSegmentsFilter,
|
FilterHandler $dynamicSegmentsFilter,
|
||||||
SegmentSubscribersRepository $segmentSubscribersRepository
|
SegmentSubscribersRepository $segmentSubscribersRepository,
|
||||||
|
SubscribersCountsController $subscribersCountsController
|
||||||
) {
|
) {
|
||||||
parent::__construct($entityManager);
|
parent::__construct($entityManager);
|
||||||
$this->dynamicSegmentsFilter = $dynamicSegmentsFilter;
|
$this->dynamicSegmentsFilter = $dynamicSegmentsFilter;
|
||||||
$this->entityManager = $entityManager;
|
$this->entityManager = $entityManager;
|
||||||
$this->segmentSubscribersRepository = $segmentSubscribersRepository;
|
$this->segmentSubscribersRepository = $segmentSubscribersRepository;
|
||||||
|
$this->subscribersCountsController = $subscribersCountsController;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getData(ListingDefinition $definition): array {
|
public function getData(ListingDefinition $definition): array {
|
||||||
@ -223,7 +228,7 @@ class SubscriberListingRepository extends ListingRepository {
|
|||||||
public function getFilters(ListingDefinition $definition): array {
|
public function getFilters(ListingDefinition $definition): array {
|
||||||
$group = $definition->getGroup();
|
$group = $definition->getGroup();
|
||||||
|
|
||||||
$subscribersWithoutSegmentStats = $this->segmentSubscribersRepository->getSubscribersWithoutSegmentStatisticsCount();
|
$subscribersWithoutSegmentStats = $this->subscribersCountsController->getSubscribersWithoutSegmentStatisticsCount();
|
||||||
$key = $group ?: 'all';
|
$key = $group ?: 'all';
|
||||||
$subscribersWithoutSegmentCount = $subscribersWithoutSegmentStats[$key];
|
$subscribersWithoutSegmentCount = $subscribersWithoutSegmentStats[$key];
|
||||||
|
|
||||||
@ -256,7 +261,11 @@ class SubscriberListingRepository extends ListingRepository {
|
|||||||
$segmentList = [];
|
$segmentList = [];
|
||||||
foreach ($queryBuilder->getQuery()->getResult() as $segment) {
|
foreach ($queryBuilder->getQuery()->getResult() as $segment) {
|
||||||
$key = $group ?: 'all';
|
$key = $group ?: 'all';
|
||||||
$count = $this->segmentSubscribersRepository->getSubscribersStatisticsCount($segment);
|
if ($segment->isStatic()) {
|
||||||
|
$count = $this->subscribersCountsController->getSegmentGlobalStatusStatisticsCount($segment);
|
||||||
|
} else {
|
||||||
|
$count = $this->subscribersCountsController->getSegmentStatisticsCount($segment);
|
||||||
|
}
|
||||||
if (!$count[$key]) {
|
if (!$count[$key]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ use Codeception\Stub\Expected;
|
|||||||
use MailPoet\API\JSON\Error as APIError;
|
use MailPoet\API\JSON\Error as APIError;
|
||||||
use MailPoet\API\JSON\Response as APIResponse;
|
use MailPoet\API\JSON\Response as APIResponse;
|
||||||
use MailPoet\API\JSON\v1\Settings;
|
use MailPoet\API\JSON\v1\Settings;
|
||||||
use MailPoet\Cache\TransientCache;
|
|
||||||
use MailPoet\Config\ServicesChecker;
|
use MailPoet\Config\ServicesChecker;
|
||||||
use MailPoet\Cron\Workers\InactiveSubscribers;
|
use MailPoet\Cron\Workers\InactiveSubscribers;
|
||||||
use MailPoet\Cron\Workers\WooCommerceSync;
|
use MailPoet\Cron\Workers\WooCommerceSync;
|
||||||
@ -17,12 +16,12 @@ use MailPoet\Models\ScheduledTask;
|
|||||||
use MailPoet\Newsletter\NewslettersRepository;
|
use MailPoet\Newsletter\NewslettersRepository;
|
||||||
use MailPoet\Newsletter\Sending\ScheduledTasksRepository;
|
use MailPoet\Newsletter\Sending\ScheduledTasksRepository;
|
||||||
use MailPoet\Segments\SegmentsRepository;
|
use MailPoet\Segments\SegmentsRepository;
|
||||||
use MailPoet\Segments\SegmentSubscribersRepository;
|
|
||||||
use MailPoet\Services\AuthorizedEmailsController;
|
use MailPoet\Services\AuthorizedEmailsController;
|
||||||
use MailPoet\Services\Bridge;
|
use MailPoet\Services\Bridge;
|
||||||
use MailPoet\Settings\SettingsController;
|
use MailPoet\Settings\SettingsController;
|
||||||
use MailPoet\Settings\SettingsRepository;
|
use MailPoet\Settings\SettingsRepository;
|
||||||
use MailPoet\Statistics\StatisticsOpensRepository;
|
use MailPoet\Statistics\StatisticsOpensRepository;
|
||||||
|
use MailPoet\Subscribers\SubscribersCountsController;
|
||||||
use MailPoet\WooCommerce\TransactionalEmails;
|
use MailPoet\WooCommerce\TransactionalEmails;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
use MailPoetVendor\Carbon\Carbon;
|
use MailPoetVendor\Carbon\Carbon;
|
||||||
@ -57,9 +56,8 @@ class SettingsTest extends \MailPoetTest {
|
|||||||
$this->diContainer->get(ScheduledTasksRepository::class),
|
$this->diContainer->get(ScheduledTasksRepository::class),
|
||||||
$this->diContainer->get(FormMessageController::class),
|
$this->diContainer->get(FormMessageController::class),
|
||||||
$this->make(ServicesChecker::class, ['isMailPoetAPIKeyPendingApproval' => false]),
|
$this->make(ServicesChecker::class, ['isMailPoetAPIKeyPendingApproval' => false]),
|
||||||
$this->diContainer->get(TransientCache::class),
|
|
||||||
$this->diContainer->get(SegmentsRepository::class),
|
$this->diContainer->get(SegmentsRepository::class),
|
||||||
$this->diContainer->get(SegmentSubscribersRepository::class)
|
$this->diContainer->get(SubscribersCountsController::class)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,9 +96,8 @@ class SettingsTest extends \MailPoetTest {
|
|||||||
$this->diContainer->get(ScheduledTasksRepository::class),
|
$this->diContainer->get(ScheduledTasksRepository::class),
|
||||||
$this->diContainer->get(FormMessageController::class),
|
$this->diContainer->get(FormMessageController::class),
|
||||||
$this->make(ServicesChecker::class, ['isMailPoetAPIKeyPendingApproval' => false]),
|
$this->make(ServicesChecker::class, ['isMailPoetAPIKeyPendingApproval' => false]),
|
||||||
$this->diContainer->get(TransientCache::class),
|
|
||||||
$this->diContainer->get(SegmentsRepository::class),
|
$this->diContainer->get(SegmentsRepository::class),
|
||||||
$this->diContainer->get(SegmentSubscribersRepository::class)
|
$this->diContainer->get(SubscribersCountsController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
$response = $this->endpoint->set(/* missing data */);
|
$response = $this->endpoint->set(/* missing data */);
|
||||||
@ -130,9 +127,8 @@ class SettingsTest extends \MailPoetTest {
|
|||||||
$this->diContainer->get(ScheduledTasksRepository::class),
|
$this->diContainer->get(ScheduledTasksRepository::class),
|
||||||
$this->diContainer->get(FormMessageController::class),
|
$this->diContainer->get(FormMessageController::class),
|
||||||
$this->make(ServicesChecker::class, ['isMailPoetAPIKeyPendingApproval' => false]),
|
$this->make(ServicesChecker::class, ['isMailPoetAPIKeyPendingApproval' => false]),
|
||||||
$this->diContainer->get(TransientCache::class),
|
|
||||||
$this->diContainer->get(SegmentsRepository::class),
|
$this->diContainer->get(SegmentsRepository::class),
|
||||||
$this->diContainer->get(SegmentSubscribersRepository::class)
|
$this->diContainer->get(SubscribersCountsController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
MailerLog::pauseSending(MailerLog::getMailerLog());
|
MailerLog::pauseSending(MailerLog::getMailerLog());
|
||||||
@ -156,9 +152,8 @@ class SettingsTest extends \MailPoetTest {
|
|||||||
$this->diContainer->get(ScheduledTasksRepository::class),
|
$this->diContainer->get(ScheduledTasksRepository::class),
|
||||||
$this->diContainer->get(FormMessageController::class),
|
$this->diContainer->get(FormMessageController::class),
|
||||||
$this->make(ServicesChecker::class),
|
$this->make(ServicesChecker::class),
|
||||||
$this->diContainer->get(TransientCache::class),
|
|
||||||
$this->diContainer->get(SegmentsRepository::class),
|
$this->diContainer->get(SegmentsRepository::class),
|
||||||
$this->diContainer->get(SegmentSubscribersRepository::class)
|
$this->diContainer->get(SubscribersCountsController::class)
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->settings->set('sender.address', '');
|
$this->settings->set('sender.address', '');
|
||||||
|
@ -39,7 +39,8 @@ class SubscriberListingRepositoryTest extends \MailPoetTest {
|
|||||||
$this->repository = new SubscriberListingRepository(
|
$this->repository = new SubscriberListingRepository(
|
||||||
$this->entityManager,
|
$this->entityManager,
|
||||||
$this->diContainer->get(FilterHandler::class),
|
$this->diContainer->get(FilterHandler::class),
|
||||||
$this->diContainer->get(SegmentSubscribersRepository::class)
|
$this->diContainer->get(SegmentSubscribersRepository::class),
|
||||||
|
$this->diContainer->get(SubscribersCountsController::class)
|
||||||
);
|
);
|
||||||
$this->cleanup();
|
$this->cleanup();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user