PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.35.1
MailPoet – Newsletters, Email Marketing, and Automation v5.35.1
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 / ManageSubscriptionFormRenderer.php
mailpoet / lib / Subscription Last commit date
AdminUserSubscription.php 3 months ago Blacklist.php 1 year ago Comment.php 3 months ago Form.php 1 month ago Manage.php 3 weeks ago ManageSubscriptionFormRenderer.php 1 day ago Pages.php 3 weeks ago Registration.php 3 months ago SubscriptionUrlFactory.php 3 weeks ago Throttling.php 3 months ago index.php 3 years ago
ManageSubscriptionFormRenderer.php
386 lines
1 <?php declare(strict_types = 1);
2
3 namespace MailPoet\Subscription;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\Config\Renderer as TemplateRenderer;
9 use MailPoet\CustomFields\CustomFieldsRepository;
10 use MailPoet\Entities\CustomFieldEntity;
11 use MailPoet\Entities\SegmentEntity;
12 use MailPoet\Entities\SubscriberEntity;
13 use MailPoet\Form\Block\Date as FormBlockDate;
14 use MailPoet\Form\Renderer as FormRenderer;
15 use MailPoet\Segments\SegmentsRepository;
16 use MailPoet\Settings\SettingsController;
17 use MailPoet\Subscribers\LinkTokens;
18 use MailPoet\Subscribers\TrackingConsentController;
19 use MailPoet\Util\Helpers;
20 use MailPoet\Util\Url as UrlHelper;
21 use MailPoet\WP\Functions as WPFunctions;
22 use MailPoetVendor\Doctrine\Common\Collections\Criteria;
23
24 class ManageSubscriptionFormRenderer {
25 const FORM_STATE_SUCCESS = 'success';
26 const FORM_STATE_ERROR = 'error';
27 const FORM_STATE_NOT_SUBMITTED = 'not_submitted';
28
29 /** @var UrlHelper */
30 private $urlHelper;
31
32 /** @var WPFunctions */
33 private $wp;
34
35 /** @var LinkTokens */
36 private $linkTokens;
37
38 /** @var FormRenderer */
39 private $formRenderer;
40
41 /** @var FormBlockDate */
42 private $dateBlock;
43
44 /** @var TemplateRenderer */
45 private $templateRenderer;
46
47 /** @var CustomFieldsRepository */
48 private $customFieldsRepository;
49
50 /** @var SegmentsRepository */
51 private $segmentsRepository;
52
53 /** @var SettingsController */
54 private $settings;
55
56 /** @var TrackingConsentController */
57 private $trackingConsentController;
58
59 public function __construct(
60 WPFunctions $wp,
61 UrlHelper $urlHelper,
62 LinkTokens $linkTokens,
63 FormRenderer $formRenderer,
64 FormBlockDate $dateBlock,
65 TemplateRenderer $templateRenderer,
66 CustomFieldsRepository $customFieldsRepository,
67 SegmentsRepository $segmentsRepository,
68 SettingsController $settings,
69 TrackingConsentController $trackingConsentController
70 ) {
71 $this->wp = $wp;
72 $this->urlHelper = $urlHelper;
73 $this->linkTokens = $linkTokens;
74 $this->formRenderer = $formRenderer;
75 $this->dateBlock = $dateBlock;
76 $this->templateRenderer = $templateRenderer;
77 $this->customFieldsRepository = $customFieldsRepository;
78 $this->segmentsRepository = $segmentsRepository;
79 $this->settings = $settings;
80 $this->trackingConsentController = $trackingConsentController;
81 }
82
83 public function renderForm(SubscriberEntity $subscriber, string $formState = self::FORM_STATE_NOT_SUBMITTED): string {
84 $isModernStyle = $this->isModernStyle();
85 $basicFields = $this->getBasicFields($subscriber, $isModernStyle);
86 $customFields = $this->getCustomFields($subscriber);
87 $segmentField = $this->getSegmentField($subscriber, $isModernStyle);
88 $submitField = [
89 'id' => 'submit',
90 'type' => 'submit',
91 'params' => [
92 'label' => $isModernStyle ? __('Save changes', 'mailpoet') : __('Save', 'mailpoet'),
93 ],
94 ];
95
96 $form = array_merge(
97 $basicFields,
98 $customFields,
99 [
100 $segmentField,
101 $submitField,
102 ]
103 );
104
105 $filteredForm = $this->wp->applyFilters('mailpoet_manage_subscription_page_form_fields', $form);
106 if (is_array($filteredForm)) {
107 $form = $filteredForm;
108 }
109
110 $templateData = [
111 'actionUrl' => admin_url('admin-post.php'),
112 'redirectUrl' => $this->urlHelper->getCurrentUrl(),
113 'email' => $subscriber->getEmail(),
114 'token' => $this->linkTokens->getToken($subscriber),
115 'editEmailInfo' => __('Need to change your email address? Unsubscribe using the form below, then simply sign up again.', 'mailpoet'),
116 'isModernStyle' => $isModernStyle,
117 'isGloballyUnsubscribed' => $subscriber->getStatus() === SubscriberEntity::STATUS_UNSUBSCRIBED,
118 'formState' => $formState,
119 ];
120
121 if ($isModernStyle) {
122 $formSections = $this->splitFormSections($form);
123 $templateData['identityFieldsHtml'] = $this->formRenderer->renderBlocks($formSections['identityFields'], [], null, $honeypot = false, $captcha = false);
124 $templateData['additionalIdentityFieldsHtml'] = $this->formRenderer->renderBlocks($formSections['additionalIdentityFields'], [], null, $honeypot = false, $captcha = false);
125 $templateData['listFieldsHtml'] = $this->formRenderer->renderBlocks($formSections['listFields'], [], null, $honeypot = false, $captcha = false);
126 $templateData['submitHtml'] = $this->formRenderer->renderBlocks($formSections['submitFields'], [], null, $honeypot = false, $captcha = false);
127 $templateData['hasVisibleLists'] = $formSections['hasVisibleLists'];
128 } else {
129 $templateData['formHtml'] = $this->formRenderer->renderBlocks($form, [], null, $honeypot = false, $captcha = false);
130 }
131
132 if ($subscriber->isWPUser() || $subscriber->getIsWoocommerceUser()) {
133 $wpCurrentUser = $this->wp->wpGetCurrentUser();
134 if ($wpCurrentUser->user_email === $subscriber->getEmail()) { // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
135 $templateData['editEmailInfo'] = Helpers::replaceLinkTags(
136 __('[link]Edit your profile[/link] to update your email.', 'mailpoet'),
137 $this->wp->getEditProfileUrl(),
138 ['target' => '_blank']
139 );
140 } else {
141 $templateData['editEmailInfo'] = Helpers::replaceLinkTags(
142 __('[link]Log in to your account[/link] to update your email.', 'mailpoet'),
143 $this->wp->wpLoginUrl(),
144 ['target' => '_blank']
145 );
146 }
147 }
148
149 return $this->templateRenderer->render('subscription/manage_subscription.html', $templateData);
150 }
151
152 private function isModernStyle(): bool {
153 return $this->settings->get('subscription.manage_subscription_page_style') === SettingsController::MANAGE_SUBSCRIPTION_PAGE_STYLE_MODERN;
154 }
155
156 private function splitFormSections(array $form): array {
157 $identityFields = [];
158 $additionalIdentityFields = [];
159 $listFields = [];
160 $submitFields = [];
161 $hasVisibleLists = false;
162 $placeAdditionalIdentityFieldsAfterNoListNotice = false;
163
164 foreach ($form as $field) {
165 if (!is_array($field)) {
166 continue;
167 }
168 $params = isset($field['params']) && is_array($field['params']) ? $field['params'] : [];
169
170 if (($field['type'] ?? null) === 'submit') {
171 $submitFields[] = $field;
172 continue;
173 }
174
175 if (($field['type'] ?? null) === 'segment' && (($params['display_mode'] ?? null) === 'manage_subscription_choices')) {
176 if (!empty($params['values']) && is_array($params['values'])) {
177 $hasVisibleLists = true;
178 $listFields[] = $field;
179 }
180 continue;
181 }
182
183 if ($placeAdditionalIdentityFieldsAfterNoListNotice) {
184 $additionalIdentityFields[] = $field;
185 } else {
186 $identityFields[] = $field;
187 }
188 if (($field['id'] ?? null) === 'status') {
189 $placeAdditionalIdentityFieldsAfterNoListNotice = true;
190 }
191 }
192
193 return [
194 'identityFields' => $identityFields,
195 'additionalIdentityFields' => $additionalIdentityFields,
196 'listFields' => $listFields,
197 'submitFields' => $submitFields,
198 'hasVisibleLists' => $hasVisibleLists,
199 ];
200 }
201
202 private function getCustomFields(SubscriberEntity $subscriber): array {
203 $customFieldValues = [];
204 foreach ($subscriber->getSubscriberCustomFields() as $subscriberCustomField) {
205 $customField = $subscriberCustomField->getCustomField();
206 if (!$customField) continue;
207
208 $customFieldValues[$customField->getId()] = $subscriberCustomField->getValue();
209 }
210 return array_map(function (CustomFieldEntity $customFieldEntity) use ($customFieldValues) {
211 $customField = [
212 'id' => 'cf_' . $customFieldEntity->getId(),
213 'name' => $customFieldEntity->getName(),
214 'type' => $customFieldEntity->getType(),
215 'params' => $customFieldEntity->getParams(),
216 ];
217
218 $customField['params']['value'] = $customFieldValues[$customFieldEntity->getId()] ?? null;
219
220 if ($customField['type'] === 'date') {
221 $dateFormats = $this->dateBlock->getDateFormats();
222 $customField['params']['date_format'] = array_shift(
223 $dateFormats[$customField['params']['date_type']]
224 );
225 }
226 if (!isset($customField['params']['label'])) {
227 $customField['params']['label'] = $customField['name'];
228 }
229
230 return $customField;
231 }, $this->customFieldsRepository->findAllActive());
232 }
233
234 public static function getTrackingConsentCopy(): string {
235 return __('Allow tracking of email opens and link clicks', 'mailpoet');
236 }
237
238 private function getBasicFields(SubscriberEntity $subscriber, bool $isModernStyle): array {
239 $statusParams = [
240 'required' => true,
241 'label' => $isModernStyle ? __('Email subscription status', 'mailpoet') : __('Status', 'mailpoet'),
242 'values' => [
243 [
244 'value' => [
245 SubscriberEntity::STATUS_SUBSCRIBED => __('Subscribed', 'mailpoet'),
246 ],
247 'is_checked' => (
248 $subscriber->getStatus() === SubscriberEntity::STATUS_SUBSCRIBED
249 ),
250 ],
251 [
252 'value' => [
253 SubscriberEntity::STATUS_UNSUBSCRIBED => __('Unsubscribed', 'mailpoet'),
254 ],
255 'is_checked' => (
256 $subscriber->getStatus() === SubscriberEntity::STATUS_UNSUBSCRIBED
257 ),
258 ],
259 [
260 'value' => [
261 SubscriberEntity::STATUS_BOUNCED => __('Bounced', 'mailpoet'),
262 ],
263 'is_checked' => (
264 $subscriber->getStatus() === SubscriberEntity::STATUS_BOUNCED
265 ),
266 'is_disabled' => true,
267 'is_hidden' => (
268 $subscriber->getStatus() !== SubscriberEntity::STATUS_BOUNCED
269 ),
270 ],
271 [
272 'value' => [
273 SubscriberEntity::STATUS_INACTIVE => __('Inactive', 'mailpoet'),
274 ],
275 'is_checked' => (
276 $subscriber->getStatus() === SubscriberEntity::STATUS_INACTIVE
277 ),
278 'is_hidden' => (
279 $subscriber->getStatus() !== SubscriberEntity::STATUS_INACTIVE
280 ),
281 ],
282 ],
283 ];
284 if ($isModernStyle) {
285 $statusParams['description'] = __('This controls whether you receive emails overall. Your list choices below control which public lists you receive.', 'mailpoet');
286 $statusParams['class_name'] = 'mailpoet-manage-subscription-status';
287 $statusParams['input_id'] = 'mailpoet_manage_subscription_status';
288 }
289
290 $fields = [
291 [
292 'id' => 'first_name',
293 'type' => 'text',
294 'params' => [
295 'label' => __('First name', 'mailpoet'),
296 'value' => $subscriber->getFirstName(),
297 'disabled' => ($subscriber->isWPUser() || $subscriber->getIsWoocommerceUser()),
298 ],
299 ],
300 [
301 'id' => 'last_name',
302 'type' => 'text',
303 'params' => [
304 'label' => __('Last name', 'mailpoet'),
305 'value' => $subscriber->getLastName(),
306 'disabled' => ($subscriber->isWPUser() || $subscriber->getIsWoocommerceUser()),
307 ],
308 ],
309 [
310 'id' => 'status',
311 'type' => 'select',
312 'params' => $statusParams,
313 ],
314 ];
315
316 // Only sites that asked subscribers to choose show a tracking control. A
317 // site that tracks everyone never exposes one, so nobody is prompted to
318 // opt out of something the site owner never offered.
319 if ($this->trackingConsentController->areSubscriberControlsVisible()) {
320 $fields[] = [
321 'id' => 'tracking_consent',
322 'type' => 'checkbox',
323 'params' => [
324 'label' => __('Email activity tracking', 'mailpoet'),
325 'values' => [
326 [
327 'value' => self::getTrackingConsentCopy(),
328 'is_checked' => $subscriber->getTrackingConsent() === SubscriberEntity::TRACKING_CONSENT_GRANTED,
329 ],
330 ],
331 ],
332 ];
333 }
334
335 return $fields;
336 }
337
338 private function getSegmentField(SubscriberEntity $subscriber, bool $isModernStyle): array {
339 // Get default segments
340 $criteria = [
341 'type' => SegmentEntity::TYPE_DEFAULT,
342 'deletedAt' => null,
343 'displayInManageSubscriptionPage' => true,
344 ];
345 $segments = $this->segmentsRepository->findBy($criteria, ['name' => Criteria::ASC]);
346
347 $subscribedSegmentIds = [];
348 foreach ($subscriber->getSubscriberSegments() as $subscriberSegment) {
349 $segment = $subscriberSegment->getSegment();
350 if (!$segment) continue;
351
352 if ($subscriberSegment->getStatus() === SubscriberEntity::STATUS_SUBSCRIBED) {
353 $subscribedSegmentIds[] = $segment->getId();
354 }
355 }
356
357 $segments = array_map(function (SegmentEntity $segment) use ($subscribedSegmentIds, $isModernStyle) {
358 $segmentData = [
359 'id' => $segment->getId(),
360 'name' => $segment->getName(),
361 'is_checked' => in_array($segment->getId(), $subscribedSegmentIds),
362 ];
363 if ($isModernStyle) {
364 $segmentData['public_description'] = $segment->getPublicDescription();
365 }
366 return $segmentData;
367 }, $segments);
368
369 $params = [
370 'label' => __('Your lists', 'mailpoet'),
371 'class_name' => 'mailpoet-manage-subscription-list-fields',
372 'values' => $segments,
373 ];
374 if ($isModernStyle) {
375 $params['description'] = __('Choose Yes for lists you want to receive and No for lists you do not want to receive.', 'mailpoet');
376 $params['display_mode'] = 'manage_subscription_choices';
377 }
378
379 return [
380 'id' => 'segments',
381 'type' => 'segment',
382 'params' => $params,
383 ];
384 }
385 }
386