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 / Statistics / Track / SubscriberActivityTracker.php
mailpoet / lib / Statistics / Track Last commit date
Clicks.php 5 days ago Opens.php 5 days ago PageViewCookie.php 2 months ago SubscriberActivityTracker.php 5 days ago SubscriberCookie.php 2 months ago SubscriberHandler.php 1 year ago Unsubscribes.php 2 months ago WooCommercePurchases.php 2 years ago index.php 3 years ago
SubscriberActivityTracker.php
156 lines
1 <?php declare(strict_types = 1);
2
3 namespace MailPoet\Statistics\Track;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\Entities\SubscriberEntity;
9 use MailPoet\Settings\TrackingConfig;
10 use MailPoet\Subscribers\SubscribersRepository;
11 use MailPoet\WooCommerce\Helper as WooCommerceHelper;
12 use MailPoet\WP\Functions as WPFunctions;
13 use MailPoetVendor\Doctrine\DBAL\Exception\InvalidFieldNameException;
14 use MailPoetVendor\Doctrine\DBAL\Exception\TableNotFoundException;
15
16 class SubscriberActivityTracker {
17
18 const TRACK_INTERVAL = 60; // 1 minute
19
20 /** @var PageViewCookie */
21 private $pageViewCookie;
22
23 /** @var SubscriberCookie */
24 private $subscriberCookie;
25
26 /** @var SubscribersRepository */
27 private $subscribersRepository;
28
29 /** @var WPFunctions */
30 private $wp;
31
32 /** @var TrackingConfig */
33 private $trackingConfig;
34
35 /** @var callable[] */
36 private $callbacks = [];
37
38 /** @var WooCommerceHelper */
39 private $wooCommerceHelper;
40
41 public function __construct(
42 PageViewCookie $pageViewCookie,
43 SubscriberCookie $subscriberCookie,
44 SubscribersRepository $subscribersRepository,
45 WPFunctions $wp,
46 WooCommerceHelper $wooCommerceHelper,
47 TrackingConfig $trackingConfig
48 ) {
49 $this->pageViewCookie = $pageViewCookie;
50 $this->subscriberCookie = $subscriberCookie;
51 $this->subscribersRepository = $subscribersRepository;
52 $this->wp = $wp;
53 $this->wooCommerceHelper = $wooCommerceHelper;
54 $this->trackingConfig = $trackingConfig;
55 }
56
57 public function trackActivity(): bool {
58 // Don't track in admin interface
59 if ($this->wp->isAdmin()) {
60 return false;
61 }
62
63 $subscriber = null;
64 $latestTimestamp = $this->getLatestTimestampFromCookie();
65
66 // If cookie tracking is not allowed try use last activity from subscriber data
67 if ($latestTimestamp === null) {
68 $subscriber = $this->getSubscriber();
69 if (!$subscriber) {
70 return false; // Can't determine timestamp
71 }
72 $latestTimestamp = $this->getLatestTimestampFromSubscriber($subscriber);
73 }
74
75 if ($latestTimestamp + self::TRACK_INTERVAL > $this->wp->currentTime('timestamp', true)) {
76 return false;
77 }
78
79 if ($subscriber === null) {
80 $subscriber = $this->getSubscriber();
81 }
82
83 if (!$subscriber) {
84 return false;
85 }
86
87 $this->processTracking($subscriber);
88 return true;
89 }
90
91 public function registerCallback(string $slug, callable $callback): void {
92 $this->callbacks[$slug] = $callback;
93 }
94
95 public function unregisterCallback(string $slug): void {
96 unset($this->callbacks[$slug]);
97 }
98
99 private function processTracking(SubscriberEntity $subscriber): void {
100 $this->subscribersRepository->maybeUpdateLastPageViewAt($subscriber);
101 $this->pageViewCookie->setPageViewTimestamp($this->wp->currentTime('timestamp', true));
102 foreach ($this->callbacks as $callback) {
103 $callback($subscriber);
104 }
105 }
106
107 private function getLatestTimestampFromCookie(): ?int {
108 if ($this->trackingConfig->isCookieTrackingEnabled()) {
109 return $this->pageViewCookie->getPageViewTimestamp() ?? 0;
110 }
111 return null;
112 }
113
114 private function getLatestTimestampFromSubscriber(SubscriberEntity $subscriber): int {
115 return $subscriber->getLastEngagementAt() ? $subscriber->getLastEngagementAt()->getTimestamp() : 0;
116 }
117
118 private function getSubscriber(): ?SubscriberEntity {
119 try {
120 return $this->findSubscriber();
121 } catch (InvalidFieldNameException | TableNotFoundException $e) {
122 // The subscribers schema may be mid-migration during a plugin update (e.g. the
123 // tracking_consent column added in STOMAIL-8268). Skip activity tracking for this
124 // request rather than aborting Initializer::initialize(), which would take the whole
125 // mailpoet/v1 REST namespace down with it. Tracking resumes on the next request once
126 // the migration completes.
127 return null;
128 }
129 }
130
131 private function findSubscriber(): ?SubscriberEntity {
132 $wpUser = $this->wp->wpGetCurrentUser();
133 if ($wpUser->exists()) {
134 return $this->subscribersRepository->findOneBy(['wpUserId' => $wpUser->ID]);
135 }
136
137 $subscriberId = $this->subscriberCookie->getSubscriberId();
138 if ($subscriberId) {
139 return $this->subscribersRepository->findOneById($subscriberId);
140 }
141
142 if (!$this->wooCommerceHelper->isWooCommerceActive()) {
143 return null;
144 }
145 $wooCommerce = $this->wooCommerceHelper->WC();
146 if (!$wooCommerce || !$wooCommerce->session) {
147 return null;
148 }
149 $customer = $wooCommerce->session->get('customer');
150 if (!is_array($customer) || empty($customer['email'])) {
151 return null;
152 }
153 return $this->subscribersRepository->findOneBy(['email' => $customer['email']]);
154 }
155 }
156