PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.14
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.14
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 3.6.65 All 196 releases
← All changes | app/Services/FormBuilder/Notifications/EmailNotification.php +242 -88 3.6.646.2.14 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,67 +31,133 @@
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 +
42 60 $emailBody = $notification['message'];
43 61
44 - $emailBody = apply_filters('fluentform_submission_message_parse', $emailBody, $entryId, $submittedData, $form);
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 + );
45 74
75 + $emailBody = apply_filters('fluentform/submission_message_parse', $emailBody, $entryId, $submittedData, $form);
76 +
46 77 $notification['parsed_message'] = $emailBody;
47 78
48 - if (!$isSendAsPlain) {
79 + if (! $isSendAsPlain) {
49 80 $emailBody = $this->getEmailWithTemplate($emailBody, $form, $notification);
50 81 }
51 82
52 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 + );
53 96
54 - $subject = apply_filters('fluentform_email_subject', $notification['subject'], $notification, $submittedData, $form);
97 + $subject = apply_filters('fluentform/email_subject', $notification['subject'], $notification, $submittedData, $form);
55 98
56 - if (!$sendAddresses || !$subject) {
57 - do_action('ff_log_data', [
58 - 'parent_source_id' => $form->id,
59 - 'source_type' => 'submission_item',
60 - 'source_id' => $entryId,
61 - 'component' => 'EmailNotification',
62 - 'status' => 'error',
63 - 'title' => 'Email sending skipped',
64 - 'description' => "Email skipped to send because email/subject may not valid.<br />Subject: {$notification['subject']}. <br/>Email: " . implode(', ', $sendAddresses),
65 - ]);
66 - return false;
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;
67 112 }
68 113
69 114 $headers = $this->getHeaders($notification, $isSendAsPlain);
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 + );
70 128 $attachments = $this->app->applyFilters(
71 - 'fluentform_filter_email_attachments',
72 - isset($notification['attachments']) ? $notification['attachments'] : [],
129 + 'fluentform/filter_email_attachments',
130 + $notificationAttachments,
73 131 $notification,
74 132 $form,
75 133 $submittedData
76 134 );
77 135
78 - $emailBody = apply_filters('fluentform_email_body', $emailBody, $notification, $submittedData, $form);
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 + );
79 148
149 + $emailBody = apply_filters('fluentform/email_body', $emailBody, $notification, $submittedData, $form);
150 +
80 151 if ($entryId) {
81 152 /*
82 153 * Inline email logger. It will work fine hopefully
83 154 */
84 155 add_action('wp_mail_failed', function ($error) use ($notification, $form, $entryId) {
85 -
86 156 $failedMailSubject = ArrayHelper::get($error->error_data, 'wp_mail_failed.subject');
87 157 if ($failedMailSubject == $notification['subject']) {
88 158 $reason = $error->get_error_message();
89 - do_action('ff_log_data', [
159 + do_action('fluentform/log_data', [
90 160 'parent_source_id' => $form->id,
91 161 'source_type' => 'submission_item',
92 162 'source_id' => $entryId,
93 163 'component' => 'EmailNotification',
@@ -97,32 +167,45 @@
97 167 ]);
98 168 }
99 169 }, 10, 1);
100 170 }
101 - $result = false;
102 - foreach ($sendAddresses as $address) {
103 - do_action('ff_log_data', [
104 - 'parent_source_id' => $form->id,
105 - 'source_type' => 'submission_item',
106 - 'source_id' => $entryId,
107 - 'component' => 'EmailNotification',
108 - 'status' => 'info',
109 - 'title' => 'Email sending initiated',
110 - 'description' => "Email Notification broadcasted to " . $address . ".<br />Subject: {$subject}",
111 - ]);
112 - $emailTo = apply_filters('fluentform_email_to', $address, $notification, $submittedData, $form);
113 - $result = $this->broadCast([
114 - 'email' => $emailTo,
115 - 'subject' => $subject,
116 - 'body' => $emailBody,
117 - 'headers' => $headers,
118 - 'attachments' => $attachments
119 - ]);
171 +
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);
120 188 }
121 - return $result;
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 + ]);
122 206 }
123 207
124 -
125 208 private function broadCast($data)
126 209 {
127 210 $sendEmail = explode(',', $data['email']);
128 211 if (count($sendEmail) > 1) {
@@ -137,22 +220,28 @@
137 220 $data['attachments']
138 221 );
139 222 }
140 223
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 + */
141 232 private function getSendAddresses($notification, $submittedData)
142 233 {
143 - $sendAddresses = [
144 - ArrayHelper::get($notification, 'sendTo.email')
145 - ];
234 + $sendAddresses = ArrayHelper::get($notification, 'sendTo.email');
146 235
147 - if (ArrayHelper::get($notification, 'sendTo.type') == 'field' && !empty($notification['sendTo']['field'])) {
148 - $sendAddresses = [
149 - ArrayHelper::get($submittedData, $notification['sendTo']['field'])
150 - ];
151 - $sendAddresses = array_filter($sendAddresses, 'is_email');
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 + }
152 241 }
153 242
154 - if (ArrayHelper::get($notification, 'sendTo.type') != 'routing') {
243 + if ('routing' != ArrayHelper::get($notification, 'sendTo.type')) {
155 244 return $sendAddresses;
156 245 }
157 246
158 247 $routings = ArrayHelper::get($notification, 'sendTo.routing');
@@ -157,32 +246,40 @@
157 246
158 247 $routings = ArrayHelper::get($notification, 'sendTo.routing');
159 248 $validAddresses = [];
160 249 foreach ($routings as $routing) {
161 - $inputValue = ArrayHelper::get($routing, 'input_value');
162 - if(!$inputValue || !is_email($inputValue)) {
250 + $emailAddresses = ArrayHelper::get($routing, 'input_value');
251 +
252 + if (!$emailAddresses || trim($emailAddresses) === '') {
163 253 continue;
164 254 }
255 + $emailAddresses = array_map('trim', explode(',', $emailAddresses));
256 + $emailAddresses = array_filter($emailAddresses, function ($email) {
257 + return is_email($email);
258 + });
165 259 $condition = [
166 260 'conditionals' => [
167 261 'status' => true,
168 262 'type' => 'any',
169 263 'conditions' => [
170 - $routing
171 - ]
172 - ]
264 + $routing,
265 + ],
266 + ],
173 267 ];
174 268 if (\FluentForm\App\Services\ConditionAssesor::evaluate($condition, $submittedData)) {
175 - $validAddresses[] = $inputValue;
269 + $validAddresses = array_merge($validAddresses, $emailAddresses);
176 270 }
177 271 }
178 -
179 - return $validAddresses;
272 + return implode(',', $validAddresses);
180 273 }
181 274
182 275 /**
276 + * Resolve a form's input keys and their admin labels.
277 + *
183 278 * @param $formId
279 + *
184 280 * @return array
281 + *
185 282 * @todo: Implement Caching mechanism so we don't have to parse these things for every request
186 283 */
187 284 private function getFormInputsAndLabels($form)
188 285 {
@@ -191,9 +288,9 @@
191 288 $inputLabels = FormFieldsParser::getAdminLabels($form, $formInputs);
192 289
193 290 return [
194 291 'inputs' => $formInputs,
195 - 'labels' => $inputLabels
292 + 'labels' => $inputLabels,
196 293 ];
197 294 }
198 295
199 296 public function getEmailWithTemplate($emailBody, $form, $notification)
@@ -198,28 +295,64 @@
198 295
199 296 public function getEmailWithTemplate($emailBody, $form, $notification)
200 297 {
201 298 $originalEmailBody = $emailBody;
202 - $emailHeader = apply_filters('fluentform_email_header', '', $form, $notification);
203 - $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);
204 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 +
205 327 if (empty($emailHeader)) {
206 - $emailHeader = View::make('email.template.header', array(
328 + $emailHeader = wpFluentForm('view')->make('email.template.header', [
207 329 'form' => $form,
208 - 'notification' => $notification
209 - ));
330 + 'notification' => $notification,
331 + ]);
210 332 }
211 333
212 334 if (empty($emailFooter)) {
213 - $emailFooter = View::make('email.template.footer', array(
335 + $emailFooter = wpFluentForm('view')->make('email.template.footer', [
214 336 'form' => $form,
215 337 'notification' => $notification,
216 - 'footerText' => $this->getFooterText($form, $notification)
217 - ));
338 + 'footerText' => $this->getFooterText($form, $notification),
339 + ]);
218 340 }
219 341
220 - $css = View::make('email.template.styles');
221 - $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);
222 355 $emailBody = $emailHeader . $emailBody . $emailFooter;
223 356
224 357 ob_start();
225 358 try {
@@ -225,10 +358,9 @@
225 358 try {
226 359 // apply CSS styles inline for picky email clients
227 360 $emogrifier = new Emogrifier($emailBody, $css);
228 361 $emailBody = $emogrifier->emogrify();
229 - } catch (\Exception $e) {
230 -
362 + } catch (\Exception $e) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement -- Emogrifier failed (malformed HTML/CSS); keep the un-inlined body.
231 363 }
232 364 $maybeError = ob_get_clean();
233 365
234 366 if ($maybeError) {
@@ -240,26 +372,37 @@
240 372
241 373 private function getFooterText($form, $notification)
242 374 {
243 375 $option = get_option('_fluentform_global_form_settings');
244 - if ($option && !empty($option['misc']['email_footer_text'])) {
376 + if ($option && ! empty($option['misc']['email_footer_text'])) {
245 377 $footerText = $option['misc']['email_footer_text'];
246 378 } else {
247 379 $footerText = '&copy; ' . get_bloginfo('name', 'display') . '.';
248 380 }
249 381
250 - 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);
251 394 }
252 395
253 396 public function getHeaders($notification, $isSendAsPlain = false)
254 397 {
255 398 $headers = [
256 - 'Content-Type: text/html; charset=utf-8'
399 + 'Content-Type: text/html; charset=utf-8',
257 400 ];
258 401
259 402 $fromEmail = $notification['fromEmail'];
260 403
261 - if (!is_email($fromEmail)) {
404 + if (!is_string($fromEmail) || ! is_email($fromEmail)) {
262 405 $fromEmail = false;
263 406 }
264 407
265 408 if ($notification['fromName'] && $fromEmail) {
@@ -267,26 +410,37 @@
267 410 } elseif ($fromEmail) {
268 411 $headers[] = "From: <{$fromEmail}>";
269 412 }
270 413
271 - if (!empty($notification['bcc'])) {
414 + if (! empty($notification['bcc'])) {
272 415 $bccEmail = $notification['bcc'];
273 416 $headers[] = 'bcc: ' . $bccEmail;
274 417 }
275 418
276 - if (!empty($notification['cc'])) {
419 + if (! empty($notification['cc'])) {
277 420 $ccEmail = $notification['cc'];
278 421 $headers[] = 'cc: ' . $ccEmail;
279 422 }
280 423
281 424 if ($notification['replyTo'] && is_email($notification['replyTo'])) {
282 - $headers[] = "Reply-To: <" . $notification['replyTo'] . ">";
425 + $headers[] = 'Reply-To: <' . $notification['replyTo'] . '>';
283 426 }
284 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 + );
285 438 $headers = $this->app->applyFilters(
286 - 'fluenttform_email_header', $headers, $notification
439 + 'fluentform/email_template_header',
440 + $headers,
441 + $notification
287 442 );
288 443
289 444 return $headers;
290 445 }
291 -
292 446 }