| @@ -62,10 +62,9 @@ | ||
| 62 | 62 | if ( $intent_is_processing ) { |
| 63 | 63 | // Append an additional processing message to the end of the success message. |
| 64 | 64 | $filter = function ( $message ) { |
| 65 | 65 | $stripe_settings = FrmStrpLiteAppHelper::get_settings(); |
| 66 | - $message .= '<p>' . esc_html( $stripe_settings->settings->processing_message ) . '</p>'; | |
| 67 | - return $message; | |
| 66 | + return $message . ( '<p>' . esc_html( $stripe_settings->settings->processing_message ) . '</p>' ); | |
| 68 | 67 | }; |
| 69 | 68 | add_filter( 'frm_content', $filter ); |
| 70 | 69 | } |
| 71 | 70 | |
| @@ -70,10 +69,9 @@ | ||
| 70 | 69 | } |
| 71 | 70 | |
| 72 | 71 | ob_start(); |
| 73 | 72 | FrmFormsController::run_on_submit_actions( $atts ); |
| 74 | - $message = ob_get_contents(); | |
| 75 | - ob_end_clean(); | |
| 73 | + $message = ob_get_clean(); | |
| 76 | 74 | |
| 77 | 75 | // Clean up the filter we added above so no other success messages get altered if there are multiple forms. |
| 78 | 76 | if ( $intent_is_processing ) { |
| 79 | 77 | remove_filter( 'frm_content', $filter ); |
| @@ -117,9 +115,9 @@ | ||
| 117 | 115 | private static function check_html_for_form_id_match( $html ) { |
| 118 | 116 | foreach ( self::$form_ids as $form_id ) { |
| 119 | 117 | $substring = '<input type="hidden" name="form_id" value="' . $form_id . '"'; |
| 120 | 118 | |
| 121 | - if ( strpos( $html, $substring ) ) { | |
| 119 | + if ( str_contains( $html, $substring ) ) { | |
| 122 | 120 | return $form_id; |
| 123 | 121 | } |
| 124 | 122 | } |
| 125 | 123 | |
| @@ -153,8 +151,10 @@ | ||
| 153 | 151 | case 'create_subscription_failed': |
| 154 | 152 | return __( 'Something went wrong when trying to create a subscription.', 'formidable' ); |
| 155 | 153 | case 'payment_failed': |
| 156 | 154 | return __( 'Payment was not successfully processed.', 'formidable' ); |
| 155 | + case 'amount_mismatch': | |
| 156 | + return __( 'The payment amount does not match the expected amount.', 'formidable' ); | |
| 157 | 157 | } |
| 158 | 158 | return ''; |
| 159 | 159 | } |
| 160 | 160 | |
| @@ -174,14 +174,16 @@ | ||
| 174 | 174 | $atts['conf_method'] = ! empty( $atts['form']->options[ $opt ] ) ? $atts['form']->options[ $opt ] : 'message'; |
| 175 | 175 | |
| 176 | 176 | $actions = FrmFormsController::get_met_on_submit_actions( $atts, 'create' ); |
| 177 | 177 | |
| 178 | - if ( $actions ) { | |
| 179 | - $action = reset( $actions ); | |
| 178 | + if ( ! $actions ) { | |
| 179 | + return; | |
| 180 | + } | |
| 180 | 181 | |
| 181 | - if ( ! empty( $action->post_content['success_action'] ) && 'message' === $action->post_content['success_action'] ) { | |
| 182 | - $atts['conf_method'] = $action->post_content['success_action']; | |
| 183 | - } | |
| 182 | + $action = reset( $actions ); | |
| 183 | + | |
| 184 | + if ( ! empty( $action->post_content['success_action'] ) && 'message' === $action->post_content['success_action'] ) { | |
| 185 | + $atts['conf_method'] = $action->post_content['success_action']; | |
| 184 | 186 | } |
| 185 | 187 | } |
| 186 | 188 | |
| 187 | 189 | /** |
| @@ -212,9 +214,9 @@ | ||
| 212 | 214 | */ |
| 213 | 215 | public static function add_hidden_token_field( $form ) { |
| 214 | 216 | $posted_form = FrmAppHelper::get_param( 'form_id', 0, 'post', 'absint' ); |
| 215 | 217 | |
| 216 | - if ( $posted_form != $form->id || FrmFormsController::just_created_entry( $form->id ) ) { | |
| 218 | + if ( $posted_form !== (int) $form->id || FrmFormsController::just_created_entry( $form->id ) ) { | |
| 217 | 219 | // Check to make sure the correct form was submitted. |
| 218 | 220 | // Was an entry already created and the form should be loaded fresh? |
| 219 | 221 | |
| 220 | 222 | $intents = self::maybe_create_intents( $form->id ); |
| @@ -224,10 +226,10 @@ | ||
| 224 | 226 | } |
| 225 | 227 | |
| 226 | 228 | $intents = self::get_payment_intents( 'frmintent' . $form->id ); |
| 227 | 229 | |
| 228 | - if ( ! empty( $intents ) ) { | |
| 229 | - self::update_intent_pricing( $form->id, $intents ); | |
| 230 | + if ( $intents ) { | |
| 231 | + self::update_intent_pricing( $form->id, $intents, $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing | |
| 230 | 232 | } else { |
| 231 | 233 | $intents = self::maybe_create_intents( $form->id ); |
| 232 | 234 | } |
| 233 | 235 | |
| @@ -272,9 +274,10 @@ | ||
| 272 | 274 | if ( ! isset( $_POST[ $name ] ) ) { |
| 273 | 275 | return array(); |
| 274 | 276 | } |
| 275 | 277 | |
| 276 | - $intents = $_POST[ $name ]; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing | |
| 278 | + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing | |
| 279 | + $intents = $_POST[ $name ]; | |
| 277 | 280 | FrmAppHelper::sanitize_value( 'sanitize_text_field', $intents ); |
| 278 | 281 | return $intents; |
| 279 | 282 | } |
| 280 | 283 | |
| @@ -291,9 +294,10 @@ | ||
| 291 | 294 | if ( empty( $_POST['form'] ) ) { |
| 292 | 295 | wp_die(); |
| 293 | 296 | } |
| 294 | 297 | |
| 295 | - $form = json_decode( stripslashes( $_POST['form'] ), true ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized | |
| 298 | + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized | |
| 299 | + $form = json_decode( stripslashes( $_POST['form'] ), true ); | |
| 296 | 300 | |
| 297 | 301 | if ( ! is_array( $form ) ) { |
| 298 | 302 | wp_die(); |
| 299 | 303 | } |
| @@ -302,24 +306,23 @@ | ||
| 302 | 306 | |
| 303 | 307 | $form_id = absint( $form['form_id'] ); |
| 304 | 308 | $intents = $form[ 'frmintent' . $form_id ] ?? array(); |
| 305 | 309 | |
| 306 | - if ( empty( $intents ) ) { | |
| 310 | + if ( ! $intents ) { | |
| 307 | 311 | wp_die(); |
| 308 | 312 | } |
| 309 | 313 | |
| 310 | - if ( ! is_array( $intents ) ) { | |
| 311 | - $intents = array( $intents ); | |
| 312 | - } else { | |
| 314 | + if ( is_array( $intents ) ) { | |
| 313 | 315 | foreach ( $intents as $k => $intent ) { |
| 314 | 316 | if ( is_array( $intent ) && isset( $intent[ $k ] ) ) { |
| 315 | 317 | $intents[ $k ] = $intent[ $k ]; |
| 316 | 318 | } |
| 317 | 319 | } |
| 320 | + } else { | |
| 321 | + $intents = array( $intents ); | |
| 318 | 322 | } |
| 319 | 323 | |
| 320 | - $_POST = $form; | |
| 321 | - self::update_intent_pricing( $form_id, $intents ); | |
| 324 | + self::update_intent_pricing( $form_id, $intents, $form ); | |
| 322 | 325 | |
| 323 | 326 | wp_die(); |
| 324 | 327 | } |
| 325 | 328 | |
| @@ -327,22 +330,22 @@ | ||
| 327 | 330 | * Update pricing on page turn and non-ajax validation. |
| 328 | 331 | * |
| 329 | 332 | * @since 6.5, introduced in v2.0 of the Stripe add on. |
| 330 | 333 | * |
| 331 | - * @param int $form_id | |
| 332 | - * @param array $intents | |
| 334 | + * @param int|string $form_id | |
| 335 | + * @param array $intents | |
| 336 | + * @param array $form_data | |
| 333 | 337 | * |
| 334 | 338 | * @return void |
| 335 | 339 | */ |
| 336 | - private static function update_intent_pricing( $form_id, &$intents ) { | |
| 337 | - // phpcs:ignore WordPress.Security.NonceVerification.Missing | |
| 338 | - if ( ! isset( $_POST['form_id'] ) || absint( $_POST['form_id'] ) != $form_id ) { | |
| 340 | + private static function update_intent_pricing( $form_id, &$intents, $form_data ) { | |
| 341 | + if ( ! isset( $form_data['form_id'] ) || absint( $form_data['form_id'] ) !== (int) $form_id ) { | |
| 339 | 342 | return; |
| 340 | 343 | } |
| 341 | 344 | |
| 342 | 345 | $actions = FrmStrpLiteActionsController::get_actions_before_submit( $form_id ); |
| 343 | 346 | |
| 344 | - if ( empty( $actions ) || empty( $intents ) ) { | |
| 347 | + if ( ! $actions || ! $intents ) { | |
| 345 | 348 | return; |
| 346 | 349 | } |
| 347 | 350 | |
| 348 | 351 | $form = FrmForm::getOne( $form_id ); |
| @@ -357,9 +360,9 @@ | ||
| 357 | 360 | } |
| 358 | 361 | |
| 359 | 362 | foreach ( $intents as $k => $intent ) { |
| 360 | 363 | $intent_id = explode( '_secret_', $intent )[0]; |
| 361 | - $is_setup_intent = 0 === strpos( $intent_id, 'seti_' ); | |
| 364 | + $is_setup_intent = str_starts_with( $intent_id, 'seti_' ); | |
| 362 | 365 | |
| 363 | 366 | if ( $is_setup_intent ) { |
| 364 | 367 | continue; |
| 365 | 368 | } |
| @@ -370,11 +373,13 @@ | ||
| 370 | 373 | continue; |
| 371 | 374 | } |
| 372 | 375 | |
| 373 | 376 | foreach ( $actions as $action ) { |
| 377 | + // phpcs:ignore Universal.Operators.StrictComparisons | |
| 374 | 378 | if ( $saved->metadata->action != $action->ID ) { |
| 375 | 379 | continue; |
| 376 | 380 | } |
| 381 | + | |
| 377 | 382 | $intents[ $k ] = array( |
| 378 | 383 | 'id' => $intent, |
| 379 | 384 | 'action' => $action->ID, |
| 380 | 385 | ); |
| @@ -380,17 +385,18 @@ | ||
| 380 | 385 | ); |
| 381 | 386 | |
| 382 | 387 | $amount = $action->post_content['amount']; |
| 383 | 388 | |
| 384 | - if ( strpos( $amount, '[' ) === false ) { | |
| 389 | + if ( ! str_contains( $amount, '[' ) ) { | |
| 385 | 390 | // The amount is static, so it doesn't need an update. |
| 386 | 391 | continue; |
| 387 | 392 | } |
| 388 | 393 | |
| 389 | 394 | // Update amount based on field shortcodes. |
| 390 | - $entry = self::generate_false_entry(); | |
| 395 | + $entry = self::generate_false_entry( $form_data ); | |
| 391 | 396 | $amount = FrmStrpLiteActionsController::prepare_amount( $amount, compact( 'form', 'entry', 'action' ) ); |
| 392 | 397 | |
| 398 | + // phpcs:ignore Universal.Operators.StrictComparisons | |
| 393 | 399 | if ( $saved->amount == $amount || $amount == '000' ) { |
| 394 | 400 | continue; |
| 395 | 401 | } |
| 396 | 402 | |
| @@ -403,11 +409,13 @@ | ||
| 403 | 409 | * Create an entry object with posted values. |
| 404 | 410 | * |
| 405 | 411 | * @since 6.5, introduced in v2.0 of the Stripe add on. |
| 406 | 412 | * |
| 413 | + * @param array $form_data | |
| 414 | + * | |
| 407 | 415 | * @return stdClass |
| 408 | 416 | */ |
| 409 | - private static function generate_false_entry() { | |
| 417 | + private static function generate_false_entry( $form_data ) { | |
| 410 | 418 | $entry = new stdClass(); |
| 411 | 419 | $entry->post_id = 0; |
| 412 | 420 | $entry->id = 0; |
| 413 | 421 | $entry->item_key = ''; |
| @@ -412,22 +420,22 @@ | ||
| 412 | 420 | $entry->id = 0; |
| 413 | 421 | $entry->item_key = ''; |
| 414 | 422 | $entry->metas = array(); |
| 415 | 423 | |
| 416 | - // phpcs:ignore WordPress.Security.NonceVerification.Missing | |
| 417 | - foreach ( $_POST as $k => $v ) { | |
| 424 | + foreach ( $form_data as $k => $v ) { | |
| 418 | 425 | $k = sanitize_text_field( stripslashes( $k ) ); |
| 419 | 426 | $v = wp_unslash( $v ); |
| 420 | 427 | |
| 421 | - if ( $k === 'item_meta' ) { | |
| 422 | - foreach ( $v as $f => $value ) { | |
| 423 | - FrmAppHelper::sanitize_value( 'wp_kses_post', $value ); | |
| 424 | - $entry->metas[ absint( $f ) ] = $value; | |
| 425 | - } | |
| 426 | - } else { | |
| 428 | + if ( $k !== 'item_meta' ) { | |
| 427 | 429 | FrmAppHelper::sanitize_value( 'wp_kses_post', $v ); |
| 428 | 430 | $entry->{$k} = $v; |
| 431 | + continue; | |
| 429 | 432 | } |
| 433 | + | |
| 434 | + foreach ( $v as $f => $value ) { | |
| 435 | + FrmAppHelper::sanitize_value( 'wp_kses_post', $value ); | |
| 436 | + $entry->metas[ absint( $f ) ] = $value; | |
| 437 | + } | |
| 430 | 438 | } |
| 431 | 439 | |
| 432 | 440 | return $entry; |
| 433 | 441 | } |
| @@ -446,16 +454,17 @@ | ||
| 446 | 454 | |
| 447 | 455 | foreach ( $form as $input ) { |
| 448 | 456 | $key = $input['name']; |
| 449 | 457 | |
| 450 | - if ( isset( $formatted[ $key ] ) ) { | |
| 451 | - if ( is_array( $formatted[ $key ] ) ) { | |
| 452 | - $formatted[ $key ][] = $input['value']; | |
| 453 | - } else { | |
| 454 | - $formatted[ $key ] = array( $formatted[ $key ], $input['value'] ); | |
| 455 | - } | |
| 458 | + if ( ! isset( $formatted[ $key ] ) ) { | |
| 459 | + $formatted[ $key ] = $input['value']; | |
| 460 | + continue; | |
| 461 | + } | |
| 462 | + | |
| 463 | + if ( is_array( $formatted[ $key ] ) ) { | |
| 464 | + $formatted[ $key ][] = $input['value']; | |
| 456 | 465 | } else { |
| 457 | - $formatted[ $key ] = $input['value']; | |
| 466 | + $formatted[ $key ] = array( $formatted[ $key ], $input['value'] ); | |
| 458 | 467 | } |
| 459 | 468 | } |
| 460 | 469 | |
| 461 | 470 | parse_str( http_build_query( $formatted ), $form ); |
| @@ -472,9 +481,8 @@ | ||
| 472 | 481 | * @return array |
| 473 | 482 | */ |
| 474 | 483 | private static function maybe_create_intents( $form_id ) { |
| 475 | 484 | $intents = array(); |
| 476 | - | |
| 477 | 485 | $details = self::check_request_params( $form_id ); |
| 478 | 486 | |
| 479 | 487 | if ( is_array( $details ) ) { |
| 480 | 488 | $payment = $details['payment']; |
| @@ -539,8 +547,9 @@ | ||
| 539 | 547 | private static function create_intent( $action ) { |
| 540 | 548 | $amount = $action->post_content['amount']; |
| 541 | 549 | $currency = $action->post_content['currency']; |
| 542 | 550 | |
| 551 | + // phpcs:ignore Universal.Operators.StrictComparisons | |
| 543 | 552 | if ( $amount == '000' ) { |
| 544 | 553 | // Create the intent when the form loads. |
| 545 | 554 | $amount = in_array( strtolower( $currency ), array( 'aud', 'cad', 'eur', 'gbp', 'usd' ), true ) ? 100 : 1000; |
| 546 | 555 | } |
| @@ -610,13 +619,9 @@ | ||
| 610 | 619 | } |
| 611 | 620 | |
| 612 | 621 | $name = self::strip_special_characters_from_statement_descriptor( $name ); |
| 613 | 622 | |
| 614 | - if ( ! self::statement_descriptor_is_valid( $name ) ) { | |
| 615 | - return false; | |
| 616 | - } | |
| 617 | - | |
| 618 | - return $name; | |
| 623 | + return self::statement_descriptor_is_valid( $name ) ? $name : false; | |
| 619 | 624 | } |
| 620 | 625 | |
| 621 | 626 | /** |
| 622 | 627 | * Remove the special characters that Stripe doesn't allow in statement descriptors, in case any exist. |
| @@ -657,13 +662,9 @@ | ||
| 657 | 662 | if ( strlen( $name ) > 22 ) { |
| 658 | 663 | $name = substr( $name, 0, 22 ); |
| 659 | 664 | } |
| 660 | 665 | |
| 661 | - if ( ! preg_match( '/^[a-zA-Z0-9\s\p{P}]+$/', $name ) ) { | |
| 662 | - return false; | |
| 663 | - } | |
| 664 | - | |
| 665 | - return true; | |
| 666 | + return (bool) preg_match( '/^[a-zA-Z0-9\s\p{P}]+$/', $name ); | |
| 666 | 667 | } |
| 667 | 668 | |
| 668 | 669 | /** |
| 669 | 670 | * Create a customer and an associated setup intent for a recurring Stripe link payment. |
| @@ -697,9 +698,9 @@ | ||
| 697 | 698 | * |
| 698 | 699 | * @return void |
| 699 | 700 | */ |
| 700 | 701 | private static function add_amount_to_actions( $form_id, &$actions ) { |
| 701 | - if ( empty( $actions ) ) { | |
| 702 | + if ( ! $actions ) { | |
| 702 | 703 | return; |
| 703 | 704 | } |
| 704 | 705 | |
| 705 | 706 | $form = FrmForm::getOne( $form_id ); |
| @@ -737,15 +738,9 @@ | ||
| 737 | 738 | 'entry' => $atts['entry'], |
| 738 | 739 | ); |
| 739 | 740 | self::prepare_success_atts( $atts ); |
| 740 | 741 | |
| 741 | - if ( $atts['conf_method'] === 'redirect' ) { | |
| 742 | - $redirect = self::get_redirect_url( $atts ); | |
| 743 | - } else { | |
| 744 | - $redirect = self::get_message_url( $atts ); | |
| 745 | - } | |
| 746 | - | |
| 747 | - return $redirect; | |
| 742 | + return $atts['conf_method'] === 'redirect' ? self::get_redirect_url( $atts ) : self::get_message_url( $atts ); | |
| 748 | 743 | } |
| 749 | 744 | |
| 750 | 745 | /** |
| 751 | 746 | * If the form should redirect, get the url to redirect to. |
| @@ -771,9 +766,9 @@ | ||
| 771 | 766 | if ( empty( $success_url ) ) { |
| 772 | 767 | $success_url = $atts['form']->options['success_url']; |
| 773 | 768 | } |
| 774 | 769 | |
| 775 | - $success_url = trim( $atts['form']->options['success_url'] ); | |
| 770 | + $success_url = trim( $success_url ); | |
| 776 | 771 | $success_url = apply_filters( 'frm_content', $success_url, $atts['form'], $atts['entry'] ); |
| 777 | 772 | $success_url = do_shortcode( $success_url ); |
| 778 | 773 | $atts['id'] = $atts['entry']->id; |
| 779 | 774 | |
| @@ -795,8 +790,9 @@ | ||
| 795 | 790 | |
| 796 | 791 | if ( false === $url ) { |
| 797 | 792 | $url = FrmAppHelper::get_server_value( 'HTTP_REFERER' ); |
| 798 | 793 | } |
| 794 | + | |
| 799 | 795 | return add_query_arg( array( 'frmstrp' => $atts['entry_id'] ), $url ); |
| 800 | 796 | } |
| 801 | 797 | |
| 802 | 798 | /** |
| @@ -828,9 +824,12 @@ | ||
| 828 | 824 | if ( ! is_array( $meta ) || empty( $meta['referer'] ) ) { |
| 829 | 825 | return false; |
| 830 | 826 | } |
| 831 | 827 | |
| 832 | - self::delete_temporary_referer_meta( (int) $row->id ); | |
| 828 | + if ( $delete_meta ) { | |
| 829 | + self::delete_temporary_referer_meta( (int) $row->id ); | |
| 830 | + } | |
| 831 | + | |
| 833 | 832 | return $meta['referer']; |
| 834 | 833 | } |
| 835 | 834 | |
| 836 | 835 | /** |
| @@ -871,13 +870,8 @@ | ||
| 871 | 870 | public static function payment_failed( $payment, $intent ) { |
| 872 | 871 | if ( self::intent_has_failed_status( $intent ) ) { |
| 873 | 872 | return true; |
| 874 | 873 | } |
| 875 | - | |
| 876 | 874 | // The $intent will be "succeeded" with a failed payment when testing with the 4000000000000341 credit card. |
| 877 | - if ( 'payment_failed' === FrmAppHelper::simple_get( 'frm_link_error' ) && 'failed' === $payment->status ) { | |
| 878 | - return true; | |
| 879 | - } | |
| 880 | - | |
| 881 | - return false; | |
| 875 | + return 'payment_failed' === FrmAppHelper::simple_get( 'frm_link_error' ) && 'failed' === $payment->status; | |
| 882 | 876 | } |
| 883 | 877 | } |