PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.14
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.14
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 / EmailNotificationActions.php

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

248 lines 8.5 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\App\Helpers\Helper;
8 use FluentForm\App\Modules\Form\FormFieldsParser;
9 use FluentForm\App\Services\FormBuilder\ShortCodeParser;
10 use FluentForm\Framework\Foundation\Application;
11 use FluentForm\Framework\Helpers\ArrayHelper;
12
13 class EmailNotificationActions
14 {
15 protected $app = null;
16
17 public function __construct(Application $app)
18 {
19 $this->app = $app;
20 }
21
22 public function register()
23 {
24 add_filter('fluentform/notifying_async_email_notifications', '__return_false', 9);
25 add_filter('fluentform/notifying_async_notifications', '__return_false', 9);
26
27 add_filter('fluentform/global_notification_active_types', function ($types) {
28 $types['notifications'] = 'email_notifications';
29 return $types;
30 });
31
32 add_action('fluentform/integration_notify_notifications', [$this, 'notify'], 10, 4);
33
34 add_action('fluentform/notify_on_form_submit', [$this, 'notifyOnSubmitPaymentForm'], 10, 3);
35 }
36
37 public function notifyOnSubmitPaymentForm($submissionId, $submissionData, $form)
38 {
39 $emailFeeds = wpFluent()->table('fluentform_form_meta')
40 ->where('form_id', $form->id)
41 ->where('meta_key', 'notifications')
42 ->get();
43
44 if (count($emailFeeds) === 0) {
45 return;
46 }
47
48 $formData = $this->getFormData($submissionId);
49 $notificationManager = new \FluentForm\App\Services\Integrations\GlobalNotificationManager(wpFluentForm());
50
51 $activeEmailFeeds = $notificationManager->getEnabledFeeds($emailFeeds, $formData, $submissionId);
52 if (! $activeEmailFeeds) {
53 return;
54 }
55
56 $onSubmitEmailFeeds = array_filter($activeEmailFeeds, function ($feed) {
57 return 'payment_form_submit' == ArrayHelper::get($feed, 'settings.feed_trigger_event');
58 });
59
60 if (! $onSubmitEmailFeeds || 'yes' === Helper::getSubmissionMeta($submissionId, '_ff_on_submit_email_sent')) {
61 return;
62 }
63
64 $entry = $this->getEntry($submissionId);
65
66 foreach ($onSubmitEmailFeeds as $feed) {
67 $processedValues = $feed['settings'];
68 unset($processedValues['conditionals']);
69
70 $processedValues = ShortCodeParser::parse(
71 $processedValues,
72 $submissionId,
73 $formData,
74 $form,
75 false,
76 $feed['meta_key']
77 );
78 $feed['processedValues'] = $processedValues;
79
80 $this->notify($feed, $formData, $entry, $form);
81 }
82
83 Helper::setSubmissionMeta($submissionId, '_ff_on_submit_email_sent', 'yes', $form->id);
84 }
85
86 public function notify($feed, $formData, $entry, $form)
87 {
88 // Defer a payment_success email only for a KNOWN unsettled status. An empty
89 // status is a genuine $0 order (an all-optional form or a 100% coupon, no payment
90 // attempted) and still confirms; any status NOT in the deny-list still sends, so a
91 // custom/settled status a gateway registers via fluentform/available_payment_statuses
92 // is never silently dropped. Custom unsettled statuses extend the deny-list via
93 // fluentform/unsettled_payment_statuses. A non-success gateway return never reaches
94 // here as empty -- it is gated in the processor and left as its pending status.
95 if (isset($form->has_payment) && $form->has_payment) {
96 if (FormFieldsParser::hasElement($form, 'payment_method')) {
97 $isTriggerOnPaymentSuccess = ArrayHelper::get($feed, 'processedValues.feed_trigger_event') === 'payment_success';
98 if ($isTriggerOnPaymentSuccess) {
99 $paymentStatus = is_null($entry->payment_status ?? null) ? '' : (string) $entry->payment_status;
100 $unsettledStatuses = apply_filters('fluentform/unsettled_payment_statuses', [
101 'pending', 'failed', 'requires_review', 'cancelled', 'refunded', 'partially-refunded',
102 ]);
103 if (in_array($paymentStatus, $unsettledStatuses, true)) {
104 return;
105 }
106 }
107 }
108 }
109
110 $notifier = $this->app->make(
111 'FluentForm\App\Services\FormBuilder\Notifications\EmailNotification'
112 );
113
114 $emailData = $feed['processedValues'];
115 $emailAttachments = $this->getAttachments($emailData, $formData, $entry, $form);
116 if ($emailAttachments) {
117 $emailData['attachments'] = $emailAttachments;
118 }
119
120 $notifier->notify($emailData, $formData, $form, $entry->id);
121 }
122
123 /**
124 * @param $emailData
125 * @param $formData
126 * @param $entry
127 * @param $form
128 *
129 * @return array
130 */
131 private function getAttachments($emailData, $formData, $entry, $form)
132 {
133 $emailAttachments = [];
134
135 $uploadDir = wp_upload_dir();
136
137 if (!empty($emailData['attachments']) && is_array($emailData['attachments'])) {
138 $attachments = [];
139 foreach ($emailData['attachments'] as $name) {
140 $fileUrls = ArrayHelper::get($formData, $name);
141 if ($fileUrls && is_array($fileUrls)) {
142 foreach ($fileUrls as $url) {
143 $filePath = $this->resolveUploadAttachmentPath($url, $uploadDir);
144 if ($filePath) {
145 $attachments[] = $filePath;
146 }
147 }
148 }
149 }
150 $emailAttachments = $attachments;
151 }
152 $mediaAttachments = ArrayHelper::get($emailData, 'media_attachments');
153 if (!empty($mediaAttachments) && is_array($mediaAttachments)) {
154 $attachments = [];
155 foreach ($mediaAttachments as $file) {
156 $fileUrl = ArrayHelper::get($file, 'url');
157 $filePath = $this->resolveUploadAttachmentPath($fileUrl, $uploadDir);
158 if ($filePath) {
159 $attachments[] = $filePath;
160 }
161 }
162 $emailAttachments = array_merge($emailAttachments, $attachments);
163 }
164
165 $emailAttachments = apply_filters_deprecated(
166 'fluentform_email_attachments',
167 [
168 $emailAttachments,
169 $emailData,
170 $formData,
171 $entry,
172 $form
173 ],
174 FLUENTFORM_FRAMEWORK_UPGRADE,
175 'fluentform/email_attachments',
176 'Use fluentform/email_attachments instead of fluentform_email_attachments.'
177 );
178 // let others to apply attachments
179 $emailAttachments = apply_filters(
180 'fluentform/email_attachments',
181 $emailAttachments,
182 $emailData,
183 $formData,
184 $entry,
185 $form
186 );
187 return $emailAttachments;
188 }
189
190 private function resolveUploadAttachmentPath($fileUrl, $uploadDir)
191 {
192 if (!$fileUrl || empty($uploadDir['baseurl']) || empty($uploadDir['basedir'])) {
193 return null;
194 }
195
196 $normalizedUrl = strtok($fileUrl, '?#');
197 if (strpos($normalizedUrl, $uploadDir['baseurl']) !== 0) {
198 return null;
199 }
200
201 $relativePath = rawurldecode(str_replace($uploadDir['baseurl'], '', $normalizedUrl));
202 $relativePath = ltrim(wp_normalize_path($relativePath), '/');
203
204 if (!$relativePath || strpos($relativePath, '../') !== false) {
205 return null;
206 }
207
208 $uploadsBaseDir = realpath($uploadDir['basedir']);
209 if (!$uploadsBaseDir) {
210 return null;
211 }
212
213 $uploadsBaseDir = trailingslashit(wp_normalize_path($uploadsBaseDir));
214 $resolvedPath = realpath($uploadsBaseDir . $relativePath);
215
216 if (!$resolvedPath) {
217 return null;
218 }
219
220 $resolvedPath = wp_normalize_path($resolvedPath);
221 if (strpos($resolvedPath, $uploadsBaseDir) !== 0 || !is_file($resolvedPath)) {
222 return null;
223 }
224
225 return $resolvedPath;
226 }
227
228 public function getFormData($submissionId)
229 {
230 $submission = wpFluent()->table('fluentform_submissions')
231 ->where('id', $submissionId)
232 ->first();
233
234 if (! $submission) {
235 return false;
236 }
237
238 return json_decode($submission->response, true);
239 }
240
241 public function getEntry($submissionId)
242 {
243 return wpFluent()->table('fluentform_submissions')
244 ->where('id', $submissionId)
245 ->first();
246 }
247 }
248