PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.37.0
MailPoet – Newsletters, Email Marketing, and Automation v5.37.0
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 / Subscription / Registration.php
mailpoet / lib / Subscription Last commit date
AdminUserSubscription.php 3 months ago Blacklist.php 1 year ago Comment.php 1 day ago Form.php 1 month ago Manage.php 1 month ago ManageSubscriptionFormRenderer.php 3 weeks ago Pages.php 1 week ago Registration.php 1 day ago SubscriptionUrlFactory.php 1 month ago Throttling.php 3 months ago index.php 3 years ago
Registration.php
225 lines
1 <?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
2
3 namespace MailPoet\Subscription;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\Entities\SubscriberEntity;
9 use MailPoet\Segments\WP as WPSegment;
10 use MailPoet\Settings\SettingsController;
11 use MailPoet\Statistics\Track\SubscriberHandler;
12 use MailPoet\Subscribers\SubscriberActions;
13 use MailPoet\Subscribers\SubscribersRepository;
14 use MailPoet\Subscribers\TrackingConsentCapture;
15 use MailPoet\WP\Functions as WPFunctions;
16
17 class Registration {
18
19 /** @var SettingsController */
20 private $settings;
21
22 /** @var SubscriberActions */
23 private $subscriberActions;
24
25 /** @var WPFunctions */
26 private $wp;
27
28 /** @var SubscriberHandler */
29 private $subscriberHandler;
30
31 /** @var TrackingConsentCapture */
32 private $trackingConsentCapture;
33
34 /** @var SubscribersRepository */
35 private $subscribersRepository;
36
37 /** @var WPSegment */
38 private $wpSegment;
39
40 public function __construct(
41 SettingsController $settings,
42 WPFunctions $wp,
43 SubscriberActions $subscriberActions,
44 SubscriberHandler $subscriberHandler,
45 TrackingConsentCapture $trackingConsentCapture,
46 SubscribersRepository $subscribersRepository,
47 WPSegment $wpSegment
48 ) {
49 $this->settings = $settings;
50 $this->subscriberActions = $subscriberActions;
51 $this->wp = $wp;
52 $this->subscriberHandler = $subscriberHandler;
53 $this->trackingConsentCapture = $trackingConsentCapture;
54 $this->subscribersRepository = $subscribersRepository;
55 $this->wpSegment = $wpSegment;
56 }
57
58 public function extendForm() {
59 $label = $this->settings->get(
60 'subscribe.on_register.label',
61 __('Yes, please add me to your mailing list.', 'mailpoet')
62 );
63
64 $form = '<p class="registration-form-mailpoet">
65 <label for="mailpoet_subscribe_on_register">
66 <input
67 type="hidden"
68 id="mailpoet_subscribe_on_register_active"
69 value="1"
70 name="mailpoet[subscribe_on_register_active]"
71 />
72 <input
73 type="checkbox"
74 id="mailpoet_subscribe_on_register"
75 value="1"
76 name="mailpoet[subscribe_on_register]"
77 />&nbsp;' . esc_html($label) . '
78 </label>
79 </p>' . $this->getTrackingConsentField();
80
81 $filtered = $this->wp->applyFilters('mailpoet_register_form_extend', $form);
82 $form = is_string($filtered) ? $filtered : $form;
83
84 // We control the template and $form can be considered safe.
85 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
86 echo $form;
87 }
88
89 public function onMultiSiteRegister($result) {
90 if (empty($result['errors']->errors)) {
91 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- type narrowing only, value is read as bool
92 $mailpoetPost = isset($_POST['mailpoet']) && is_array($_POST['mailpoet']) ? $_POST['mailpoet'] : [];
93 if (
94 isset($mailpoetPost['subscribe_on_register'])
95 && (bool)$mailpoetPost['subscribe_on_register'] === true
96 && !empty($result['user_email'])
97 ) {
98 $this->subscribeNewUser(
99 $result['user_name'],
100 $result['user_email'],
101 !empty($mailpoetPost['tracking_consent'])
102 );
103 }
104 }
105 return $result;
106 }
107
108 public function onRegister(
109 $errors,
110 $userLogin,
111 $userEmail = null
112 ) {
113 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- type narrowing only, value is read as bool
114 $mailpoetPost = isset($_POST['mailpoet']) && is_array($_POST['mailpoet']) ? $_POST['mailpoet'] : [];
115 if (
116 empty($errors->errors)
117 && isset($mailpoetPost['subscribe_on_register'])
118 && (bool)$mailpoetPost['subscribe_on_register'] === true
119 && !empty($userEmail)
120 ) {
121 $this->subscribeNewUser(
122 $userLogin,
123 $userEmail,
124 !empty($mailpoetPost['tracking_consent'])
125 );
126 }
127 return $errors;
128 }
129
130 /**
131 * A second, independent checkbox. Consent to open and click tracking is never
132 * inferred from the "add me to your mailing list" box above it, and it is
133 * only shown on sites that chose to ask. Never pre-ticked: a pre-ticked
134 * consent box is not valid consent (CJEU Planet49).
135 */
136
137 /**
138 * Hooked on user_register, after the WP-user sync has created or updated the
139 * subscriber row for every new WP user, whether or not "add me to your
140 * mailing list" was ticked. That is the gap this closes:
141 * onRegister()/onMultiSiteRegister() only read tracking_consent inside the
142 * subscribe branch, so someone who allowed tracking without subscribing had
143 * their answer thrown away. Covers single-site, multisite and WooCommerce
144 * registration alike, since all three create the WP user and fire this hook.
145 */
146 public function applyTrackingConsentOnUserRegister(int $userId): void {
147 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- type narrowing only, the value is read as a bool
148 $mailpoetPost = isset($_POST['mailpoet']) && is_array($_POST['mailpoet']) ? $_POST['mailpoet'] : [];
149 if (!isset($mailpoetPost['tracking_consent'])) {
150 return;
151 }
152 $wpUser = $this->wp->getUserdata($userId);
153 if (!$wpUser || empty($wpUser->user_email)) { // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
154 return;
155 }
156 $subscriber = $this->subscribersRepository->findOneBy(
157 ['email' => $wpUser->user_email] // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
158 );
159 if (!$subscriber instanceof SubscriberEntity) {
160 return;
161 }
162 $method = SubscriberEntity::TRACKING_CONSENT_METHOD_REGISTRATION;
163 $this->trackingConsentCapture->applyToSubscriber(
164 $subscriber,
165 !empty($mailpoetPost['tracking_consent']),
166 $method,
167 $this->trackingConsentCapture->getCopy($method),
168 $this->wpSegment->wasSubscriberCreatedBySync($userId)
169 );
170 $this->subscribersRepository->flush();
171 }
172
173 private function getTrackingConsentField(): string {
174 if (!$this->trackingConsentCapture->isCaptureEnabled()) {
175 return '';
176 }
177 $copy = $this->trackingConsentCapture->getCopy(
178 SubscriberEntity::TRACKING_CONSENT_METHOD_REGISTRATION
179 );
180
181 return '<p class="registration-form-mailpoet-tracking-consent">
182 <label for="mailpoet_tracking_consent">
183 <input
184 type="checkbox"
185 id="mailpoet_tracking_consent"
186 value="1"
187 name="mailpoet[tracking_consent]"
188 />&nbsp;' . esc_html($copy) . '
189 </label>
190 </p>';
191 }
192
193 private function subscribeNewUser($name, $email, bool $trackingConsent = false) {
194 $segmentIds = $this->settings->get(
195 'subscribe.on_register.segments',
196 []
197 );
198 $method = SubscriberEntity::TRACKING_CONSENT_METHOD_REGISTRATION;
199 $consentData = $this->trackingConsentCapture->getConsentData(
200 $trackingConsent,
201 $method,
202 $this->trackingConsentCapture->getCopy($method),
203 $this->trackingConsentCapture->isNewSubscriber($email)
204 );
205
206 $this->subscriberActions->subscribe(
207 array_merge([
208 'email' => $email,
209 'first_name' => $name,
210 ], $consentData),
211 $segmentIds
212 );
213
214
215 /**
216 * On multisite headers are already sent at this point, tracking will start
217 * once the user has activated his account at a later stage.
218 **/
219 if (!headers_sent()) {
220 // start subscriber tracking (by email, we don't have WP user ID yet)
221 $this->subscriberHandler->identifyByEmail($email);
222 }
223 }
224 }
225