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

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