PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.15
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.15
6.2.15 6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 All 197 releases
← All changes | app/Services/FormBuilder/Notifications/EmailNotification.php +298 -88 3.6.31 → 6.2.15 View file →
@@ -1,18 +1,20 @@
1 1 <?php
2 2
3 3 namespace FluentForm\App\Services\FormBuilder\Notifications;
4 4
5 +defined('ABSPATH') || die;
6 +
7 +use FluentForm\Framework\Helpers\ArrayHelper;
8 +use FluentForm\Framework\Foundation\Application;
5 9 use FluentForm\App\Modules\Form\FormFieldsParser;
6 10 use FluentForm\App\Services\Emogrifier\Emogrifier;
7 -use FluentForm\Framework\Foundation\Application;
8 -use FluentForm\Framework\Helpers\ArrayHelper;
9 -use FluentForm\View;
10 11
11 12 class EmailNotification
12 13 {
13 14 /**
14 15 * FluentForm\Framework\Foundation\Application
16 + *
15 17 * @var $app
16 18 */
17 19 protected $app = null;
18 20
@@ -17,9 +19,11 @@
17 19 protected $app = null;
18 20
19 21 /**
20 22 * Biuld the instance of this class
21 - * @param FluentForm\Framework\Foundation\Application $app
23 + *
24 + * @param \FluentForm\Framework\Foundation\Application $app
25 + *
22 26 * @return $this
23 27 */
24 28 public function __construct(Application $app)
25 29 {
@@ -27,102 +31,255 @@
27 31 }
28 32
29 33 /**
30 34 * Send the email notification
31 - * @param array $notification [Notification settings from form meta]
32 - * @param array $submittedData [User submitted form data]
33 - * @param \StdClass $form [The form object from database]
35 + *
36 + * @param array $notification [Notification settings from form meta]
37 + * @param array $submittedData [User submitted form data]
38 + * @param \StdClass $form [The form object from database]
39 + *
34 40 * @return bool
35 41 */
36 42 public function notify($notification, $submittedData, $form, $entryId = false)
37 43 {
38 - $isSendAsPlain = ArrayHelper::get($notification, 'asPlainText') == 'yes';
44 + $isSendAsPlain = 'yes' == ArrayHelper::get($notification, 'asPlainText');
39 45
40 - $isSendAsPlain = apply_filters('fluenform_send_plain_html_email', $isSendAsPlain, $form, $notification);
46 + $isSendAsPlain= apply_filters_deprecated(
47 + 'fluentform_send_plain_html_email',
48 + [
49 + $isSendAsPlain,
50 + $form,
51 + $notification,
52 + ],
53 + FLUENTFORM_FRAMEWORK_UPGRADE,
54 + 'fluentform/send_plain_html_email',
55 + 'Use fluentform/send_plain_html_email instead of fluentform_send_plain_html_email.'
56 + );
41 57
58 + $isSendAsPlain = apply_filters('fluentform/send_plain_html_email', $isSendAsPlain, $form, $notification);
59 +
60 + $emailBody = $notification['message'];
61 +
62 + $emailBody = apply_filters_deprecated(
63 + 'fluentform_submission_message_parse',
64 + [
65 + $emailBody,
66 + $entryId,
67 + $submittedData,
68 + $form,
69 + ],
70 + FLUENTFORM_FRAMEWORK_UPGRADE,
71 + 'fluentform/submission_message_parse',
72 + 'Use fluentform/submission_message_parse instead of fluentform_submission_message_parse.'
73 + );
74 +
75 + $emailBody = apply_filters('fluentform/submission_message_parse', $emailBody, $entryId, $submittedData, $form);
76 +
77 + $notification['parsed_message'] = $emailBody;
78 +
79 + if (! $isSendAsPlain) {
80 + $emailBody = $this->getEmailWithTemplate($emailBody, $form, $notification);
81 + }
82 +
83 + $sendAddresses = $this->getSendAddresses($notification, $submittedData);
84 + $notification['subject'] = apply_filters_deprecated(
85 + 'fluentform_email_subject',
86 + [
87 + $notification['subject'],
88 + $notification,
89 + $submittedData,
90 + $form,
91 + ],
92 + FLUENTFORM_FRAMEWORK_UPGRADE,
93 + 'fluentform/email_subject',
94 + 'Use fluentform/email_subject instead of fluentform_email_subject.'
95 + );
96 +
97 + $subject = apply_filters('fluentform/email_subject', $notification['subject'], $notification, $submittedData, $form);
98 +
99 + if (! $sendAddresses || ! $subject) {
100 + if ($entryId) {
101 + do_action('fluentform/log_data', [
102 + 'parent_source_id' => $form->id,
103 + 'source_type' => 'submission_item',
104 + 'source_id' => $entryId,
105 + 'component' => 'EmailNotification',
106 + 'status' => 'error',
107 + 'title' => 'Email sending skipped',
108 + 'description' => "Email skipped to send because email/subject may not valid.<br />Subject: {$notification['subject']}. <br/>Email: " . $sendAddresses,
109 + ]);
110 + }
111 + return null;
112 + }
113 +
42 114 $headers = $this->getHeaders($notification, $isSendAsPlain);
43 -
115 + $notificationAttachments = isset($notification['attachments']) ? $notification['attachments'] : [];
116 + $notificationAttachments = apply_filters_deprecated(
117 + 'fluentform_filter_email_attachments',
118 + [
119 + $notificationAttachments,
120 + $notification,
121 + $form,
122 + $submittedData,
123 + ],
124 + FLUENTFORM_FRAMEWORK_UPGRADE,
125 + 'fluentform/filter_email_attachments',
126 + 'Use fluentform/filter_email_attachments instead of fluentform_filter_email_attachments.'
127 + );
44 128 $attachments = $this->app->applyFilters(
45 - 'fluentform_filter_email_attachments',
46 - isset($notification['attachments']) ? $notification['attachments'] : [],
129 + 'fluentform/filter_email_attachments',
130 + $notificationAttachments,
47 131 $notification,
48 132 $form,
49 133 $submittedData
50 134 );
51 - $emailBody = $notification['message'];
52 135
53 - if ($isSendAsPlain) {
54 - $emailBody = strip_tags($emailBody);
55 - } else {
56 - $emailBody = $this->getEmailWithTemplate($emailBody, $form, $notification);
57 - }
136 + $emailBody = apply_filters_deprecated(
137 + 'fluentform_email_body',
138 + [
139 + $emailBody,
140 + $notification,
141 + $submittedData,
142 + $form,
143 + ],
144 + FLUENTFORM_FRAMEWORK_UPGRADE,
145 + 'fluentform/email_body',
146 + 'Use fluentform/email_body instead of fluentform_email_body.'
147 + );
58 148
59 - if (ArrayHelper::get($notification, 'sendTo.type') == 'field' && !empty($notification['sendTo']['field'])) {
60 - $notification['sendTo']['email'] = ArrayHelper::get($submittedData, $notification['sendTo']['field']);
61 - }
149 + $emailBody = apply_filters('fluentform/email_body', $emailBody, $notification, $submittedData, $form);
62 150
63 - if (!$notification['sendTo']['email'] || !$notification['subject']) {
64 - do_action('ff_log_data', [
65 - 'parent_source_id' => $form->id,
66 - 'source_type' => 'submission_item',
67 - 'source_id' => $entryId,
68 - 'component' => 'EmailNotification',
69 - 'status' => 'error',
70 - 'title' => 'Email sending skipped',
71 - 'description' => "Email skipped to send because email/subject may not valid.<br />Subject: {$notification['subject']}. <br/>Email: " . $notification['sendTo']['email'],
72 - ]);
73 - return false;
74 - }
75 -
76 151 if ($entryId) {
77 - do_action('ff_log_data', [
78 - 'parent_source_id' => $form->id,
79 - 'source_type' => 'submission_item',
80 - 'source_id' => $entryId,
81 - 'component' => 'EmailNotification',
82 - 'status' => 'info',
83 - 'title' => 'Email sending initiated',
84 - 'description' => "Email Notification broadcasted to " . $notification['sendTo']['email'] . ".<br />Subject: {$notification['subject']}",
85 - ]);
86 -
87 152 /*
88 153 * Inline email logger. It will work fine hopefully
89 154 */
90 155 add_action('wp_mail_failed', function ($error) use ($notification, $form, $entryId) {
91 -
92 156 $failedMailSubject = ArrayHelper::get($error->error_data, 'wp_mail_failed.subject');
93 157 if ($failedMailSubject == $notification['subject']) {
94 158 $reason = $error->get_error_message();
95 - do_action('ff_log_data', [
159 + do_action('fluentform/log_data', [
96 160 'parent_source_id' => $form->id,
97 - 'source_type' => 'submission_item',
98 - 'source_id' => $entryId,
99 - 'component' => 'EmailNotification',
100 - 'status' => 'failed',
101 - 'title' => 'Email sending failed',
102 - 'description' => "Email Notification failed to sent.<br />Subject: {$notification['subject']}. <br/>Reason: " . $reason,
161 + 'source_type' => 'submission_item',
162 + 'source_id' => $entryId,
163 + 'component' => 'EmailNotification',
164 + 'status' => 'failed',
165 + 'title' => 'Email sending failed',
166 + 'description' => "Email Notification failed to sent.<br />Subject: {$notification['subject']}. <br/>Reason: " . $reason,
103 167 ]);
104 168 }
105 169 }, 10, 1);
106 170 }
107 171
108 - $sendEmail = explode(',', $notification['sendTo']['email']);
172 + $sendAddresses = apply_filters_deprecated(
173 + 'fluentform_email_to',
174 + [
175 + $sendAddresses,
176 + $notification,
177 + $submittedData,
178 + $form,
179 + ],
180 + FLUENTFORM_FRAMEWORK_UPGRADE,
181 + 'fluentform/email_to',
182 + 'Use fluentform/email_to instead of fluentform_email_to.'
183 + );
184 +
185 + $emailTo = apply_filters('fluentform/email_to', $sendAddresses, $notification, $submittedData, $form);
186 + if (is_array($emailTo)) {
187 + $emailTo = implode(', ', $emailTo);
188 + }
189 + do_action('fluentform/log_data', [
190 + 'parent_source_id' => $form->id,
191 + 'source_type' => 'submission_item',
192 + 'source_id' => $entryId,
193 + 'component' => 'EmailNotification',
194 + 'status' => 'info',
195 + 'title' => 'Email sending initiated',
196 + 'description' => 'Email Notification broadcasted to ' . $emailTo . ".<br />Subject: {$subject}",
197 + ]);
198 +
199 + return $this->broadCast([
200 + 'email' => $emailTo,
201 + 'subject' => $subject,
202 + 'body' => $emailBody,
203 + 'headers' => $headers,
204 + 'attachments' => $attachments,
205 + ]);
206 + }
207 +
208 + private function broadCast($data)
209 + {
210 + $sendEmail = explode(',', $data['email']);
109 211 if (count($sendEmail) > 1) {
110 - $notification['sendTo']['email'] = $sendEmail;
212 + $data['email'] = $sendEmail;
111 213 }
112 214
113 215 return wp_mail(
114 - $notification['sendTo']['email'],
115 - $notification['subject'],
116 - $emailBody,
117 - $headers,
118 - $attachments
216 + $data['email'],
217 + $data['subject'],
218 + $data['body'],
219 + $data['headers'],
220 + $data['attachments']
119 221 );
120 222 }
121 223
122 224 /**
225 + * Get email addresses
226 + *
227 + * @param array $notification [Notification settings from form meta]
228 + * @param array $submittedData [User submitted form data]
229 + *
230 + * @return string $sendAddresses [Email address or addresses as comma separated string]
231 + */
232 + private function getSendAddresses($notification, $submittedData)
233 + {
234 + $sendAddresses = ArrayHelper::get($notification, 'sendTo.email');
235 +
236 + if ('field' == ArrayHelper::get($notification, 'sendTo.type') && ! empty($notification['sendTo']['field'])) {
237 + $sendAddresses = ArrayHelper::get($submittedData, $notification['sendTo']['field'], '');
238 + if (!is_email($sendAddresses)) {
239 + return '';
240 + }
241 + }
242 +
243 + if ('routing' != ArrayHelper::get($notification, 'sendTo.type')) {
244 + return $sendAddresses;
245 + }
246 +
247 + $routings = ArrayHelper::get($notification, 'sendTo.routing');
248 + $validAddresses = [];
249 + foreach ($routings as $routing) {
250 + $emailAddresses = ArrayHelper::get($routing, 'input_value');
251 +
252 + if (!$emailAddresses || trim($emailAddresses) === '') {
253 + continue;
254 + }
255 + $emailAddresses = array_map('trim', explode(',', $emailAddresses));
256 + $emailAddresses = array_filter($emailAddresses, function ($email) {
257 + return is_email($email);
258 + });
259 + $condition = [
260 + 'conditionals' => [
261 + 'status' => true,
262 + 'type' => 'any',
263 + 'conditions' => [
264 + $routing,
265 + ],
266 + ],
267 + ];
268 + if (\FluentForm\App\Services\ConditionAssesor::evaluate($condition, $submittedData)) {
269 + $validAddresses = array_merge($validAddresses, $emailAddresses);
270 + }
271 + }
272 + return implode(',', $validAddresses);
273 + }
274 +
275 + /**
276 + * Resolve a form's input keys and their admin labels.
277 + *
123 278 * @param $formId
279 + *
124 280 * @return array
281 + *
125 282 * @todo: Implement Caching mechanism so we don't have to parse these things for every request
126 283 */
127 284 private function getFormInputsAndLabels($form)
128 285 {
@@ -131,9 +288,9 @@
131 288 $inputLabels = FormFieldsParser::getAdminLabels($form, $formInputs);
132 289
133 290 return [
134 291 'inputs' => $formInputs,
135 - 'labels' => $inputLabels
292 + 'labels' => $inputLabels,
136 293 ];
137 294 }
138 295
139 296 public function getEmailWithTemplate($emailBody, $form, $notification)
@@ -138,28 +295,64 @@
138 295
139 296 public function getEmailWithTemplate($emailBody, $form, $notification)
140 297 {
141 298 $originalEmailBody = $emailBody;
142 - $emailHeader = apply_filters('fluentform_email_header', '', $form, $notification);
143 - $emailFooter = apply_filters('fluentform_email_footer', '', $form, $notification);
299 + $emailHeader = '';
300 + $emailHeader = apply_filters_deprecated(
301 + 'fluentform_email_header',
302 + [
303 + $emailHeader,
304 + $form,
305 + $notification,
306 + ],
307 + FLUENTFORM_FRAMEWORK_UPGRADE,
308 + 'fluentform/email_header',
309 + 'Use fluentform/email_header instead of fluentform_email_header.'
310 + );
311 + $emailHeader = apply_filters('fluentform/email_header', $emailHeader, $form, $notification);
144 312
313 + $emailFooter = '';
314 + $emailFooter = apply_filters_deprecated(
315 + 'fluentform_email_footer',
316 + [
317 + $emailFooter,
318 + $form,
319 + $notification,
320 + ],
321 + FLUENTFORM_FRAMEWORK_UPGRADE,
322 + 'fluentform/email_footer',
323 + 'Use fluentform/email_footer instead of fluentform_email_footer.'
324 + );
325 + $emailFooter = apply_filters('fluentform/email_footer', $emailFooter, $form, $notification);
326 +
145 327 if (empty($emailHeader)) {
146 - $emailHeader = View::make('email.template.header', array(
147 - 'form' => $form,
148 - 'notification' => $notification
149 - ));
328 + $emailHeader = wpFluentForm('view')->make('email.template.header', [
329 + 'form' => $form,
330 + 'notification' => $notification,
331 + ]);
150 332 }
151 333
152 334 if (empty($emailFooter)) {
153 - $emailFooter = View::make('email.template.footer', array(
154 - 'form' => $form,
335 + $emailFooter = wpFluentForm('view')->make('email.template.footer', [
336 + 'form' => $form,
155 337 'notification' => $notification,
156 - 'footerText' => $this->getFooterText($form, $notification)
157 - ));
338 + 'footerText' => $this->getFooterText($form, $notification),
339 + ]);
158 340 }
159 341
160 - $css = View::make('email.template.styles');
161 - $css = apply_filters('fluentform_email_styles', $css, $form, $notification);
342 + $css = wpFluentForm('view')->make('email.template.styles');
343 + $css = apply_filters_deprecated(
344 + 'fluentform_email_styles',
345 + [
346 + $css,
347 + $form,
348 + $notification,
349 + ],
350 + FLUENTFORM_FRAMEWORK_UPGRADE,
351 + 'fluentform/email_styles',
352 + 'Use fluentform/email_styles instead of fluentform_email_styles.'
353 + );
354 + $css = apply_filters('fluentform/email_styles', $css, $form, $notification);
162 355 $emailBody = $emailHeader . $emailBody . $emailFooter;
163 356
164 357 ob_start();
165 358 try {
@@ -165,10 +358,9 @@
165 358 try {
166 359 // apply CSS styles inline for picky email clients
167 360 $emogrifier = new Emogrifier($emailBody, $css);
168 361 $emailBody = $emogrifier->emogrify();
169 - } catch (\Exception $e) {
170 -
362 + } catch (\Exception $e) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement -- Emogrifier failed (malformed HTML/CSS); keep the un-inlined body.
171 363 }
172 364 $maybeError = ob_get_clean();
173 365
174 366 if ($maybeError) {
@@ -180,30 +372,37 @@
180 372
181 373 private function getFooterText($form, $notification)
182 374 {
183 375 $option = get_option('_fluentform_global_form_settings');
184 - if ($option && !empty($option['misc']['email_footer_text'])) {
376 + if ($option && ! empty($option['misc']['email_footer_text'])) {
185 377 $footerText = $option['misc']['email_footer_text'];
186 378 } else {
187 379 $footerText = '&copy; ' . get_bloginfo('name', 'display') . '.';
188 380 }
189 381
190 - return apply_filters('fluentform_email_template_footer_text', $footerText, $form, $notification);
382 + $footerText = apply_filters_deprecated(
383 + 'fluentform_email_template_footer_text',
384 + [
385 + $footerText,
386 + $form,
387 + $notification,
388 + ],
389 + FLUENTFORM_FRAMEWORK_UPGRADE,
390 + 'fluentform/email_template_footer_text',
391 + 'Use fluentform/email_template_footer_text instead of fluentform_email_header.'
392 + );
393 + return apply_filters('fluentform/email_template_footer_text', $footerText, $form, $notification);
191 394 }
192 395
193 - private function getHeaders($notification, $isSendAsPlain = false)
396 + public function getHeaders($notification, $isSendAsPlain = false)
194 397 {
195 398 $headers = [
196 - 'Content-Type: text/html; charset=utf-8'
399 + 'Content-Type: text/html; charset=utf-8',
197 400 ];
198 401
199 - if ($isSendAsPlain) {
200 - $headers = [];
201 - }
202 -
203 402 $fromEmail = $notification['fromEmail'];
204 403
205 - if (!is_email($fromEmail)) {
404 + if (!is_string($fromEmail) || ! is_email($fromEmail)) {
206 405 $fromEmail = false;
207 406 }
208 407
209 408 if ($notification['fromName'] && $fromEmail) {
@@ -211,26 +410,37 @@
211 410 } elseif ($fromEmail) {
212 411 $headers[] = "From: <{$fromEmail}>";
213 412 }
214 413
215 - if (!empty($notification['bcc'])) {
414 + if (! empty($notification['bcc'])) {
216 415 $bccEmail = $notification['bcc'];
217 416 $headers[] = 'bcc: ' . $bccEmail;
218 417 }
219 418
220 - if (!empty($notification['cc'])) {
419 + if (! empty($notification['cc'])) {
221 420 $ccEmail = $notification['cc'];
222 421 $headers[] = 'cc: ' . $ccEmail;
223 422 }
224 423
225 424 if ($notification['replyTo'] && is_email($notification['replyTo'])) {
226 - $headers[] = "Reply-To: <".$notification['replyTo'].">";
425 + $headers[] = 'Reply-To: <' . $notification['replyTo'] . '>';
227 426 }
228 427
428 + $headers = apply_filters_deprecated(
429 + 'fluenttform_email_header',
430 + [
431 + $headers,
432 + $notification,
433 + ],
434 + FLUENTFORM_FRAMEWORK_UPGRADE,
435 + 'fluentform/email_template_header',
436 + 'Use fluentform/email_template_header instead of fluenttform_email_header.'
437 + );
229 438 $headers = $this->app->applyFilters(
230 - 'fluenttform_email_header', $headers, $notification
439 + 'fluentform/email_template_header',
440 + $headers,
441 + $notification
231 442 );
232 443
233 444 return $headers;
234 445 }
235 -
236 446 }