PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.8
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.8
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
fluentform / app / Services / FormBuilder / Notifications / EmailNotification.php

EmailNotification.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.8, at app/Services/FormBuilder/Notifications/EmailNotification.php

445 lines 15.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\App\Services\FormBuilder\Notifications;
4
5 defined('ABSPATH') or die;
6
7 use FluentForm\Framework\Helpers\ArrayHelper;
8 use FluentForm\Framework\Foundation\Application;
9 use FluentForm\App\Modules\Form\FormFieldsParser;
10 use FluentForm\App\Services\Emogrifier\Emogrifier;
11
12 class EmailNotification
13 {
14 /**
15 * FluentForm\Framework\Foundation\Application
16 *
17 * @var $app
18 */
19 protected $app = null;
20
21 /**
22 * Biuld the instance of this class
23 *
24 * @param \FluentForm\Framework\Foundation\Application $app
25 *
26 * @return $this
27 */
28 public function __construct(Application $app)
29 {
30 $this->app = $app;
31 }
32
33 /**
34 * Send the email notification
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 *
40 * @return bool
41 */
42 public function notify($notification, $submittedData, $form, $entryId = false)
43 {
44 $isSendAsPlain = 'yes' == ArrayHelper::get($notification, 'asPlainText');
45
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 );
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
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 );
128 $attachments = $this->app->applyFilters(
129 'fluentform/filter_email_attachments',
130 $notificationAttachments,
131 $notification,
132 $form,
133 $submittedData
134 );
135
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 );
148
149 $emailBody = apply_filters('fluentform/email_body', $emailBody, $notification, $submittedData, $form);
150
151 if ($entryId) {
152 /*
153 * Inline email logger. It will work fine hopefully
154 */
155 add_action('wp_mail_failed', function ($error) use ($notification, $form, $entryId) {
156 $failedMailSubject = ArrayHelper::get($error->error_data, 'wp_mail_failed.subject');
157 if ($failedMailSubject == $notification['subject']) {
158 $reason = $error->get_error_message();
159 do_action('fluentform/log_data', [
160 'parent_source_id' => $form->id,
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,
167 ]);
168 }
169 }, 10, 1);
170 }
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);
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']);
211 if (count($sendEmail) > 1) {
212 $data['email'] = $sendEmail;
213 }
214
215 return wp_mail(
216 $data['email'],
217 $data['subject'],
218 $data['body'],
219 $data['headers'],
220 $data['attachments']
221 );
222 }
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 */
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 * @param $formId
277 *
278 * @return array
279 *
280 * @todo: Implement Caching mechanism so we don't have to parse these things for every request
281 */
282 private function getFormInputsAndLabels($form)
283 {
284 $formInputs = FormFieldsParser::getInputs($form);
285
286 $inputLabels = FormFieldsParser::getAdminLabels($form, $formInputs);
287
288 return [
289 'inputs' => $formInputs,
290 'labels' => $inputLabels,
291 ];
292 }
293
294 public function getEmailWithTemplate($emailBody, $form, $notification)
295 {
296 $originalEmailBody = $emailBody;
297 $emailHeader = "";
298 $emailHeader = apply_filters_deprecated(
299 'fluentform_email_header',
300 [
301 $emailHeader,
302 $form,
303 $notification
304 ],
305 FLUENTFORM_FRAMEWORK_UPGRADE,
306 'fluentform/email_header',
307 'Use fluentform/email_header instead of fluentform_email_header.'
308 );
309 $emailHeader = apply_filters('fluentform/email_header', $emailHeader, $form, $notification);
310
311 $emailFooter = '';
312 $emailFooter = apply_filters_deprecated(
313 'fluentform_email_footer',
314 [
315 $emailFooter,
316 $form,
317 $notification
318 ],
319 FLUENTFORM_FRAMEWORK_UPGRADE,
320 'fluentform/email_footer',
321 'Use fluentform/email_footer instead of fluentform_email_footer.'
322 );
323 $emailFooter = apply_filters('fluentform/email_footer', $emailFooter, $form, $notification);
324
325 if (empty($emailHeader)) {
326 $emailHeader = wpFluentForm('view')->make('email.template.header', [
327 'form' => $form,
328 'notification' => $notification,
329 ]);
330 }
331
332 if (empty($emailFooter)) {
333 $emailFooter = wpFluentForm('view')->make('email.template.footer', [
334 'form' => $form,
335 'notification' => $notification,
336 'footerText' => $this->getFooterText($form, $notification),
337 ]);
338 }
339
340 $css = wpFluentForm('view')->make('email.template.styles');
341 $css = apply_filters_deprecated(
342 'fluentform_email_styles',
343 [
344 $css,
345 $form,
346 $notification
347 ],
348 FLUENTFORM_FRAMEWORK_UPGRADE,
349 'fluentform/email_styles',
350 'Use fluentform/email_styles instead of fluentform_email_styles.'
351 );
352 $css = apply_filters('fluentform/email_styles', $css, $form, $notification);
353 $emailBody = $emailHeader . $emailBody . $emailFooter;
354
355 ob_start();
356 try {
357 // apply CSS styles inline for picky email clients
358 $emogrifier = new Emogrifier($emailBody, $css);
359 $emailBody = $emogrifier->emogrify();
360 } catch (\Exception $e) {
361 }
362 $maybeError = ob_get_clean();
363
364 if ($maybeError) {
365 return $originalEmailBody;
366 }
367
368 return $emailBody;
369 }
370
371 private function getFooterText($form, $notification)
372 {
373 $option = get_option('_fluentform_global_form_settings');
374 if ($option && ! empty($option['misc']['email_footer_text'])) {
375 $footerText = $option['misc']['email_footer_text'];
376 } else {
377 $footerText = '&copy; ' . get_bloginfo('name', 'display') . '.';
378 }
379
380 $footerText = apply_filters_deprecated(
381 'fluentform_email_template_footer_text',
382 [
383 $footerText,
384 $form,
385 $notification
386 ],
387 FLUENTFORM_FRAMEWORK_UPGRADE,
388 'fluentform/email_template_footer_text',
389 'Use fluentform/email_template_footer_text instead of fluentform_email_header.'
390 );
391 return apply_filters('fluentform/email_template_footer_text', $footerText, $form, $notification);
392 }
393
394 public function getHeaders($notification, $isSendAsPlain = false)
395 {
396 $headers = [
397 'Content-Type: text/html; charset=utf-8',
398 ];
399
400 $fromEmail = $notification['fromEmail'];
401
402 if (!is_string($fromEmail) || ! is_email($fromEmail)) {
403 $fromEmail = false;
404 }
405
406 if ($notification['fromName'] && $fromEmail) {
407 $headers[] = "From: {$notification['fromName']} <{$fromEmail}>";
408 } elseif ($fromEmail) {
409 $headers[] = "From: <{$fromEmail}>";
410 }
411
412 if (! empty($notification['bcc'])) {
413 $bccEmail = $notification['bcc'];
414 $headers[] = 'bcc: ' . $bccEmail;
415 }
416
417 if (! empty($notification['cc'])) {
418 $ccEmail = $notification['cc'];
419 $headers[] = 'cc: ' . $ccEmail;
420 }
421
422 if ($notification['replyTo'] && is_email($notification['replyTo'])) {
423 $headers[] = 'Reply-To: <' . $notification['replyTo'] . '>';
424 }
425
426 $headers = apply_filters_deprecated(
427 'fluenttform_email_header',
428 [
429 $headers,
430 $notification
431 ],
432 FLUENTFORM_FRAMEWORK_UPGRADE,
433 'fluentform/email_template_header',
434 'Use fluentform/email_template_header instead of fluenttform_email_header.'
435 );
436 $headers = $this->app->applyFilters(
437 'fluentform/email_template_header',
438 $headers,
439 $notification
440 );
441
442 return $headers;
443 }
444 }
445