PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.33.1
MailPoet – Newsletters, Email Marketing, and Automation v5.33.1
5.37.0 5.36.1 5.36.0 5.35.1 5.35.0 5.34.3 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 / Router / Endpoints / Subscription.php
mailpoet / lib / Router / Endpoints Last commit date
Captcha.php 5 months ago CronDaemon.php 3 years ago ExportDownload.php 3 months ago FormPreview.php 2 years ago Subscription.php 3 months ago TemplateImage.php 3 months ago Track.php 3 months ago ViewInBrowser.php 2 months ago index.php 3 years ago
Subscription.php
157 lines
1 <?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
2
3 namespace MailPoet\Router\Endpoints;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\Config\AccessControl;
9 use MailPoet\Entities\StatisticsUnsubscribeEntity;
10 use MailPoet\Subscription as UserSubscription;
11 use MailPoet\Util\Request;
12 use MailPoet\WP\Functions as WPFunctions;
13
14 class Subscription {
15 const ENDPOINT = 'subscription';
16 const ACTION_CONFIRM = 'confirm';
17 const ACTION_MANAGE = 'manage';
18 const ACTION_UNSUBSCRIBE = 'unsubscribe';
19 const ACTION_UNSUBSCRIBE_REASON = 'unsubscribeReason';
20 const ACTION_CONFIRM_UNSUBSCRIBE = 'confirmUnsubscribe';
21 const ACTION_RE_ENGAGEMENT = 'reEngagement';
22
23 public $allowedActions = [
24 self::ACTION_CONFIRM,
25 self::ACTION_MANAGE,
26 self::ACTION_UNSUBSCRIBE,
27 self::ACTION_UNSUBSCRIBE_REASON,
28 self::ACTION_CONFIRM_UNSUBSCRIBE,
29 self::ACTION_RE_ENGAGEMENT,
30 ];
31
32 public $permissions = [
33 'global' => AccessControl::NO_ACCESS_RESTRICTION,
34 ];
35
36 /** @var UserSubscription\Pages */
37 private $subscriptionPages;
38
39 /** @var WPFunctions */
40 private $wp;
41
42 /*** @var Request */
43 private $request;
44
45 public function __construct(
46 UserSubscription\Pages $subscriptionPages,
47 WPFunctions $wp,
48 Request $request
49 ) {
50 $this->subscriptionPages = $subscriptionPages;
51 $this->wp = $wp;
52 $this->request = $request;
53 }
54
55 public function confirm($data) {
56 $subscription = $this->initSubscriptionPage(UserSubscription\Pages::ACTION_CONFIRM, $data);
57 $subscription->confirm();
58 }
59
60 public function confirmUnsubscribe($data) {
61 $enableUnsubscribeConfirmation = $this->wp->applyFilters('mailpoet_unsubscribe_confirmation_enabled', true);
62 if ($this->isPostRequest()) {
63 $this->performUnsubscribe($data, StatisticsUnsubscribeEntity::METHOD_ONE_CLICK);
64 exit;
65 }
66
67 if ($enableUnsubscribeConfirmation) {
68 $this->initSubscriptionPage(UserSubscription\Pages::ACTION_CONFIRM_UNSUBSCRIBE, $data);
69 } else {
70 $this->performUnsubscribe($data, StatisticsUnsubscribeEntity::METHOD_LINK);
71 }
72 }
73
74 public function manage($data) {
75 $this->initSubscriptionPage(UserSubscription\Pages::ACTION_MANAGE, $data);
76 }
77
78 public function unsubscribe($data) {
79 if ($this->isPostRequest()) {
80 if ($this->request->getStringParam('type') === 'confirmation') {
81 // POST from confirmation page
82 $this->performUnsubscribe($data, StatisticsUnsubscribeEntity::METHOD_LINK);
83 } else {
84 // POST from one click unsubscribe
85 $this->performUnsubscribe($data, StatisticsUnsubscribeEntity::METHOD_ONE_CLICK);
86 exit;
87 }
88 } else {
89 // For GET requests, we render the confirmUnsubscribe page, unless it is preview request of successful unsubscribe
90 // or the subscriber is already unsubscribed.
91 if (isset($data['preview']) && $data['preview'] && !isset($data['token'])) {
92 $this->performUnsubscribe($data, StatisticsUnsubscribeEntity::METHOD_LINK);
93 } elseif ($this->renderUnsubscribePageForAlreadyUnsubscribedSubscriber($data)) {
94 return;
95 } else {
96 $this->confirmUnsubscribe($data);
97 }
98 }
99 }
100
101 public function unsubscribeReason($data) {
102 if (!$this->request->isPost()) {
103 $this->wp->wpSafeRedirect($this->wp->homeUrl());
104 exit;
105 }
106
107 $nonce = $this->request->getStringParam('_wpnonce');
108 if (!$this->wp->wpVerifyNonce($nonce, 'mailpoet_unsubscribe_reason')) {
109 $this->wp->wpDie(__('Security check failed.', 'mailpoet'), '', ['response' => 403]);
110 exit;
111 }
112
113 $subscription = $this->initSubscriptionPage(UserSubscription\Pages::ACTION_UNSUBSCRIBE, $data);
114 $reason = strtolower($this->wp->sanitizeKey((string)$this->request->getStringParam('reason')));
115 $reasonText = $this->request->getTextareaParam('reason_text');
116
117 $saved = $reason !== '' && $subscription->saveUnsubscribeReason($reason, $reasonText);
118 $this->wp->wpSafeRedirect($subscription->getUnsubscribeReasonRedirectUrl($saved));
119 exit;
120 }
121
122 public function reEngagement($data) {
123 $this->initSubscriptionPage(UserSubscription\Pages::ACTION_RE_ENGAGEMENT, $data);
124 }
125
126 private function initSubscriptionPage($action, $data) {
127 return $this->subscriptionPages->init($action, $data, true, true);
128 }
129
130 private function renderUnsubscribePageForAlreadyUnsubscribedSubscriber($data): bool {
131 $subscription = $this->subscriptionPages->init(UserSubscription\Pages::ACTION_UNSUBSCRIBE, $data, false, false);
132 if (!$subscription->isSubscriberUnsubscribed()) {
133 return false;
134 }
135
136 $this->initSubscriptionPage(UserSubscription\Pages::ACTION_UNSUBSCRIBE, $data);
137 return true;
138 }
139
140 private function performUnsubscribe($data, string $method): void {
141 $subscription = $this->initSubscriptionPage(UserSubscription\Pages::ACTION_UNSUBSCRIBE, $data);
142 $subscription->unsubscribe($method);
143 }
144
145 private function isPostRequest(): bool {
146 if ($this->request->isPost()) {
147 return true;
148 }
149 // For tracking redirects we store original method in the query string
150 $requestMethod = $this->request->getStringParam('request_method');
151 if (!$requestMethod) {
152 return false;
153 }
154 return strtoupper($requestMethod) === 'POST';
155 }
156 }
157