Add fetching of global subscribers stats to Homepage data controller
[MAILPOET-4828]
This commit is contained in:
committed by
Aschepikov
parent
9217f197f9
commit
ab35f5c8c1
@ -8,6 +8,7 @@ use MailPoet\Automation\Integrations\MailPoet\Actions\SendEmailAction;
|
||||
use MailPoet\Automation\Integrations\MailPoet\Triggers\SomeoneSubscribesTrigger;
|
||||
use MailPoet\Automation\Integrations\MailPoet\Triggers\UserRegistrationTrigger;
|
||||
use MailPoet\Entities\NewsletterEntity;
|
||||
use MailPoet\Entities\SubscriberEntity;
|
||||
use MailPoet\Form\FormsRepository;
|
||||
use MailPoet\Newsletter\NewslettersRepository;
|
||||
use MailPoet\Services\Bridge;
|
||||
@ -15,6 +16,8 @@ use MailPoet\Settings\SettingsController;
|
||||
use MailPoet\Subscribers\SubscribersRepository;
|
||||
use MailPoet\Util\License\Features\Subscribers;
|
||||
use MailPoet\WooCommerce\Helper as WooCommerceHelper;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
use MailPoetVendor\Carbon\Carbon;
|
||||
|
||||
class HomepageDataController {
|
||||
public const UPSELL_SUBSCRIBERS_COUNT_REQUIRED = 600;
|
||||
@ -40,6 +43,9 @@ class HomepageDataController {
|
||||
/** @var Subscribers */
|
||||
private $subscribers;
|
||||
|
||||
/** @var WPFunctions */
|
||||
private $wp;
|
||||
|
||||
public function __construct(
|
||||
SettingsController $settingsController,
|
||||
SubscribersRepository $subscribersRepository,
|
||||
@ -47,6 +53,7 @@ class HomepageDataController {
|
||||
NewslettersRepository $newslettersRepository,
|
||||
AutomationStorage $automationStorage,
|
||||
Subscribers $subscribers,
|
||||
WPFunctions $wp,
|
||||
WooCommerceHelper $wooCommerceHelper
|
||||
) {
|
||||
$this->settingsController = $settingsController;
|
||||
@ -54,6 +61,7 @@ class HomepageDataController {
|
||||
$this->formsRepository = $formsRepository;
|
||||
$this->newslettersRepository = $newslettersRepository;
|
||||
$this->automationStorage = $automationStorage;
|
||||
$this->wp = $wp;
|
||||
$this->wooCommerceHelper = $wooCommerceHelper;
|
||||
$this->subscribers = $subscribers;
|
||||
}
|
||||
@ -73,6 +81,7 @@ class HomepageDataController {
|
||||
'upsellStatus' => $showUpsell ? $this->getUpsellStatus($subscribersCount) : null,
|
||||
'wooCustomersCount' => $this->wooCommerceHelper->getCustomersCount(),
|
||||
'subscribersCount' => $subscribersCount,
|
||||
'subscribersStats' => $this->getSubscribersStats(),
|
||||
];
|
||||
}
|
||||
|
||||
@ -129,4 +138,17 @@ class HomepageDataController {
|
||||
'canDisplay' => !$hasValidMssKey && $subscribersCount > self::UPSELL_SUBSCRIBERS_COUNT_REQUIRED,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{global:array{subscribed:int, unsubscribed:int}}
|
||||
*/
|
||||
private function getSubscribersStats(): array {
|
||||
$thirtyDaysAgo = Carbon::createFromTimestamp($this->wp->currentTime('timestamp'))->subDays(30);
|
||||
return [
|
||||
'global' => [
|
||||
'subscribed' => $this->subscribersRepository->getCountOfCreatedAfterWithStatues($thirtyDaysAgo, [SubscriberEntity::STATUS_SUBSCRIBED]),
|
||||
'unsubscribed' => $this->subscribersRepository->getCountOfUnsubscribedAfter($thirtyDaysAgo),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ namespace MailPoet\Subscribers;
|
||||
use MailPoet\Config\SubscriberChangesNotifier;
|
||||
use MailPoet\Doctrine\Repository;
|
||||
use MailPoet\Entities\SegmentEntity;
|
||||
use MailPoet\Entities\StatisticsUnsubscribeEntity;
|
||||
use MailPoet\Entities\SubscriberCustomFieldEntity;
|
||||
use MailPoet\Entities\SubscriberEntity;
|
||||
use MailPoet\Entities\SubscriberSegmentEntity;
|
||||
@ -370,6 +371,35 @@ class SubscribersRepository extends Repository {
|
||||
return is_int($maxSubscriberId) ? $maxSubscriberId : 0;
|
||||
}
|
||||
|
||||
public function getCountOfCreatedAfterWithStatues(\DateTimeInterface $createdAfter, array $statuses): int {
|
||||
$result = $this->entityManager->createQueryBuilder()
|
||||
->select('COUNT(s.id)')
|
||||
->from(SubscriberEntity::class, 's')
|
||||
->where('s.createdAt > :createdAfter')
|
||||
->andWhere('s.status IN (:statuses)')
|
||||
->andWhere('s.deletedAt IS NULL')
|
||||
->setParameter('createdAfter', $createdAfter)
|
||||
->setParameter('statuses', $statuses)
|
||||
->getQuery()
|
||||
->getSingleScalarResult();
|
||||
return intval($result);
|
||||
}
|
||||
|
||||
public function getCountOfUnsubscribedAfter(\DateTimeInterface $unsubscribedAfter): int {
|
||||
$result = $this->entityManager->createQueryBuilder()
|
||||
->select('COUNT(s.id)')
|
||||
->from(StatisticsUnsubscribeEntity::class, 'su')
|
||||
->join('su.subscriber', 's')
|
||||
->where('s.createdAt > :unsubscribedAfter')
|
||||
->andWhere('s.status = :status')
|
||||
->andWhere('s.deletedAt IS NULL')
|
||||
->setParameter('unsubscribedAfter', $unsubscribedAfter)
|
||||
->setParameter('status', SubscriberEntity::STATUS_UNSUBSCRIBED)
|
||||
->getQuery()
|
||||
->getSingleScalarResult();
|
||||
return intval($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int - number of processed ids
|
||||
*/
|
||||
|
@ -136,7 +136,7 @@ class Subscriber {
|
||||
* @return $this
|
||||
*/
|
||||
public function withCreatedAt(DateTimeInterface $createdAt) {
|
||||
$this->data['setCreatedAt'] = $createdAt;
|
||||
$this->data['createdAt'] = $createdAt;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -208,6 +208,7 @@ class Subscriber {
|
||||
if (isset($this->data['subscribedIp'])) $subscriber->setSubscribedIp($this->data['subscribedIp']);
|
||||
if (isset($this->data['confirmedIp'])) $subscriber->setConfirmedIp($this->data['confirmedIp']);
|
||||
if (isset($this->data['unconfirmedData'])) $subscriber->setUnconfirmedData($this->data['unconfirmedData']);
|
||||
if (isset($this->data['createdAt'])) $subscriber->setCreatedAt($this->data['createdAt']);
|
||||
if (isset($this->data['source'])) {
|
||||
$subscriber->setSource($this->data['source']);
|
||||
}
|
||||
|
@ -7,11 +7,13 @@ use MailPoet\Entities\NewsletterEntity;
|
||||
use MailPoet\Entities\NewsletterOptionEntity;
|
||||
use MailPoet\Entities\NewsletterOptionFieldEntity;
|
||||
use MailPoet\Entities\SettingEntity;
|
||||
use MailPoet\Entities\StatisticsUnsubscribeEntity;
|
||||
use MailPoet\Entities\SubscriberEntity;
|
||||
use MailPoet\Settings\SettingsController;
|
||||
use MailPoet\Test\DataFactories\Form;
|
||||
use MailPoet\Test\DataFactories\Newsletter;
|
||||
use MailPoet\Test\DataFactories\Subscriber;
|
||||
use MailPoetVendor\Carbon\Carbon;
|
||||
|
||||
class HomepageDataControllerTest extends \MailPoetTest {
|
||||
/** @var HomepageDataController */
|
||||
@ -34,6 +36,8 @@ class HomepageDataControllerTest extends \MailPoetTest {
|
||||
expect($data['productDiscoveryStatus'])->notEmpty();
|
||||
expect($data['wooCustomersCount'])->int();
|
||||
expect($data['subscribersCount'])->int();
|
||||
expect($data['subscribersStats'])->array();
|
||||
expect($data['taskListStatus'])->notEmpty();
|
||||
}
|
||||
|
||||
public function testItFetchesSenderTaskListStatus(): void {
|
||||
@ -169,6 +173,37 @@ class HomepageDataControllerTest extends \MailPoetTest {
|
||||
expect($productDiscoveryStatus['setUpAbandonedCartEmail'])->true();
|
||||
}
|
||||
|
||||
public function testItFetchesSubscriberStatsForZeroSubscribers(): void {
|
||||
$subscribersStats = $this->homepageDataController->getPageData()['subscribersStats'];
|
||||
expect($subscribersStats['global']['subscribed'])->equals(0);
|
||||
expect($subscribersStats['global']['unsubscribed'])->equals(0);
|
||||
}
|
||||
|
||||
public function testItFetchesCorrectGlobalSubscriberStats(): void {
|
||||
$thirtyOneDaysAgo = Carbon::now()->subDays(31);
|
||||
$twentyNineDaysAgo = Carbon::now()->subDays(29);
|
||||
// Old subscribed
|
||||
(new Subscriber())->withCreatedAt($thirtyOneDaysAgo)->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)->create();
|
||||
// New subscribed
|
||||
(new Subscriber())->withCreatedAt($twentyNineDaysAgo)->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)->create();
|
||||
// Unsubscribed long time ago
|
||||
$oldUnsubscribed = (new Subscriber())->withCreatedAt($thirtyOneDaysAgo)->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)->create();
|
||||
$oldUnsubscribedStats = new StatisticsUnsubscribeEntity(null, null, $oldUnsubscribed);
|
||||
$oldUnsubscribedStats->setCreatedAt($thirtyOneDaysAgo);
|
||||
$this->entityManager->persist($oldUnsubscribedStats);
|
||||
$this->entityManager->flush();
|
||||
// Freshly unsubscribed
|
||||
$newUnsubscribed = (new Subscriber())->withCreatedAt($twentyNineDaysAgo)->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)->create();
|
||||
$newUnsubscribedStats = new StatisticsUnsubscribeEntity(null, null, $newUnsubscribed);
|
||||
$newUnsubscribedStats->setCreatedAt($twentyNineDaysAgo);
|
||||
$this->entityManager->persist($newUnsubscribedStats);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$subscribersStats = $this->homepageDataController->getPageData()['subscribersStats'];
|
||||
expect($subscribersStats['global']['subscribed'])->equals(1);
|
||||
expect($subscribersStats['global']['unsubscribed'])->equals(1);
|
||||
}
|
||||
|
||||
private function cleanup(): void {
|
||||
$this->truncateEntity(SettingEntity::class);
|
||||
$this->truncateEntity(SubscriberEntity::class);
|
||||
|
Reference in New Issue
Block a user