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 / Captcha / CaptchaFormRenderer.php
mailpoet / lib / Captcha Last commit date
Validator 1 month ago BehavioralSignals.php 1 month ago CaptchaConstants.php 2 months ago CaptchaFormRenderer.php 2 weeks ago CaptchaHooks.php 2 months ago CaptchaPhrase.php 1 year ago CaptchaRenderer.php 4 months ago CaptchaSession.php 1 year ago CaptchaUrlFactory.php 4 months ago PageRenderer.php 5 months ago ReCaptchaHooks.php 2 months ago ReCaptchaRenderer.php 1 year ago ReCaptchaValidator.php 1 year ago TurnstileHooks.php 2 months ago TurnstileRenderer.php 2 months ago TurnstileValidator.php 2 months ago index.php 1 year ago
CaptchaFormRenderer.php
245 lines
1 <?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
2
3 namespace MailPoet\Captcha;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\Config\Env;
9 use MailPoet\Entities\FormEntity;
10 use MailPoet\Form\FormsRepository;
11 use MailPoet\Form\Renderer as FormRenderer;
12 use MailPoet\Form\Util\Styles;
13 use MailPoet\Util\Url as UrlHelper;
14 use MailPoet\WP\Functions as WPFunctions;
15
16 class CaptchaFormRenderer {
17 /** @var UrlHelper */
18 private $urlHelper;
19
20 /** @var CaptchaSession */
21 private $captchaSession;
22
23 /** @var CaptchaPhrase */
24 private $captchaPhrase;
25
26 /** @var CaptchaUrlFactory */
27 private $captchaUrlFactory;
28
29 /** @var FormRenderer */
30 private $formRenderer;
31
32 /** @var FormsRepository */
33 private $formsRepository;
34
35 /** @var Styles */
36 private $styles;
37
38 private $wp;
39
40 public function __construct(
41 UrlHelper $urlHelper,
42 CaptchaSession $captchaSession,
43 CaptchaPhrase $captchaPhrase,
44 CaptchaUrlFactory $urlFactory,
45 FormsRepository $formsRepository,
46 FormRenderer $formRenderer,
47 Styles $styles,
48 WPFunctions $wp
49 ) {
50 $this->urlHelper = $urlHelper;
51 $this->captchaSession = $captchaSession;
52 $this->captchaPhrase = $captchaPhrase;
53 $this->captchaUrlFactory = $urlFactory;
54 $this->formRenderer = $formRenderer;
55 $this->formsRepository = $formsRepository;
56 $this->styles = $styles;
57 $this->wp = $wp;
58 }
59
60 public function render(array $data) {
61 $sessionId = (isset($data['captcha_session_id']) && is_string($data['captcha_session_id']))
62 ? $data['captcha_session_id']
63 : null;
64
65 if (!$sessionId) {
66 return false;
67 }
68
69 $ref = $data['referrer_form'] ?? null;
70 if ($ref === CaptchaUrlFactory::REFERER_MP_FORM) {
71 return $this->renderFormInSubscriptionForm($sessionId);
72 } elseif ($ref === CaptchaUrlFactory::REFERER_WP_FORM) {
73 return $this->renderFormInWPRegisterForm($data, 'wp-submit');
74 } elseif ($ref === CaptchaUrlFactory::REFERER_WC_FORM) {
75 return $this->renderFormInWPRegisterForm($data, 'register');
76 }
77
78 return false;
79 }
80
81 private function renderFormInSubscriptionForm($sessionId) {
82 $captchaSessionForm = $this->captchaSession->getFormData($sessionId);
83 $showSuccessMessage = !empty($_GET['mailpoet_success']);
84 $showErrorMessage = !empty($_GET['mailpoet_error']);
85
86 $formId = 0;
87 if (isset($captchaSessionForm['form_id']) && is_numeric($captchaSessionForm['form_id'])) {
88 $formId = (int)$captchaSessionForm['form_id'];
89 } elseif ($showSuccessMessage && is_numeric($_GET['mailpoet_success'])) {
90 $formId = (int)$_GET['mailpoet_success'];
91 } elseif ($showErrorMessage && is_numeric($_GET['mailpoet_error'])) {
92 $formId = (int)$_GET['mailpoet_error'];
93 }
94
95 $formModel = $this->formsRepository->findOneById($formId);
96 if (!$formModel instanceof FormEntity) {
97 return false;
98 } elseif ($showSuccessMessage) {
99 // Display a success message in a no-JS flow
100 return $this->renderFormMessages($formModel, true);
101 }
102
103 $redirectUrl = $this->urlHelper->getCurrentUrl();
104 $hiddenFields = '<input type="hidden" name="data[form_id]" value="' . $this->wp->escAttr($formId) . '" />';
105 $hiddenFields .= '<input type="hidden" name="data[captcha_session_id]" value="' . $this->wp->escAttr($sessionId) . '" />';
106 $hiddenFields .= '<input type="hidden" name="api_version" value="v1" />';
107 $hiddenFields .= '<input type="hidden" name="endpoint" value="subscribers" />';
108 $hiddenFields .= '<input type="hidden" name="mailpoet_method" value="subscribe" />';
109 $hiddenFields .= '<input type="hidden" name="mailpoet_redirect" value="' . $this->wp->escUrl($redirectUrl) . '" />';
110 $hiddenFields .= '<input type="hidden" name="token" value="' . $this->wp->escAttr($this->wp->wpCreateNonce('mailpoet_token')) . '" />';
111
112 $actionUrl = admin_url('admin-post.php?action=mailpoet_subscription_form');
113
114 $submitBlocks = $formModel->getBlocksByTypes(['submit']);
115 $submitLabel = count($submitBlocks) && $submitBlocks[0]['params']['label']
116 ? $submitBlocks[0]['params']['label']
117 : __('Subscribe', 'mailpoet');
118
119 $afterSubmitElement = $this->renderFormMessages($formModel, false, $showErrorMessage);
120
121 $styles = $this->styles->renderFormMessageStyles($formModel, '#mailpoet_captcha_form');
122 $styles = '<style>' . $styles . '</style>';
123
124 return $this->renderForm($sessionId, $hiddenFields, $actionUrl, $submitLabel, $afterSubmitElement, $styles);
125 }
126
127 private function renderFormInWPRegisterForm(array $data, string $submitLabelKey) {
128 $sessionId = $data['captcha_session_id'];
129
130 unset($data['captcha_session_id']);
131 // The 'name' attr is required in this format for the refresh button to work
132 $hiddenFields = '<input type="hidden" name="data[captcha_session_id]" value="' . $this->wp->escAttr($sessionId) . '" />';
133
134 $actionUrl = $data['referrer_form_url'];
135 unset($data['referrer_form_url']);
136
137 unset($data['referrer_form']);
138 foreach ($data as $key => $value) {
139 if (!is_scalar($value)) continue;
140 $hiddenFields .= '<input type="hidden" name="' . $this->wp->escAttr($key) . '" value="' . $this->wp->escAttr($value) . '" />';
141 }
142
143 $submitLabel = $data[$submitLabelKey] ?? esc_attr_e('Register'); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
144
145 return $this->renderForm($sessionId, $hiddenFields, $actionUrl, $submitLabel);
146 }
147
148 private function renderForm(
149 $sessionId,
150 $hiddenFields,
151 $actionUrl,
152 $submitLabel,
153 $afterSubmitElement = null,
154 $styles = null
155 ) {
156 $this->captchaPhrase->createPhrase($sessionId);
157
158 $fields = [
159 [
160 'id' => 'captcha',
161 'type' => 'text',
162 'params' => [
163 'label' => __('Type in the characters you see in the picture above:', 'mailpoet'),
164 'value' => '',
165 'obfuscate' => false,
166 ],
167 ],
168 ];
169
170 $form = array_merge(
171 $fields,
172 [
173 [
174 'id' => 'submit',
175 'type' => 'submit',
176 'params' => [
177 'label' => $submitLabel,
178 ],
179 ],
180 ],
181 );
182
183 if ($afterSubmitElement) {
184 // The 'mailpoet_form' class alter the form's submission behavior
185 // Refer to mailpoet/assets/js/src/public.tsx
186 $classes = 'mailpoet_form mailpoet_captcha_form';
187 } else {
188 $classes = 'mailpoet_captcha_form';
189 }
190
191 $formHtml = '<form method="POST" action="' . $this->wp->escUrl($actionUrl) . '" class="' . $this->wp->escAttr($classes) . '" id="mailpoet_captcha_form" novalidate>';
192 $formHtml .= $hiddenFields;
193
194 $width = CaptchaRenderer::DEFAULT_WIDTH;
195 $height = CaptchaRenderer::DEFAULT_HEIGHT;
196 $captchaUrl = $this->captchaUrlFactory->getCaptchaImageUrl($sessionId);
197 $mp3CaptchaUrl = $this->captchaUrlFactory->getCaptchaAudioUrl($sessionId);
198 $reloadIcon = Env::$assetsUrl . '/img/icons/image-rotate.svg';
199 $playIcon = Env::$assetsUrl . '/img/icons/controls-volumeon.svg';
200
201 $formHtml .= '<div class="mailpoet_form_hide_on_success">';
202 $formHtml .= '<p class="mailpoet_paragraph">';
203 $formHtml .= '<img class="mailpoet_captcha" src="' . $this->wp->escUrl($captchaUrl) . '" width="' . $this->wp->escAttr($width) . '" height="' . $this->wp->escAttr($height) . '" title="' . esc_attr__('CAPTCHA', 'mailpoet') . '" />';
204 $formHtml .= '</p>';
205 $formHtml .= '<button type="button" class="mailpoet_icon_button mailpoet_captcha_update" title="' . esc_attr(__('Reload CAPTCHA', 'mailpoet')) . '"><img src="' . $this->wp->escUrl($reloadIcon) . '" alt="" /></button>';
206 $formHtml .= '<button type="button" class="mailpoet_icon_button mailpoet_captcha_audio" title="' . esc_attr(__('Play CAPTCHA', 'mailpoet')) . '"><img src="' . $this->wp->escUrl($playIcon) . '" alt="" /></button>';
207 $formHtml .= '<audio class="mailpoet_captcha_player">';
208 $formHtml .= '<source src="' . $this->wp->escUrl($mp3CaptchaUrl) . '" type="audio/mpeg">';
209 $formHtml .= '</audio>';
210
211 $formHtml .= $this->formRenderer->renderBlocks($form, [], null, $honeypot = false);
212 $formHtml .= '</div>';
213
214 if ($afterSubmitElement) {
215 $formHtml .= $afterSubmitElement;
216 }
217
218 $formHtml .= '</form>';
219
220 if ($styles) {
221 $formHtml .= $styles;
222 }
223
224 return $formHtml;
225 }
226
227 private function renderFormMessages(
228 FormEntity $formModel,
229 $showSuccessMessage = false,
230 $showErrorMessage = false
231 ) {
232 $settings = $formModel->getSettings() ?? [];
233 $errorMessage = __('The characters you entered did not match the CAPTCHA image. Please try again with this new image.', 'mailpoet');
234
235 $success = isset($settings['success_message']) ? (string)$settings['success_message'] : '';
236
237 $formHtml = '<div class="mailpoet_message" role="alert" aria-live="assertive">';
238 $formHtml .= '<p class="mailpoet_validate_success" ' . ($showSuccessMessage ? '' : ' style="display:none;"') . '>' . $this->wp->escHtml($success) . '</p>';
239 $formHtml .= '<p class="mailpoet_validate_error" ' . ($showErrorMessage ? '' : ' style="display:none;"') . '>' . $this->wp->escHtml($errorMessage) . '</p>';
240 $formHtml .= '</div>';
241
242 return $formHtml;
243 }
244 }
245