PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.5
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.5
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / stripe / controllers / FrmTransLiteActionsController.php

FrmTransLiteActionsController.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.5, at stripe/controllers/FrmTransLiteActionsController.php

374 lines 10.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 die( 'You are not allowed to call this page directly.' );
4 }
5
6 class FrmTransLiteActionsController {
7
8 /**
9 * Register payment action type.
10 *
11 * @param array $actions
12 * @return array
13 */
14 public static function register_actions( $actions ) {
15 $actions['payment'] = 'FrmTransLiteAction';
16 return $actions;
17 }
18
19 /**
20 * Include scripts for handling payments at an administrative level.
21 * This includes handling the after payment settings for Stripe actions.
22 * It also handles refunds and canceling subscriptions.
23 *
24 * @return void
25 */
26 public static function actions_js() {
27 wp_enqueue_script(
28 'frmtrans_admin',
29 FrmTransLiteAppHelper::plugin_url() . '/js/frmtrans_admin.js',
30 array( 'jquery' ),
31 FrmAppHelper::plugin_version()
32 );
33 wp_localize_script(
34 'frmtrans_admin',
35 'frm_trans_vars',
36 array(
37 'nonce' => wp_create_nonce( 'frm_trans_ajax' ),
38 )
39 );
40 }
41
42 /**
43 * Add event types for actions so an email can trigger on a successful payment.
44 *
45 * @param array $triggers
46 * @return array
47 */
48 public static function add_payment_trigger( $triggers ) {
49 $triggers['payment-success'] = __( 'Successful Payment', 'formidable' );
50 $triggers['payment-failed'] = __( 'Failed Payment', 'formidable' );
51 $triggers['payment-processing'] = __( 'Processing Payment', 'formidable' );
52 $triggers['payment-future-cancel'] = __( 'Canceled Subscription', 'formidable' );
53 $triggers['payment-canceled'] = __( 'Subscription Canceled and Expired', 'formidable' );
54 return $triggers;
55 }
56
57 /**
58 * @param array $options
59 * @return array
60 */
61 public static function add_trigger_to_action( $options ) {
62 $options['event'][] = 'payment-success';
63 $options['event'][] = 'payment-failed';
64 $options['event'][] = 'payment-processing';
65 $options['event'][] = 'payment-future-cancel';
66 $options['event'][] = 'payment-canceled';
67 return $options;
68 }
69
70 /**
71 * @param WP_Post $action
72 * @param stdClass $entry
73 * @param mixed $form
74 * @return void
75 */
76 public static function trigger_action( $action, $entry, $form ) {
77 self::prepare_description( $action, compact( 'entry', 'form' ) );
78 FrmStrpLiteActionsController::trigger_gateway( $action, $entry, $form );
79 }
80
81 /**
82 * @param WP_Post $action
83 * @param stdClass $entry
84 * @param mixed $form
85 * @return array
86 */
87 public static function trigger_gateway( $action, $entry, $form ) {
88 // This function must be overridden in a subclass.
89 return array(
90 'success' => false,
91 'run_triggers' => false,
92 'show_errors' => true,
93 );
94 }
95
96 /**
97 * @return string
98 */
99 public static function force_message_after_create() {
100 return 'message';
101 }
102
103 /**
104 * @since 6.5, introduced in v1.12 of the Payments submodule.
105 *
106 * @param object $sub
107 * @return void
108 */
109 public static function trigger_subscription_status_change( $sub ) {
110 $frm_payment = new FrmTransLitePayment();
111 $payment = $frm_payment->get_one_by( $sub->id, 'sub_id' );
112
113 if ( $payment && $payment->action_id ) {
114 self::trigger_payment_status_change(
115 array(
116 'status' => $sub->status,
117 'payment' => $payment,
118 )
119 );
120 }
121 }
122
123 /**
124 * @param array $atts
125 * @return void
126 */
127 public static function trigger_payment_status_change( $atts ) {
128 $action = isset( $atts['action'] ) ? $atts['action'] : $atts['payment']->action_id;
129 $entry_id = isset( $atts['entry'] ) ? $atts['entry']->id : $atts['payment']->item_id;
130 $atts = array(
131 'trigger' => $atts['status'],
132 'entry_id' => $entry_id,
133 );
134
135 if ( ! isset( $atts['payment'] ) ) {
136 $frm_payment = new FrmTransLitePayment();
137 $atts['payment'] = $frm_payment->get_one_by( $entry_id, 'item_id' );
138 }
139
140 if ( ! isset( $atts['trigger'] ) ) {
141 $atts['trigger'] = $atts['status'];
142 }
143
144 // Set future-cancel as trigger when applicable.
145 $atts['trigger'] = str_replace( '_', '-', $atts['trigger'] );
146
147 if ( $atts['payment'] ) {
148 self::trigger_actions_after_payment( $atts['payment'], $atts );
149 }
150 }
151
152 /**
153 * Maybe trigger payment-success or payment-failed event after payment so actions (like emails) can run.
154 *
155 * @param object $payment
156 * @param array $atts
157 * @return void
158 */
159 public static function trigger_actions_after_payment( $payment, $atts = array() ) {
160 if ( ! is_callable( 'FrmFormActionsController::trigger_actions' ) ) {
161 return;
162 }
163
164 if ( 'pending' === $payment->status ) {
165 // 3D Secure has a delayed payment status, so avoid sending a payment failed email for a pending payment.
166 return;
167 }
168
169 $entry = FrmEntry::getOne( $payment->item_id );
170
171 if ( isset( $atts['trigger'] ) ) {
172 $trigger_event = 'payment-' . $atts['trigger'];
173 } else {
174 $trigger_event = 'payment-' . $payment->status;
175 }
176
177 $allowed_triggers = array_keys( self::add_payment_trigger( array() ) );
178 if ( ! in_array( $trigger_event, $allowed_triggers, true ) ) {
179 $trigger_event = ( $payment->status === 'complete' ) ? 'payment-success' : 'payment-failed';
180 }
181 FrmFormActionsController::trigger_actions( $trigger_event, $entry->form_id, $entry->id );
182 }
183
184 /**
185 * Filter fields in description.
186 *
187 * @param WP_Post $action
188 * @param array $atts
189 * @return void
190 */
191 public static function prepare_description( &$action, $atts ) {
192 $description = $action->post_content['description'];
193 if ( ! empty( $description ) ) {
194 $atts['value'] = $description;
195 $description = FrmTransLiteAppHelper::process_shortcodes( $atts );
196 $action->post_content['description'] = $description;
197 }
198 }
199
200 /**
201 * Convert the amount into 10.00.
202 *
203 * @param mixed $amount
204 * @param array $atts
205 * @return string
206 */
207 public static function prepare_amount( $amount, $atts = array() ) {
208 if ( isset( $atts['form'] ) ) {
209 $atts['value'] = $amount;
210 $amount = FrmTransLiteAppHelper::process_shortcodes( $atts );
211 }
212
213 if ( is_string( $amount ) && strlen( $amount ) >= 2 && $amount[0] == '[' && substr( $amount, -1 ) == ']' ) {
214 // make sure we don't use a field id as the amount
215 $amount = 0;
216 }
217
218 $currency = self::get_currency_for_action( $atts );
219
220 $total = 0;
221 foreach ( (array) $amount as $a ) {
222 $this_amount = self::get_amount_from_string( $a );
223 self::maybe_use_decimal( $this_amount, $currency );
224 self::normalize_number( $this_amount, $currency );
225
226 $total += $this_amount;
227 unset( $a, $this_amount );
228 }
229
230 return number_format( $total, $currency['decimals'], '.', '' );
231 }
232
233 /**
234 * Get currency to use when preparing amount.
235 *
236 * @param array $atts
237 * @return array
238 */
239 public static function get_currency_for_action( $atts ) {
240 $currency = 'usd';
241 if ( isset( $atts['form'] ) ) {
242 $currency = $atts['action']->post_content['currency'];
243 } elseif ( isset( $atts['currency'] ) ) {
244 $currency = $atts['currency'];
245 }
246
247 return FrmCurrencyHelper::get_currency( $currency );
248 }
249
250 /**
251 * @param string $amount
252 *
253 * @return string
254 */
255 private static function get_amount_from_string( $amount ) {
256 $amount = html_entity_decode( $amount );
257 $amount = trim( $amount );
258 preg_match_all( '/[0-9,.]*\.?\,?[0-9]+/', $amount, $matches );
259 $amount = $matches ? end( $matches[0] ) : 0;
260 return $amount;
261 }
262
263 /**
264 * @param string $amount
265 * @param array $currency
266 * @return void
267 */
268 private static function maybe_use_decimal( &$amount, $currency ) {
269 if ( $currency['thousand_separator'] !== '.' ) {
270 return;
271 }
272
273 $amount_parts = explode( '.', $amount );
274 $used_for_decimal = count( $amount_parts ) === 2 && strlen( $amount_parts[1] ) === 2;
275 if ( $used_for_decimal ) {
276 $amount = str_replace( '.', $currency['decimal_separator'], $amount );
277 }
278 }
279
280 /**
281 * @param string $amount
282 * @param array $currency
283 * @return void
284 */
285 private static function normalize_number( &$amount, $currency ) {
286 $amount = str_replace( $currency['thousand_separator'], '', $amount );
287 $amount = str_replace( $currency['decimal_separator'], '.', $amount );
288 $amount = number_format( (float) $amount, $currency['decimals'], '.', '' );
289 }
290
291 /**
292 * These settings are included in frm_stripe_vars.settings global JavaScript object on Stripe forms.
293 *
294 * @param int $form_id
295 * @return array
296 */
297 public static function prepare_settings_for_js( $form_id ) {
298 $payment_actions = self::get_actions_for_form( $form_id );
299 $action_settings = array();
300 foreach ( $payment_actions as $payment_action ) {
301 $settings_for_action = array(
302 'id' => $payment_action->ID,
303 'first_name' => $payment_action->post_content['billing_first_name'],
304 'last_name' => $payment_action->post_content['billing_last_name'],
305 'gateways' => $payment_action->post_content['gateway'],
306 'fields' => self::get_fields_for_price( $payment_action ),
307 'one' => $payment_action->post_content['type'],
308 'email' => $payment_action->post_content['email'],
309 );
310
311 /**
312 * @param array $settings_for_action
313 * @param WP_Post $payment_action
314 */
315 $settings_for_action = apply_filters( 'frm_trans_settings_for_js', $settings_for_action, $payment_action );
316 $action_settings[] = $settings_for_action;
317 }
318
319 return $action_settings;
320 }
321
322 /**
323 * Include the price field ids to pass to the javascript.
324 *
325 * @since 6.5, introduced in v2.0 of the Payments submodule.
326 *
327 * @param WP_Post $action
328 * @return array|int
329 */
330 private static function get_fields_for_price( $action ) {
331 $amount = $action->post_content['amount'];
332 $shortcodes = FrmFieldsHelper::get_shortcodes( $amount, $action->menu_order );
333 return isset( $shortcodes[2] ) ? $shortcodes[2] : -1;
334 }
335
336 /**
337 * Get all published payment actions.
338 *
339 * @param int|string $form_id
340 * @return array
341 */
342 public static function get_actions_for_form( $form_id ) {
343 $action_status = array(
344 'post_status' => 'publish',
345 );
346 $payment_actions = FrmFormAction::get_action_for_form( $form_id, 'payment', $action_status );
347 if ( ! $payment_actions ) {
348 $payment_actions = array();
349 }
350 return $payment_actions;
351 }
352
353 /**
354 * Make sure a gateway field is hidden on the front end.
355 *
356 * @param array $values
357 * @param stdClass $field
358 * @return array
359 */
360 public static function hide_gateway_field_on_front_end( $values, $field ) {
361 if ( $field->type !== 'gateway' ) {
362 return $values;
363 }
364
365 // This is also called from the frm_enqueue_form_scripts hook.
366 // With this here, the value of frm_stripe_vars.settings[0].fields is -1
367 // This is because the amount value is processed and a shortcode is not found in '000'.
368 FrmStrpLiteActionsController::load_scripts( (int) $field->form_id );
369
370 $values['type'] = 'hidden';
371 return $values;
372 }
373 }
374