PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.34.2
MailPoet – Newsletters, Email Marketing, and Automation v5.34.2
5.34.2 5.34.1 5.34.0 5.33.1 5.33.0 5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / lib / Homepage / HomepageDataController.php
mailpoet / lib / Homepage Last commit date
HomepageDataController.php 2 years ago index.php 3 years ago
HomepageDataController.php
213 lines
1 <?php declare(strict_types = 1);
2
3 namespace MailPoet\Homepage;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\AutomaticEmails\WooCommerce\Events\AbandonedCart;
9 use MailPoet\Automation\Engine\Storage\AutomationStorage;
10 use MailPoet\Automation\Integrations\MailPoet\Actions\SendEmailAction;
11 use MailPoet\Automation\Integrations\MailPoet\Triggers\SomeoneSubscribesTrigger;
12 use MailPoet\Automation\Integrations\MailPoet\Triggers\UserRegistrationTrigger;
13 use MailPoet\Entities\NewsletterEntity;
14 use MailPoet\Form\FormsRepository;
15 use MailPoet\Newsletter\NewslettersRepository;
16 use MailPoet\Services\AuthorizedSenderDomainController;
17 use MailPoet\Services\Bridge;
18 use MailPoet\Settings\SettingsController;
19 use MailPoet\Subscribers\SubscribersCountsController;
20 use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
21 use MailPoet\Util\Notices\SenderDomainAuthenticationNotices;
22 use MailPoet\WooCommerce\Helper as WooCommerceHelper;
23
24 class HomepageDataController {
25 public const UPSELL_SUBSCRIBERS_COUNT_REQUIRED = 600;
26
27 /** @var SettingsController */
28 private $settingsController;
29
30 /** @var FormsRepository */
31 private $formsRepository;
32
33 /** @var WooCommerceHelper */
34 private $wooCommerceHelper;
35
36 /** @var NewslettersRepository */
37 private $newslettersRepository;
38
39 /** @var AutomationStorage */
40 private $automationStorage;
41
42 /** @var SubscribersFeature */
43 private $subscribersFeature;
44
45 /** @var SubscribersCountsController */
46 private $subscribersCountsController;
47
48 /** @var AuthorizedSenderDomainController */
49 private $senderDomainController;
50
51 /** @var SenderDomainAuthenticationNotices */
52 private $senderDomainAuthenticationNotices;
53
54 public function __construct(
55 SettingsController $settingsController,
56 FormsRepository $formsRepository,
57 NewslettersRepository $newslettersRepository,
58 AutomationStorage $automationStorage,
59 SubscribersFeature $subscribersFeature,
60 SubscribersCountsController $subscribersCountsController,
61 AuthorizedSenderDomainController $senderDomainController,
62 SenderDomainAuthenticationNotices $senderDomainAuthenticationNotices,
63 WooCommerceHelper $wooCommerceHelper
64 ) {
65 $this->settingsController = $settingsController;
66 $this->formsRepository = $formsRepository;
67 $this->newslettersRepository = $newslettersRepository;
68 $this->automationStorage = $automationStorage;
69 $this->wooCommerceHelper = $wooCommerceHelper;
70 $this->subscribersFeature = $subscribersFeature;
71 $this->subscribersCountsController = $subscribersCountsController;
72 $this->senderDomainController = $senderDomainController;
73 $this->senderDomainAuthenticationNotices = $senderDomainAuthenticationNotices;
74 }
75
76 public function getPageData(): array {
77 $subscribersCount = $this->subscribersFeature->getSubscribersCount();
78 $formsCount = $this->formsRepository->count();
79 $showTaskList = !$this->settingsController->get('homepage.task_list_dismissed', false);
80 $showProductDiscovery = !$this->settingsController->get('homepage.product_discovery_dismissed', false);
81 $showUpsell = !$this->settingsController->get('homepage.upsell_dismissed', false);
82 $fullyVerifiedSenderDomains = $this->senderDomainController->getFullyVerifiedSenderDomains(true);
83 $senderDomainsCount = count($fullyVerifiedSenderDomains);
84 return [
85 'taskListDismissed' => !$showTaskList,
86 'productDiscoveryDismissed' => !$showProductDiscovery,
87 'upsellDismissed' => !$showUpsell,
88 'taskListStatus' => $showTaskList ? $this->getTaskListStatus($subscribersCount, $formsCount, $senderDomainsCount) : null,
89 'productDiscoveryStatus' => $showProductDiscovery ? $this->getProductDiscoveryStatus($formsCount) : null,
90 'upsellStatus' => $showUpsell ? $this->getUpsellStatus($subscribersCount) : null,
91 'wooCustomersCount' => $this->wooCommerceHelper->getCustomersCount(),
92 'subscribersCount' => $subscribersCount,
93 'formsCount' => $formsCount,
94 'subscribersStats' => $this->getSubscribersStats(),
95 'isNewUserForSenderDomainAuth' => $this->senderDomainController->isNewUser(),
96 'isFreeMailUser' => $this->senderDomainAuthenticationNotices->isFreeMailUser(),
97 ];
98 }
99
100 /**
101 * @return array{senderSet:bool, mssConnected:bool, wooSubscribersImported:bool, subscribersAdded:bool, senderDomainAuthenticated:bool}
102 */
103 private function getTaskListStatus(int $subscribersCount, int $formsCount, int $senderDomainsCount): array {
104 return [
105 'senderSet' => $this->settingsController->get('sender.address', false) && $this->settingsController->get('sender.name', false),
106 'mssConnected' => Bridge::isMSSKeySpecified(),
107 'wooSubscribersImported' => (bool)$this->settingsController->get('woocommerce_import_screen_displayed', false),
108 'subscribersAdded' => $formsCount || ($subscribersCount > 10),
109 'senderDomainAuthenticated' => $senderDomainsCount > 0,
110 ];
111 }
112
113 /**
114 * @return array{setUpWelcomeCampaign:bool, addSubscriptionForm:bool, sendFirstNewsletter:bool, setUpAbandonedCartEmail:bool, brandWooEmails:bool}
115 */
116 private function getProductDiscoveryStatus(int $formsCount): array {
117 $sentStandard = $this->newslettersRepository->getCountForStatusAndTypes(
118 NewsletterEntity::STATUS_SENT,
119 [NewsletterEntity::TYPE_STANDARD]
120 );
121 $scheduledStandard = $this->newslettersRepository->getCountForStatusAndTypes(
122 NewsletterEntity::STATUS_SCHEDULED,
123 [NewsletterEntity::TYPE_STANDARD]
124 );
125 $activePostNotificationsAndAutomaticEmails = $this->newslettersRepository->getCountForStatusAndTypes(
126 NewsletterEntity::STATUS_ACTIVE,
127 [NewsletterEntity::TYPE_NOTIFICATION, NewsletterEntity::TYPE_AUTOMATIC]
128 );
129 $abandonedCartEmailsCount = $this->newslettersRepository->getCountOfActiveAutomaticEmailsForEvent(AbandonedCart::SLUG);
130 $welcomeEmailsCount = $this->newslettersRepository->getCountForStatusAndTypes(NewsletterEntity::STATUS_ACTIVE, [NewsletterEntity::TYPE_WELCOME]);
131 $welcomeEmailLikeAutomationsCount = $this->automationStorage->getCountOfActiveByTriggerKeysAndAction(
132 [UserRegistrationTrigger::KEY, SomeoneSubscribesTrigger::KEY],
133 SendEmailAction::KEY
134 );
135 return [
136 'setUpWelcomeCampaign' => ($welcomeEmailsCount + $welcomeEmailLikeAutomationsCount) > 0,
137 'addSubscriptionForm' => $formsCount > 0,
138 'sendFirstNewsletter' => ($sentStandard + $scheduledStandard + $activePostNotificationsAndAutomaticEmails) > 0,
139 'setUpAbandonedCartEmail' => $abandonedCartEmailsCount > 0,
140 'brandWooEmails' => (bool)$this->settingsController->get('woocommerce.use_mailpoet_editor', false),
141 ];
142 }
143
144 /**
145 * @return array{canDisplay:bool}
146 */
147 private function getUpsellStatus(int $subscribersCount): array {
148 $hasValidMssKey = $this->subscribersFeature->hasValidMssKey();
149
150 return [
151 'canDisplay' => !$hasValidMssKey && $subscribersCount > self::UPSELL_SUBSCRIBERS_COUNT_REQUIRED,
152 ];
153 }
154
155 /**
156 * This method returns data for subscribers stats statistics section.
157 *
158 * global:
159 * - subscribed: int number of subscribers who were added in last 30 days by checking lastSubscribedAt column and ignoring current global status
160 * - unsubscribed: int number of subscribers who have a record in statistics_unsubscribes table in last 30 days
161 * - changePercent: float ($subscribedSubscribersCount - $subscribedSubscribers30DaysAgo) / $subscribedSubscribers30DaysAgo) * 100
162 *
163 * lists:
164 * - id: int id of the list
165 * - name: string name of the list
166 * - subscribed: int number of subscribers who were added to a list in last 30 days and have both list statuse "subscribed"
167 * - unsubscribed: int number of subscribers who were removed from a list in last 30 (list status is unsubscribed and updated_at is in last 30 days)
168 * - averageEngagementScore: float engagement score of the list
169 *
170 * @return array{global:array{subscribed:int, unsubscribed:int, changePercent:float|int}, lists:array<int, array>}
171 */
172 private function getSubscribersStats(): array {
173 $listData = [];
174 $counts = $this->subscribersCountsController->getHomepageStatistics();
175 $listsDataSubscribed = $counts['listsDataSubscribed'] ?? [];
176 foreach ($listsDataSubscribed as $list) {
177 $listData[$list['id']] = array_intersect_key($list, array_flip(['name', 'id', 'type', 'averageEngagementScore']));
178 $listData[$list['id']]['subscribed'] = $list['count'];
179 $listData[$list['id']]['unsubscribed'] = 0;
180 }
181 $listsDataUnsubscribed = $counts['listsDataUnsubscribed'] ?? [];
182 foreach ($listsDataUnsubscribed as $list) {
183 if (!isset($listData[$list['id']])) {
184 $listData[$list['id']] = array_intersect_key($list, array_flip(['name', 'id', 'type', 'averageEngagementScore']));
185 $listData[$list['id']]['subscribed'] = 0;
186 }
187 $listData[$list['id']]['unsubscribed'] = $list['count'];
188 }
189
190 $subscribedCount = intval($counts['subscribedCount'] ?? 0);
191 $unsubscribedCount = intval($counts['unsubscribedCount'] ?? 0);
192 $subscribedSubscribersCount = intval($counts['subscribedSubscribersCount'] ?? 0);
193 $subscribedSubscribers30DaysAgo = $subscribedSubscribersCount - $subscribedCount + $unsubscribedCount;
194 if ($subscribedSubscribers30DaysAgo > 0) {
195 $globalChangePercent = (($subscribedSubscribersCount - $subscribedSubscribers30DaysAgo) / $subscribedSubscribers30DaysAgo) * 100;
196 if (floor($globalChangePercent) !== (float)$globalChangePercent) {
197 $globalChangePercent = round($globalChangePercent, 1);
198 }
199 } else {
200 $globalChangePercent = $subscribedSubscribersCount * 100;
201 }
202
203 return [
204 'global' => [
205 'subscribed' => $subscribedCount,
206 'unsubscribed' => $unsubscribedCount,
207 'changePercent' => $globalChangePercent,
208 ],
209 'lists' => array_values($listData),
210 ];
211 }
212 }
213