PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.15
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.15
6.2.15 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 All 197 releases
← All changes | app/Services/FormBuilder/Notifications/EmailNotificationActions.php +25 -21 6.2.14 → 6.2.15 View file →
@@ -4,9 +4,8 @@
4 4
5 5 defined('ABSPATH') or die;
6 6
7 7 use FluentForm\App\Helpers\Helper;
8 -use FluentForm\App\Modules\Form\FormFieldsParser;
9 8 use FluentForm\App\Services\FormBuilder\ShortCodeParser;
10 9 use FluentForm\Framework\Foundation\Application;
11 10 use FluentForm\Framework\Helpers\ArrayHelper;
12 11
@@ -84,28 +83,13 @@
84 83 }
85 84
86 85 public function notify($feed, $formData, $entry, $form)
87 86 {
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 - }
87 + // A payment_success email asserts a settled charge, so gate it on the payment status
88 + // for every payment form -- not only those with a Payment Method field.
89 + $isTriggerOnPaymentSuccess = ArrayHelper::get($feed, 'processedValues.feed_trigger_event') === 'payment_success';
90 + if (!empty($form->has_payment) && $isTriggerOnPaymentSuccess && !$this->paymentSucceeded($entry, $form)) {
91 + return;
108 92 }
109 93
110 94 $notifier = $this->app->make(
111 95 'FluentForm\App\Services\FormBuilder\Notifications\EmailNotification'
@@ -117,8 +101,28 @@
117 101 $emailData['attachments'] = $emailAttachments;
118 102 }
119 103
120 104 $notifier->notify($emailData, $formData, $form, $entry->id);
105 + }
106 +
107 + // Whether a payment_success trigger may fire for this entry.
108 + protected function paymentSucceeded($entry, $form)
109 + {
110 + $paymentStatus = is_null($entry->payment_status ?? null) ? '' : (string) $entry->payment_status;
111 +
112 + // Settled → a custom/settled status a gateway registered still fires; it is only the
113 + // known-unsettled ones that defer.
114 + if ('' !== $paymentStatus) {
115 + $unsettledStatuses = apply_filters('fluentform/unsettled_payment_statuses', [
116 + 'pending', 'failed', 'requires_review', 'cancelled', 'refunded', 'partially-refunded',
117 + ]);
118 + return !in_array($paymentStatus, $unsettledStatuses, true);
119 + }
120 +
121 + // Empty status is a $0 order: fulfil a coupon-zeroed purchase, not an omitted or zeroed input.
122 + $isFreeOrder = 'yes' === Helper::getSubmissionMeta($entry->id, '_ff_zero_total_free_order');
123 +
124 + return (bool) apply_filters('fluentform/send_payment_success_on_zero_total', $isFreeOrder, $entry, $form);
121 125 }
122 126
123 127 /**
124 128 * @param $emailData