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 +243 -91 3.6.40 → 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,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,50 +220,66 @@
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 234 $sendAddresses = ArrayHelper::get($notification, 'sendTo.email');
144 235
145 - if (ArrayHelper::get($notification, 'sendTo.type') == 'field' && !empty($notification['sendTo']['field'])) {
146 - $sendAddresses = [
147 - ArrayHelper::get($submittedData, $notification['sendTo']['field'])
148 - ];
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 + }
149 241 }
150 242
151 - if (ArrayHelper::get($notification, 'sendTo.type') != 'routing') {
152 - return array_filter($sendAddresses, 'is_email');
243 + if ('routing' != ArrayHelper::get($notification, 'sendTo.type')) {
244 + return $sendAddresses;
153 245 }
154 246
155 247 $routings = ArrayHelper::get($notification, 'sendTo.routing');
156 248 $validAddresses = [];
249 + foreach ($routings as $routing) {
250 + $emailAddresses = ArrayHelper::get($routing, 'input_value');
157 251
158 - foreach ($routings as $routing) {
159 - $inputValue = ArrayHelper::get($routing, 'input_value');
160 - if(!$inputValue || !is_email($inputValue)) {
252 + if (!$emailAddresses || trim($emailAddresses) === '') {
161 253 continue;
162 254 }
255 + $emailAddresses = array_map('trim', explode(',', $emailAddresses));
256 + $emailAddresses = array_filter($emailAddresses, function ($email) {
257 + return is_email($email);
258 + });
163 259 $condition = [
164 260 'conditionals' => [
165 261 'status' => true,
166 262 'type' => 'any',
167 263 'conditions' => [
168 - $routing
169 - ]
170 - ]
264 + $routing,
265 + ],
266 + ],
171 267 ];
172 268 if (\FluentForm\App\Services\ConditionAssesor::evaluate($condition, $submittedData)) {
173 - $validAddresses[] = $inputValue;
269 + $validAddresses = array_merge($validAddresses, $emailAddresses);
174 270 }
175 271 }
176 -
177 - return $validAddresses;
272 + return implode(',', $validAddresses);
178 273 }
179 274
180 275 /**
276 + * Resolve a form's input keys and their admin labels.
277 + *
181 278 * @param $formId
279 + *
182 280 * @return array
281 + *
183 282 * @todo: Implement Caching mechanism so we don't have to parse these things for every request
184 283 */
185 284 private function getFormInputsAndLabels($form)
186 285 {
@@ -189,9 +288,9 @@
189 288 $inputLabels = FormFieldsParser::getAdminLabels($form, $formInputs);
190 289
191 290 return [
192 291 'inputs' => $formInputs,
193 - 'labels' => $inputLabels
292 + 'labels' => $inputLabels,
194 293 ];
195 294 }
196 295
197 296 public function getEmailWithTemplate($emailBody, $form, $notification)
@@ -196,28 +295,64 @@
196 295
197 296 public function getEmailWithTemplate($emailBody, $form, $notification)
198 297 {
199 298 $originalEmailBody = $emailBody;
200 - $emailHeader = apply_filters('fluentform_email_header', '', $form, $notification);
201 - $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);
202 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 +
203 327 if (empty($emailHeader)) {
204 - $emailHeader = View::make('email.template.header', array(
328 + $emailHeader = wpFluentForm('view')->make('email.template.header', [
205 329 'form' => $form,
206 - 'notification' => $notification
207 - ));
330 + 'notification' => $notification,
331 + ]);
208 332 }
209 333
210 334 if (empty($emailFooter)) {
211 - $emailFooter = View::make('email.template.footer', array(
335 + $emailFooter = wpFluentForm('view')->make('email.template.footer', [
212 336 'form' => $form,
213 337 'notification' => $notification,
214 - 'footerText' => $this->getFooterText($form, $notification)
215 - ));
338 + 'footerText' => $this->getFooterText($form, $notification),
339 + ]);
216 340 }
217 341
218 - $css = View::make('email.template.styles');
219 - $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);
220 355 $emailBody = $emailHeader . $emailBody . $emailFooter;
221 356
222 357 ob_start();
223 358 try {
@@ -223,10 +358,9 @@
223 358 try {
224 359 // apply CSS styles inline for picky email clients
225 360 $emogrifier = new Emogrifier($emailBody, $css);
226 361 $emailBody = $emogrifier->emogrify();
227 - } catch (\Exception $e) {
228 -
362 + } catch (\Exception $e) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement -- Emogrifier failed (malformed HTML/CSS); keep the un-inlined body.
229 363 }
230 364 $maybeError = ob_get_clean();
231 365
232 366 if ($maybeError) {
@@ -238,30 +372,37 @@
238 372
239 373 private function getFooterText($form, $notification)
240 374 {
241 375 $option = get_option('_fluentform_global_form_settings');
242 - if ($option && !empty($option['misc']['email_footer_text'])) {
376 + if ($option && ! empty($option['misc']['email_footer_text'])) {
243 377 $footerText = $option['misc']['email_footer_text'];
244 378 } else {
245 379 $footerText = '&copy; ' . get_bloginfo('name', 'display') . '.';
246 380 }
247 381
248 - 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);
249 394 }
250 395
251 - private function getHeaders($notification, $isSendAsPlain = false)
396 + public function getHeaders($notification, $isSendAsPlain = false)
252 397 {
253 398 $headers = [
254 - 'Content-Type: text/html; charset=utf-8'
399 + 'Content-Type: text/html; charset=utf-8',
255 400 ];
256 401
257 - if ($isSendAsPlain) {
258 - $headers = [];
259 - }
260 -
261 402 $fromEmail = $notification['fromEmail'];
262 403
263 - if (!is_email($fromEmail)) {
404 + if (!is_string($fromEmail) || ! is_email($fromEmail)) {
264 405 $fromEmail = false;
265 406 }
266 407
267 408 if ($notification['fromName'] && $fromEmail) {
@@ -269,26 +410,37 @@
269 410 } elseif ($fromEmail) {
270 411 $headers[] = "From: <{$fromEmail}>";
271 412 }
272 413
273 - if (!empty($notification['bcc'])) {
414 + if (! empty($notification['bcc'])) {
274 415 $bccEmail = $notification['bcc'];
275 416 $headers[] = 'bcc: ' . $bccEmail;
276 417 }
277 418
278 - if (!empty($notification['cc'])) {
419 + if (! empty($notification['cc'])) {
279 420 $ccEmail = $notification['cc'];
280 421 $headers[] = 'cc: ' . $ccEmail;
281 422 }
282 423
283 424 if ($notification['replyTo'] && is_email($notification['replyTo'])) {
284 - $headers[] = "Reply-To: <" . $notification['replyTo'] . ">";
425 + $headers[] = 'Reply-To: <' . $notification['replyTo'] . '>';
285 426 }
286 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 + );
287 438 $headers = $this->app->applyFilters(
288 - 'fluenttform_email_header', $headers, $notification
439 + 'fluentform/email_template_header',
440 + $headers,
441 + $notification
289 442 );
290 443
291 444 return $headers;
292 445 }
293 -
294 446 }