PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
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
← All changes | stripe/controllers/FrmStrpLiteActionsController.php +92 -35 6.26 → trunk View file →
@@ -29,13 +29,9 @@
29 29
30 30 $form_id = is_object( $field ) ? $field->form_id : $field['form_id'];
31 31 $actions = self::get_actions_before_submit( $form_id );
32 32
33 - if ( empty( $actions ) ) {
34 - return $callback;
35 - }
36 -
37 - return self::class . '::show_card';
33 + return $actions ? self::class . '::show_card' : $callback;
38 34 }
39 35
40 36 /**
41 37 * Override the credit card field HTML if there is a Stripe action.
@@ -80,8 +76,9 @@
80 76 if ( ! $is_stripe || empty( $payment_action->post_content['amount'] ) ) {
81 77 unset( $payment_actions[ $k ] );
82 78 }
83 79 }
80 +
84 81 return $payment_actions;
85 82 }
86 83
87 84 /**
@@ -117,22 +114,22 @@
117 114 'run_triggers' => false,
118 115 'show_errors' => true,
119 116 );
120 117 $atts = compact( 'action', 'entry', 'form' );
118 + $amount = self::prepare_amount( $action->post_content['amount'], $atts );
121 119
122 - $amount = self::prepare_amount( $action->post_content['amount'], $atts );
123 -
124 - if ( empty( $amount ) || $amount == 000 ) {
120 + // phpcs:ignore Universal.Operators.StrictComparisons
121 + if ( ! $amount || $amount == 000 ) {
125 122 $response['error'] = __( 'Please specify an amount for the payment', 'formidable' );
126 123 return $response;
127 124 }
128 125
129 126 if ( ! self::stripe_is_configured() ) {
130 - $response['error'] = __( 'There was a problem communicating with Stripe. Please try again.', 'formidable' );
127 + $response['error'] = __( 'Stripe still needs to be configured.', 'formidable' );
131 128 return $response;
132 129 }
133 130
134 - $customer = self::set_customer_with_token( $atts );
131 + $customer = self::set_customer_with_token( $atts, self::get_customer_id_from_posted_setup_intents( $form->id ) );
135 132
136 133 if ( ! is_object( $customer ) ) {
137 134 $response['error'] = $customer;
138 135 return $response;
@@ -139,9 +136,13 @@
139 136 }
140 137
141 138 $one_time_payment_args = compact( 'customer', 'form', 'entry', 'action', 'amount' );
142 139
143 - FrmStrpLiteLinkController::create_pending_stripe_link_payment( $one_time_payment_args );
140 + if ( ! FrmStrpLiteLinkController::create_pending_stripe_link_payment( $one_time_payment_args ) ) {
141 + $response['error'] = __( 'There was something wrong with the payment data.', 'formidable' );
142 + return $response;
143 + }
144 +
144 145 $response['show_errors'] = false;
145 146 return $response;
146 147 }
147 148
@@ -154,15 +155,56 @@
154 155 return FrmStrpLiteAppHelper::call_stripe_helper_class( 'initialize_api' );
155 156 }
156 157
157 158 /**
159 + * Get the customer id from a setup intent that was created for this submission.
160 + * A Stripe Link subscription builds its subscription from the setup intent's customer,
161 + * so reusing that customer here avoids creating a duplicate customer for guests.
162 + *
163 + * @since 6.35
164 + *
165 + * @param int|string $form_id
166 + *
167 + * @return false|string The Stripe customer id, or false if it can't be found.
168 + */
169 + public static function get_customer_id_from_posted_setup_intents( $form_id ) {
170 + $posted_intents = FrmStrpLiteAuth::get_payment_intents( 'frmintent' . $form_id );
171 +
172 + if ( ! is_array( $posted_intents ) || ! $posted_intents ) {
173 + return false;
174 + }
175 +
176 + $setup_intent_ids = array_filter(
177 + $posted_intents,
178 + function ( $intent_id ) {
179 + return str_starts_with( $intent_id, 'seti_' );
180 + }
181 + );
182 +
183 + if ( ! $setup_intent_ids ) {
184 + return false;
185 + }
186 +
187 + $first_setup_intent_id = reset( $setup_intent_ids );
188 + $first_setup_intent_id = explode( '_secret_', $first_setup_intent_id )[0];
189 + $setup_intent = FrmStrpLiteAppHelper::call_stripe_helper_class( 'get_setup_intent', $first_setup_intent_id );
190 +
191 + if ( ! is_object( $setup_intent ) || empty( $setup_intent->customer ) ) {
192 + return false;
193 + }
194 +
195 + return $setup_intent->customer;
196 + }
197 +
198 + /**
158 199 * Set a customer object to $_POST['customer'] to use later.
159 200 *
160 - * @param array $atts
201 + * @param array $atts The action, entry, and form for the payment.
202 + * @param false|string $customer_id The Stripe customer id when it is already known.
161 203 *
162 204 * @return object|string
163 205 */
164 - private static function set_customer_with_token( $atts ) {
206 + private static function set_customer_with_token( $atts, $customer_id = false ) {
165 207 if ( isset( self::$customer ) ) {
166 208 // It's an object if this isn't the first Stripe action running.
167 209 return self::$customer;
168 210 }
@@ -170,8 +212,12 @@
170 212 $payment_info = array(
171 213 'user_id' => FrmTransLiteAppHelper::get_user_id_for_current_payment(),
172 214 );
173 215
216 + if ( $customer_id ) {
217 + $payment_info['customer_id'] = $customer_id;
218 + }
219 +
174 220 if ( ! empty( $atts['action']->post_content['email'] ) ) {
175 221 $payment_info['email'] = apply_filters( 'frm_content', $atts['action']->post_content['email'], $atts['form'], $atts['entry'] );
176 222 $payment_info['email'] = self::replace_email_shortcode( $payment_info['email'] );
177 223 }
@@ -192,9 +238,9 @@
192 238 *
193 239 * @return string
194 240 */
195 241 private static function replace_email_shortcode( $email ) {
196 - if ( false === strpos( $email, '[email]' ) ) {
242 + if ( ! str_contains( $email, '[email]' ) ) {
197 243 return $email;
198 244 }
199 245
200 246 global $current_user;
@@ -284,11 +330,17 @@
284 330 *
285 331 * @return array
286 332 */
287 333 public static function add_action_defaults( $defaults ) {
334 + // Stripe action options.
288 335 $defaults['plan_id'] = '';
289 336 $defaults['capture'] = '';
290 337 $defaults['stripe_link'] = '';
338 +
339 + // PayPal action options.
340 + $defaults['product_name'] = '';
341 + $defaults['pay_later'] = '';
342 +
291 343 return $defaults;
292 344 }
293 345
294 346 /**
@@ -315,10 +367,10 @@
315 367 public static function before_save_settings( $settings, $action ) {
316 368 $settings['currency'] = strtolower( $settings['currency'] );
317 369
318 370 // Gateway is a radio button but it should always be an array in the database for
319 - // compatibility with the payments submodule where it is a checkbox.
320 - $settings['gateway'] = ! empty( $settings['gateway'] ) ? (array) $settings['gateway'] : array( 'stripe' );
371 + // compatibility with the payments submodule where it is a checkbox (when Authorize.Net is active).
372 + $settings['gateway'] = ! empty( $settings['gateway'] ) ? (array) $settings['gateway'] : array( 'stripe' );
321 373
322 374 $is_stripe = in_array( 'stripe', $settings['gateway'], true );
323 375
324 376 if ( ! $is_stripe ) {
@@ -326,11 +378,10 @@
326 378 }
327 379
328 380 // In Lite Stripe link is always used.
329 381 $settings['stripe_link'] = 1;
330 - $settings = self::create_plans( $settings );
331 382
332 - return $settings;
383 + return self::create_plans( $settings );
333 384 }
334 385
335 386 /**
336 387 * Create any required Stripe plans, used for subscriptions.
@@ -347,8 +398,9 @@
347 398 }
348 399
349 400 $plan_opts = FrmStrpLiteSubscriptionHelper::prepare_plan_options( $settings );
350 401
402 + // phpcs:ignore Universal.Operators.StrictComparisons
351 403 if ( $plan_opts['id'] != $settings['plan_id'] ) {
352 404 $settings['plan_id'] = FrmStrpLiteSubscriptionHelper::maybe_create_plan( $plan_opts );
353 405 }
354 406
@@ -363,10 +415,21 @@
363 415 * @return string
364 416 */
365 417 public static function create_plan_id( $settings ) {
366 418 $amount = self::prepare_amount( $settings['amount'], $settings );
367 - $id = sanitize_title_with_dashes( $settings['description'] ) . '_' . $amount . '_' . $settings['interval_count'] . $settings['interval'] . '_' . $settings['currency'];
368 - return $id;
419 + $parts = array(
420 + sanitize_title_with_dashes( $settings['description'] ),
421 + $amount,
422 + $settings['interval_count'] . $settings['interval'],
423 + $settings['currency'],
424 + );
425 +
426 + if ( isset( $settings['trial_interval_count'] ) && '' !== $settings['trial_interval_count'] ) {
427 + // Include the trial so two actions that differ only by trial length don't share a plan.
428 + $parts[] = $settings['trial_interval_count'];
429 + }
430 +
431 + return implode( '_', $parts );
369 432 }
370 433
371 434 /**
372 435 * If this form submits with ajax, load the scripts on the first page.
@@ -375,8 +438,9 @@
375 438 *
376 439 * @return void
377 440 */
378 441 public static function maybe_load_scripts( $params ) {
442 + // phpcs:ignore Universal.Operators.StrictComparisons
379 443 if ( $params['form_id'] == $params['posted_form_id'] ) {
380 444 // This form has already been posted, so we aren't on the first page.
381 445 return;
382 446 }
@@ -460,16 +524,20 @@
460 524
461 525 $action_settings = self::prepare_settings_for_js( $form_id );
462 526 $found_gateway = false;
463 527
464 - foreach ( $action_settings as $action ) {
528 + foreach ( $action_settings as &$action ) {
465 529 $gateways = $action['gateways'];
466 530
467 531 if ( ! $gateways || in_array( 'stripe', (array) $gateways, true ) ) {
468 532 $found_gateway = true;
469 - break;
470 533 }
534 +
535 + if ( ! empty( $action['layout'] ) && ! in_array( $action['layout'], array( 'accordion', 'tabs' ), true ) ) {
536 + $action['layout'] = '';
537 + }
471 538 }
539 + unset( $action );
472 540
473 541 if ( ! $found_gateway ) {
474 542 return;
475 543 }
@@ -581,10 +649,9 @@
581 649 *
582 650 * @param array $rules
583 651 * @param array $settings
584 652 */
585 - $rules = apply_filters( 'frm_stripe_appearance_rules', $rules, $settings );
586 - return $rules;
653 + return apply_filters( 'frm_stripe_appearance_rules', $rules, $settings );
587 654 }
588 655
589 656 /**
590 657 * Get the border width for Stripe elements.
@@ -657,17 +724,7 @@
657 724 if ( ! $has_processed ) {
658 725 return $errors;
659 726 }
660 727
661 - $field_id = $field->temp_id ?? $field->id;
662 -
663 - if ( isset( $errors[ 'field' . $field_id . '-cc' ] ) ) {
664 - unset( $errors[ 'field' . $field_id . '-cc' ] );
665 - }
666 -
667 - if ( isset( $errors[ 'field' . $field_id ] ) ) {
668 - unset( $errors[ 'field' . $field_id ] );
669 - }
670 -
671 - return $errors;
728 + return FrmTransLiteActionsController::remove_cc_errors( $errors, $field );
672 729 }
673 730 }