PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 3.6.40
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v3.6.40
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 3.6.40, at app/Services/FormBuilder/Notifications/EmailNotification.php

295 lines 10.0 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 use FluentForm\App\Modules\Form\FormFieldsParser;
6 use FluentForm\App\Services\Emogrifier\Emogrifier;
7 use FluentForm\Framework\Foundation\Application;
8 use FluentForm\Framework\Helpers\ArrayHelper;
9 use FluentForm\View;
10
11 class EmailNotification
12 {
13 /**
14 * FluentForm\Framework\Foundation\Application
15 * @var $app
16 */
17 protected $app = null;
18
19 /**
20 * Biuld the instance of this class
21 * @param FluentForm\Framework\Foundation\Application $app
22 * @return $this
23 */
24 public function __construct(Application $app)
25 {
26 $this->app = $app;
27 }
28
29 /**
30 * 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]
34 * @return bool
35 */
36 public function notify($notification, $submittedData, $form, $entryId = false)
37 {
38 $isSendAsPlain = ArrayHelper::get($notification, 'asPlainText') == 'yes';
39
40 $isSendAsPlain = apply_filters('fluenform_send_plain_html_email', $isSendAsPlain, $form, $notification);
41
42 $emailBody = $notification['message'];
43
44 $emailBody = apply_filters('fluentform_submission_message_parse', $emailBody, $entryId, $submittedData, $form);
45
46 $notification['parsed_message'] = $emailBody;
47
48 if (!$isSendAsPlain) {
49 $emailBody = $this->getEmailWithTemplate($emailBody, $form, $notification);
50 }
51
52 $sendAddresses = $this->getSendAddresses($notification, $submittedData);
53
54 $subject = apply_filters('fluentform_email_subject', $notification['subject'], $notification, $submittedData, $form);
55
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;
67 }
68
69 $headers = $this->getHeaders($notification, $isSendAsPlain);
70 $attachments = $this->app->applyFilters(
71 'fluentform_filter_email_attachments',
72 isset($notification['attachments']) ? $notification['attachments'] : [],
73 $notification,
74 $form,
75 $submittedData
76 );
77
78 $emailBody = apply_filters('fluentform_email_body', $emailBody, $notification, $submittedData, $form);
79
80 if ($entryId) {
81 /*
82 * Inline email logger. It will work fine hopefully
83 */
84 add_action('wp_mail_failed', function ($error) use ($notification, $form, $entryId) {
85
86 $failedMailSubject = ArrayHelper::get($error->error_data, 'wp_mail_failed.subject');
87 if ($failedMailSubject == $notification['subject']) {
88 $reason = $error->get_error_message();
89 do_action('ff_log_data', [
90 'parent_source_id' => $form->id,
91 'source_type' => 'submission_item',
92 'source_id' => $entryId,
93 'component' => 'EmailNotification',
94 'status' => 'failed',
95 'title' => 'Email sending failed',
96 'description' => "Email Notification failed to sent.<br />Subject: {$notification['subject']}. <br/>Reason: " . $reason,
97 ]);
98 }
99 }, 10, 1);
100 }
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 ]);
120 }
121 return $result;
122 }
123
124
125 private function broadCast($data)
126 {
127 $sendEmail = explode(',', $data['email']);
128 if (count($sendEmail) > 1) {
129 $data['email'] = $sendEmail;
130 }
131
132 return wp_mail(
133 $data['email'],
134 $data['subject'],
135 $data['body'],
136 $data['headers'],
137 $data['attachments']
138 );
139 }
140
141 private function getSendAddresses($notification, $submittedData)
142 {
143 $sendAddresses = ArrayHelper::get($notification, 'sendTo.email');
144
145 if (ArrayHelper::get($notification, 'sendTo.type') == 'field' && !empty($notification['sendTo']['field'])) {
146 $sendAddresses = [
147 ArrayHelper::get($submittedData, $notification['sendTo']['field'])
148 ];
149 }
150
151 if (ArrayHelper::get($notification, 'sendTo.type') != 'routing') {
152 return array_filter($sendAddresses, 'is_email');
153 }
154
155 $routings = ArrayHelper::get($notification, 'sendTo.routing');
156 $validAddresses = [];
157
158 foreach ($routings as $routing) {
159 $inputValue = ArrayHelper::get($routing, 'input_value');
160 if(!$inputValue || !is_email($inputValue)) {
161 continue;
162 }
163 $condition = [
164 'conditionals' => [
165 'status' => true,
166 'type' => 'any',
167 'conditions' => [
168 $routing
169 ]
170 ]
171 ];
172 if (\FluentForm\App\Services\ConditionAssesor::evaluate($condition, $submittedData)) {
173 $validAddresses[] = $inputValue;
174 }
175 }
176
177 return $validAddresses;
178 }
179
180 /**
181 * @param $formId
182 * @return array
183 * @todo: Implement Caching mechanism so we don't have to parse these things for every request
184 */
185 private function getFormInputsAndLabels($form)
186 {
187 $formInputs = FormFieldsParser::getInputs($form);
188
189 $inputLabels = FormFieldsParser::getAdminLabels($form, $formInputs);
190
191 return [
192 'inputs' => $formInputs,
193 'labels' => $inputLabels
194 ];
195 }
196
197 public function getEmailWithTemplate($emailBody, $form, $notification)
198 {
199 $originalEmailBody = $emailBody;
200 $emailHeader = apply_filters('fluentform_email_header', '', $form, $notification);
201 $emailFooter = apply_filters('fluentform_email_footer', '', $form, $notification);
202
203 if (empty($emailHeader)) {
204 $emailHeader = View::make('email.template.header', array(
205 'form' => $form,
206 'notification' => $notification
207 ));
208 }
209
210 if (empty($emailFooter)) {
211 $emailFooter = View::make('email.template.footer', array(
212 'form' => $form,
213 'notification' => $notification,
214 'footerText' => $this->getFooterText($form, $notification)
215 ));
216 }
217
218 $css = View::make('email.template.styles');
219 $css = apply_filters('fluentform_email_styles', $css, $form, $notification);
220 $emailBody = $emailHeader . $emailBody . $emailFooter;
221
222 ob_start();
223 try {
224 // apply CSS styles inline for picky email clients
225 $emogrifier = new Emogrifier($emailBody, $css);
226 $emailBody = $emogrifier->emogrify();
227 } catch (\Exception $e) {
228
229 }
230 $maybeError = ob_get_clean();
231
232 if ($maybeError) {
233 return $originalEmailBody;
234 }
235
236 return $emailBody;
237 }
238
239 private function getFooterText($form, $notification)
240 {
241 $option = get_option('_fluentform_global_form_settings');
242 if ($option && !empty($option['misc']['email_footer_text'])) {
243 $footerText = $option['misc']['email_footer_text'];
244 } else {
245 $footerText = '&copy; ' . get_bloginfo('name', 'display') . '.';
246 }
247
248 return apply_filters('fluentform_email_template_footer_text', $footerText, $form, $notification);
249 }
250
251 private function getHeaders($notification, $isSendAsPlain = false)
252 {
253 $headers = [
254 'Content-Type: text/html; charset=utf-8'
255 ];
256
257 if ($isSendAsPlain) {
258 $headers = [];
259 }
260
261 $fromEmail = $notification['fromEmail'];
262
263 if (!is_email($fromEmail)) {
264 $fromEmail = false;
265 }
266
267 if ($notification['fromName'] && $fromEmail) {
268 $headers[] = "From: {$notification['fromName']} <{$fromEmail}>";
269 } elseif ($fromEmail) {
270 $headers[] = "From: <{$fromEmail}>";
271 }
272
273 if (!empty($notification['bcc'])) {
274 $bccEmail = $notification['bcc'];
275 $headers[] = 'bcc: ' . $bccEmail;
276 }
277
278 if (!empty($notification['cc'])) {
279 $ccEmail = $notification['cc'];
280 $headers[] = 'cc: ' . $ccEmail;
281 }
282
283 if ($notification['replyTo'] && is_email($notification['replyTo'])) {
284 $headers[] = "Reply-To: <" . $notification['replyTo'] . ">";
285 }
286
287 $headers = $this->app->applyFilters(
288 'fluenttform_email_header', $headers, $notification
289 );
290
291 return $headers;
292 }
293
294 }
295