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

293 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 = [
144 ArrayHelper::get($notification, 'sendTo.email')
145 ];
146
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');
152 }
153
154 if (ArrayHelper::get($notification, 'sendTo.type') != 'routing') {
155 return $sendAddresses;
156 }
157
158 $routings = ArrayHelper::get($notification, 'sendTo.routing');
159 $validAddresses = [];
160 foreach ($routings as $routing) {
161 $inputValue = ArrayHelper::get($routing, 'input_value');
162 if(!$inputValue || !is_email($inputValue)) {
163 continue;
164 }
165 $condition = [
166 'conditionals' => [
167 'status' => true,
168 'type' => 'any',
169 'conditions' => [
170 $routing
171 ]
172 ]
173 ];
174 if (\FluentForm\App\Services\ConditionAssesor::evaluate($condition, $submittedData)) {
175 $validAddresses[] = $inputValue;
176 }
177 }
178
179 return $validAddresses;
180 }
181
182 /**
183 * @param $formId
184 * @return array
185 * @todo: Implement Caching mechanism so we don't have to parse these things for every request
186 */
187 private function getFormInputsAndLabels($form)
188 {
189 $formInputs = FormFieldsParser::getInputs($form);
190
191 $inputLabels = FormFieldsParser::getAdminLabels($form, $formInputs);
192
193 return [
194 'inputs' => $formInputs,
195 'labels' => $inputLabels
196 ];
197 }
198
199 public function getEmailWithTemplate($emailBody, $form, $notification)
200 {
201 $originalEmailBody = $emailBody;
202 $emailHeader = apply_filters('fluentform_email_header', '', $form, $notification);
203 $emailFooter = apply_filters('fluentform_email_footer', '', $form, $notification);
204
205 if (empty($emailHeader)) {
206 $emailHeader = View::make('email.template.header', array(
207 'form' => $form,
208 'notification' => $notification
209 ));
210 }
211
212 if (empty($emailFooter)) {
213 $emailFooter = View::make('email.template.footer', array(
214 'form' => $form,
215 'notification' => $notification,
216 'footerText' => $this->getFooterText($form, $notification)
217 ));
218 }
219
220 $css = View::make('email.template.styles');
221 $css = apply_filters('fluentform_email_styles', $css, $form, $notification);
222 $emailBody = $emailHeader . $emailBody . $emailFooter;
223
224 ob_start();
225 try {
226 // apply CSS styles inline for picky email clients
227 $emogrifier = new Emogrifier($emailBody, $css);
228 $emailBody = $emogrifier->emogrify();
229 } catch (\Exception $e) {
230
231 }
232 $maybeError = ob_get_clean();
233
234 if ($maybeError) {
235 return $originalEmailBody;
236 }
237
238 return $emailBody;
239 }
240
241 private function getFooterText($form, $notification)
242 {
243 $option = get_option('_fluentform_global_form_settings');
244 if ($option && !empty($option['misc']['email_footer_text'])) {
245 $footerText = $option['misc']['email_footer_text'];
246 } else {
247 $footerText = '&copy; ' . get_bloginfo('name', 'display') . '.';
248 }
249
250 return apply_filters('fluentform_email_template_footer_text', $footerText, $form, $notification);
251 }
252
253 public function getHeaders($notification, $isSendAsPlain = false)
254 {
255 $headers = [
256 'Content-Type: text/html; charset=utf-8'
257 ];
258
259 $fromEmail = $notification['fromEmail'];
260
261 if (!is_email($fromEmail)) {
262 $fromEmail = false;
263 }
264
265 if ($notification['fromName'] && $fromEmail) {
266 $headers[] = "From: {$notification['fromName']} <{$fromEmail}>";
267 } elseif ($fromEmail) {
268 $headers[] = "From: <{$fromEmail}>";
269 }
270
271 if (!empty($notification['bcc'])) {
272 $bccEmail = $notification['bcc'];
273 $headers[] = 'bcc: ' . $bccEmail;
274 }
275
276 if (!empty($notification['cc'])) {
277 $ccEmail = $notification['cc'];
278 $headers[] = 'cc: ' . $ccEmail;
279 }
280
281 if ($notification['replyTo'] && is_email($notification['replyTo'])) {
282 $headers[] = "Reply-To: <" . $notification['replyTo'] . ">";
283 }
284
285 $headers = $this->app->applyFilters(
286 'fluenttform_email_header', $headers, $notification
287 );
288
289 return $headers;
290 }
291
292 }
293