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