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 +244 -94 3.6.416.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,52 +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 - $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 - ];
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 + }
151 241 }
152 242
153 - if (ArrayHelper::get($notification, 'sendTo.type') != 'routing') {
154 - return array_filter($sendAddresses, 'is_email');
243 + if ('routing' != ArrayHelper::get($notification, 'sendTo.type')) {
244 + return $sendAddresses;
155 245 }
156 246
157 247 $routings = ArrayHelper::get($notification, 'sendTo.routing');
158 248 $validAddresses = [];
249 + foreach ($routings as $routing) {
250 + $emailAddresses = ArrayHelper::get($routing, 'input_value');
159 251
160 - foreach ($routings as $routing) {
161 - $inputValue = ArrayHelper::get($routing, 'input_value');
162 - if(!$inputValue || !is_email($inputValue)) {
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,30 +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 - private function getHeaders($notification, $isSendAsPlain = false)
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 - if ($isSendAsPlain) {
260 - $headers = [];
261 - }
262 -
263 402 $fromEmail = $notification['fromEmail'];
264 403
265 - if (!is_email($fromEmail)) {
404 + if (!is_string($fromEmail) || ! is_email($fromEmail)) {
266 405 $fromEmail = false;
267 406 }
268 407
269 408 if ($notification['fromName'] && $fromEmail) {
@@ -271,26 +410,37 @@
271 410 } elseif ($fromEmail) {
272 411 $headers[] = "From: <{$fromEmail}>";
273 412 }
274 413
275 - if (!empty($notification['bcc'])) {
414 + if (! empty($notification['bcc'])) {
276 415 $bccEmail = $notification['bcc'];
277 416 $headers[] = 'bcc: ' . $bccEmail;
278 417 }
279 418
280 - if (!empty($notification['cc'])) {
419 + if (! empty($notification['cc'])) {
281 420 $ccEmail = $notification['cc'];
282 421 $headers[] = 'cc: ' . $ccEmail;
283 422 }
284 423
285 424 if ($notification['replyTo'] && is_email($notification['replyTo'])) {
286 - $headers[] = "Reply-To: <" . $notification['replyTo'] . ">";
425 + $headers[] = 'Reply-To: <' . $notification['replyTo'] . '>';
287 426 }
288 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 + );
289 438 $headers = $this->app->applyFilters(
290 - 'fluenttform_email_header', $headers, $notification
439 + 'fluentform/email_template_header',
440 + $headers,
441 + $notification
291 442 );
292 443
293 444 return $headers;
294 445 }
295 -
296 446 }