Compute change of global subscribed subscribers
[MAILPOET-4828]
This commit is contained in:
committed by
Aschepikov
parent
6e99d5ec9d
commit
04307ca2a6
@@ -161,10 +161,24 @@ class HomepageDataController {
|
|||||||
$listData[$list['id']]['unsubscribed'] = $list['count'];
|
$listData[$list['id']]['unsubscribed'] = $list['count'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$subscribedCount = $this->subscribersRepository->getCountOfCreatedAfterWithStatues($thirtyDaysAgo, [SubscriberEntity::STATUS_SUBSCRIBED]);
|
||||||
|
$unsubscribedCount = $this->subscribersRepository->getCountOfUnsubscribedAfter($thirtyDaysAgo);
|
||||||
|
$subscribedSubscribersCount = $this->subscribersRepository->getCountOfSubscribersForStates([SubscriberEntity::STATUS_SUBSCRIBED]);
|
||||||
|
$subscribedSubscribers30DaysAgo = $subscribedSubscribersCount - $subscribedCount + $unsubscribedCount;
|
||||||
|
if ($subscribedSubscribers30DaysAgo > 0) {
|
||||||
|
$globalChangePercent = (($subscribedSubscribersCount - $subscribedSubscribers30DaysAgo) / $subscribedSubscribers30DaysAgo) * 100;
|
||||||
|
if (floor($globalChangePercent) !== (float)$globalChangePercent) {
|
||||||
|
$globalChangePercent = round($globalChangePercent, 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$globalChangePercent = $subscribedSubscribersCount * 100;
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'global' => [
|
'global' => [
|
||||||
'subscribed' => $this->subscribersRepository->getCountOfCreatedAfterWithStatues($thirtyDaysAgo, [SubscriberEntity::STATUS_SUBSCRIBED]),
|
'subscribed' => $subscribedCount,
|
||||||
'unsubscribed' => $this->subscribersRepository->getCountOfUnsubscribedAfter($thirtyDaysAgo),
|
'unsubscribed' => $unsubscribedCount,
|
||||||
|
'change' => $globalChangePercent,
|
||||||
],
|
],
|
||||||
'lists' => array_values($listData),
|
'lists' => array_values($listData),
|
||||||
];
|
];
|
||||||
|
@@ -51,18 +51,22 @@ class SubscribersRepository extends Repository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getTotalSubscribers(): int {
|
public function getTotalSubscribers(): int {
|
||||||
|
return $this->getCountOfSubscribersForStates([
|
||||||
|
SubscriberEntity::STATUS_SUBSCRIBED,
|
||||||
|
SubscriberEntity::STATUS_UNCONFIRMED,
|
||||||
|
SubscriberEntity::STATUS_INACTIVE,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCountOfSubscribersForStates(array $states): int {
|
||||||
$query = $this->entityManager
|
$query = $this->entityManager
|
||||||
->createQueryBuilder()
|
->createQueryBuilder()
|
||||||
->select('count(n.id)')
|
->select('count(n.id)')
|
||||||
->from(SubscriberEntity::class, 'n')
|
->from(SubscriberEntity::class, 'n')
|
||||||
->where('n.deletedAt IS NULL AND n.status IN (:statuses)')
|
->where('n.deletedAt IS NULL AND n.status IN (:statuses)')
|
||||||
->setParameter('statuses', [
|
->setParameter('statuses', $states)
|
||||||
SubscriberEntity::STATUS_SUBSCRIBED,
|
|
||||||
SubscriberEntity::STATUS_UNCONFIRMED,
|
|
||||||
SubscriberEntity::STATUS_INACTIVE,
|
|
||||||
])
|
|
||||||
->getQuery();
|
->getQuery();
|
||||||
return (int)$query->getSingleScalarResult();
|
return intval($query->getSingleScalarResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function invalidateTotalSubscribersCache(): void {
|
public function invalidateTotalSubscribersCache(): void {
|
||||||
@@ -390,7 +394,8 @@ class SubscribersRepository extends Repository {
|
|||||||
->select('COUNT(s.id)')
|
->select('COUNT(s.id)')
|
||||||
->from(StatisticsUnsubscribeEntity::class, 'su')
|
->from(StatisticsUnsubscribeEntity::class, 'su')
|
||||||
->join('su.subscriber', 's')
|
->join('su.subscriber', 's')
|
||||||
->where('s.createdAt > :unsubscribedAfter')
|
->where('s.createdAt <= :unsubscribedAfter')
|
||||||
|
->andWhere('su.createdAt > :unsubscribedAfter')
|
||||||
->andWhere('s.status = :status')
|
->andWhere('s.status = :status')
|
||||||
->andWhere('s.deletedAt IS NULL')
|
->andWhere('s.deletedAt IS NULL')
|
||||||
->setParameter('unsubscribedAfter', $unsubscribedAfter)
|
->setParameter('unsubscribedAfter', $unsubscribedAfter)
|
||||||
|
@@ -815,11 +815,6 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: ../../lib/Subscribers/SubscribersRepository.php
|
path: ../../lib/Subscribers/SubscribersRepository.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Cannot cast mixed to int\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../../lib/Subscribers/SubscribersRepository.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Method MailPoet\\\\Subscribers\\\\SubscribersRepository\\:\\:findIdsOfDeletedByEmails\\(\\) should return array\\<int\\> but returns array\\<array\\<string, int\\>\\>\\.$#"
|
message: "#^Method MailPoet\\\\Subscribers\\\\SubscribersRepository\\:\\:findIdsOfDeletedByEmails\\(\\) should return array\\<int\\> but returns array\\<array\\<string, int\\>\\>\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
@@ -815,11 +815,6 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: ../../lib/Subscribers/SubscribersRepository.php
|
path: ../../lib/Subscribers/SubscribersRepository.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Cannot cast mixed to int\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../../lib/Subscribers/SubscribersRepository.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Method MailPoet\\\\Subscribers\\\\SubscribersRepository\\:\\:findIdsOfDeletedByEmails\\(\\) should return array\\<int\\> but returns array\\<array\\<string, int\\>\\>\\.$#"
|
message: "#^Method MailPoet\\\\Subscribers\\\\SubscribersRepository\\:\\:findIdsOfDeletedByEmails\\(\\) should return array\\<int\\> but returns array\\<array\\<string, int\\>\\>\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
@@ -814,11 +814,6 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: ../../lib/Subscribers/SubscribersRepository.php
|
path: ../../lib/Subscribers/SubscribersRepository.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Cannot cast mixed to int\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../../lib/Subscribers/SubscribersRepository.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Method MailPoet\\\\Subscribers\\\\SubscribersRepository\\:\\:findIdsOfDeletedByEmails\\(\\) should return array\\<int\\> but returns array\\<array\\<string, int\\>\\>\\.$#"
|
message: "#^Method MailPoet\\\\Subscribers\\\\SubscribersRepository\\:\\:findIdsOfDeletedByEmails\\(\\) should return array\\<int\\> but returns array\\<array\\<string, int\\>\\>\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
@@ -195,8 +195,8 @@ class HomepageDataControllerTest extends \MailPoetTest {
|
|||||||
$oldUnsubscribedStats->setCreatedAt($thirtyOneDaysAgo);
|
$oldUnsubscribedStats->setCreatedAt($thirtyOneDaysAgo);
|
||||||
$this->entityManager->persist($oldUnsubscribedStats);
|
$this->entityManager->persist($oldUnsubscribedStats);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
// Freshly unsubscribed
|
// Freshly unsubscribed (but created before the period)
|
||||||
$newUnsubscribed = (new Subscriber())->withCreatedAt($twentyNineDaysAgo)->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)->create();
|
$newUnsubscribed = (new Subscriber())->withCreatedAt($thirtyOneDaysAgo)->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)->create();
|
||||||
$newUnsubscribedStats = new StatisticsUnsubscribeEntity(null, null, $newUnsubscribed);
|
$newUnsubscribedStats = new StatisticsUnsubscribeEntity(null, null, $newUnsubscribed);
|
||||||
$newUnsubscribedStats->setCreatedAt($twentyNineDaysAgo);
|
$newUnsubscribedStats->setCreatedAt($twentyNineDaysAgo);
|
||||||
$this->entityManager->persist($newUnsubscribedStats);
|
$this->entityManager->persist($newUnsubscribedStats);
|
||||||
@@ -207,6 +207,46 @@ class HomepageDataControllerTest extends \MailPoetTest {
|
|||||||
expect($subscribersStats['global']['unsubscribed'])->equals(1);
|
expect($subscribersStats['global']['unsubscribed'])->equals(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testItFetchesCorrectGlobalSubscriberChange(): void {
|
||||||
|
$thirtyOneDaysAgo = Carbon::now()->subDays(31);
|
||||||
|
$twentyNineDaysAgo = Carbon::now()->subDays(29);
|
||||||
|
|
||||||
|
// 10 New Subscribers
|
||||||
|
for ($i = 0; $i < 10; $i++) {
|
||||||
|
(new Subscriber())->withCreatedAt($twentyNineDaysAgo)->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)->create();
|
||||||
|
}
|
||||||
|
$subscribersStats = $this->homepageDataController->getPageData()['subscribersStats'];
|
||||||
|
expect($subscribersStats['global']['change'])->equals(1000);
|
||||||
|
|
||||||
|
// 10 New Subscribers + 5 Old Subscribers
|
||||||
|
for ($i = 0; $i < 5; $i++) {
|
||||||
|
(new Subscriber())->withCreatedAt($thirtyOneDaysAgo)->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)->create();
|
||||||
|
}
|
||||||
|
$subscribersStats = $this->homepageDataController->getPageData()['subscribersStats'];
|
||||||
|
expect($subscribersStats['global']['change'])->equals(200);
|
||||||
|
|
||||||
|
// 10 New Subscribers + 6 Old Subscribers
|
||||||
|
(new Subscriber())->withCreatedAt($thirtyOneDaysAgo)->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)->create();
|
||||||
|
$subscribersStats = $this->homepageDataController->getPageData()['subscribersStats'];
|
||||||
|
expect($subscribersStats['global']['change'])->equals( 166.7);
|
||||||
|
|
||||||
|
// 10 New Subscribers + 6 Old Subscribers + 10 New Unsubscribed
|
||||||
|
for ($i = 0; $i < 10; $i++) {
|
||||||
|
$unsubscribed = (new Subscriber())->withCreatedAt($thirtyOneDaysAgo)->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)->create();
|
||||||
|
$this->entityManager->persist(new StatisticsUnsubscribeEntity(null, null, $unsubscribed));
|
||||||
|
$this->entityManager->flush();
|
||||||
|
}
|
||||||
|
$subscribersStats = $this->homepageDataController->getPageData()['subscribersStats'];
|
||||||
|
expect($subscribersStats['global']['change'])->equals( 0);
|
||||||
|
|
||||||
|
// 10 New Subscribers + 6 Old Subscribers + 11 New Unsubscribed
|
||||||
|
$unsubscribed = (new Subscriber())->withCreatedAt($thirtyOneDaysAgo)->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)->create();
|
||||||
|
$this->entityManager->persist(new StatisticsUnsubscribeEntity(null, null, $unsubscribed));
|
||||||
|
$this->entityManager->flush();
|
||||||
|
$subscribersStats = $this->homepageDataController->getPageData()['subscribersStats'];
|
||||||
|
expect($subscribersStats['global']['change'])->equals( -5.9);
|
||||||
|
}
|
||||||
|
|
||||||
public function testItFetchesCorrectListLevelSubscribedStats(): void {
|
public function testItFetchesCorrectListLevelSubscribedStats(): void {
|
||||||
$thirtyOneDaysAgo = Carbon::now()->subDays(31);
|
$thirtyOneDaysAgo = Carbon::now()->subDays(31);
|
||||||
$twentyNineDaysAgo = Carbon::now()->subDays(29);
|
$twentyNineDaysAgo = Carbon::now()->subDays(29);
|
||||||
|
Reference in New Issue
Block a user