PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.2
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.2
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 | classes/controllers/FrmFormsController.php +52 -160 6.5.36.2 View file →
@@ -5,16 +5,15 @@
5 5
6 6 class FrmFormsController {
7 7
8 8 /**
9 - * Track the form that opened the redirect URL in a new tab. This is used to check if we should show the default
10 - * message in the currect tab.
9 + * Track the form and action that ran frm_redirect_url filter. Each item in array is {form_id}_create or {form_id}_update.
11 10 *
12 11 * @since 6.2
13 12 *
14 - * @var array Keys are form IDs and values are 1.
13 + * @var array
15 14 */
16 - private static $redirected_in_new_tab = array();
15 + private static $ran_redirect_url_filter = array();
17 16
18 17 public static function menu() {
19 18 $menu_label = __( 'Forms', 'formidable' );
20 19 if ( ! FrmAppHelper::pro_is_installed() ) {
@@ -397,29 +396,13 @@
397 396 add_filter( 'is_active_sidebar', '__return_false' );
398 397 FrmStylesController::enqueue_css( 'enqueue', true );
399 398
400 399 if ( false === get_template_part( 'page' ) ) {
401 - if ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() ) {
402 - add_filter( 'body_class', 'FrmFormsController::preview_block_theme_body_classnames' );
403 - }
404 400 self::fallback_when_page_template_part_is_not_supported_by_theme();
405 401 }
406 402 }
407 403
408 404 /**
409 - * Add padding to the body for block themes.
410 - *
411 - * @since 6.5.2
412 - *
413 - * @param array $classes The body classes list.
414 - * @return array
415 - */
416 - public static function preview_block_theme_body_classnames( $classes ) {
417 - $classes[] = 'has-global-padding';
418 - return $classes;
419 - }
420 -
421 - /**
422 405 * Not every theme supports get_template_part( 'page' ).
423 406 * When this is not supported, false is returned, and we can handle a fallback.
424 407 */
425 408 private static function fallback_when_page_template_part_is_not_supported_by_theme() {
@@ -905,14 +888,14 @@
905 888 * @return array<string,string>
906 889 */
907 890 public static function get_columns( $columns ) {
908 891 $columns['cb'] = '<input type="checkbox" />';
909 - $columns['name'] = esc_html__( 'Form Title', 'formidable' );
910 - $columns['entries'] = esc_html__( 'Entries', 'formidable' );
892 + $columns['name'] = __( 'Form Title', 'formidable' );
893 + $columns['entries'] = __( 'Entries', 'formidable' );
911 894 $columns['id'] = 'ID';
912 - $columns['form_key'] = esc_html__( 'Key', 'formidable' );
913 - $columns['shortcode'] = esc_html__( 'Actions', 'formidable' );
914 - $columns['created_at'] = esc_html__( 'Date', 'formidable' );
895 + $columns['form_key'] = __( 'Key', 'formidable' );
896 + $columns['shortcode'] = __( 'Actions', 'formidable' );
897 + $columns['created_at'] = __( 'Date', 'formidable' );
915 898
916 899 add_screen_option(
917 900 'per_page',
918 901 array(
@@ -1285,21 +1268,8 @@
1285 1268 'screenshot' => 'chat.png',
1286 1269 )
1287 1270 ),
1288 1271 ),
1289 - 'abandonment' => array(
1290 - 'name' => __( 'Form Abandonment', 'formidable' ),
1291 - 'icon' => 'frm_icon_font frm_abandoned_icon',
1292 - 'html_class' => 'frm_show_upgrade_tab frm_noallow',
1293 - 'data' => FrmAppHelper::get_upgrade_data_params(
1294 - 'abandonment',
1295 - array(
1296 - 'upgrade' => __( 'Form abandonment settings', 'formidable' ),
1297 - 'message' => __( 'Unlock the power of data capture to boost lead generation and master the art of form optimization.', 'formidable' ),
1298 - 'screenshot' => 'abandonment.png',
1299 - )
1300 - ),
1301 - ),
1302 1272 'html' => array(
1303 1273 'name' => __( 'Customize HTML', 'formidable' ),
1304 1274 'class' => __CLASS__,
1305 1275 'function' => 'html_settings',
@@ -1306,9 +1276,9 @@
1306 1276 'icon' => 'frm_icon_font frm_code_icon',
1307 1277 ),
1308 1278 );
1309 1279
1310 - foreach ( array( 'landing', 'chat', 'abandonment' ) as $feature ) {
1280 + foreach ( array( 'landing', 'chat' ) as $feature ) {
1311 1281 if ( ! FrmAppHelper::show_new_feature( $feature ) ) {
1312 1282 unset( $sections[ $feature ] );
1313 1283 }
1314 1284 }
@@ -1644,17 +1614,13 @@
1644 1614 * Replace any [form_name] shortcodes in a string.
1645 1615 *
1646 1616 * @since 5.5
1647 1617 *
1648 - * @param string|array $string
1618 + * @param string $string
1649 1619 * @param stdClass|string|int $form
1650 - * @return string|array
1620 + * @return string
1651 1621 */
1652 1622 public static function replace_form_name_shortcodes( $string, $form ) {
1653 - if ( ! is_string( $string ) ) {
1654 - return $string;
1655 - }
1656 -
1657 1623 if ( false === strpos( $string, '[form_name]' ) ) {
1658 1624 return $string;
1659 1625 }
1660 1626
@@ -2304,13 +2270,8 @@
2304 2270 if ( ! FrmOnSubmitHelper::form_has_migrated( $args['form'] ) ) {
2305 2271 return array();
2306 2272 }
2307 2273
2308 - // If a redirect action has already opened the URL in a new tab, we show the default message in the currect tab.
2309 - if ( ! empty( self::$redirected_in_new_tab[ $args['form']->id ] ) ) {
2310 - return array( FrmOnSubmitHelper::get_fallback_action_after_open_in_new_tab( $event ) );
2311 - }
2312 -
2313 2274 $entry = FrmEntry::getOne( $args['entry_id'], true );
2314 2275 $actions = FrmOnSubmitHelper::get_actions( $args['form']->id );
2315 2276 $met_actions = array();
2316 2277 $has_redirect = false;
@@ -2329,11 +2290,18 @@
2329 2290 if ( 'redirect' === $action_type ) {
2330 2291 if ( $has_redirect ) { // Do not process because we run the first redirect action only.
2331 2292 continue;
2332 2293 }
2294 +
2295 + // Run through frm_redirect_url filter. This is used for the valid action check.
2296 + $action->post_content['success_url'] = self::run_redirect_url_filter(
2297 + $action->post_content['success_url'],
2298 + $args['form'],
2299 + $args + array( 'action' => $event )
2300 + );
2333 2301 }
2334 2302
2335 - if ( ! self::is_valid_on_submit_action( $action, $args, $event ) ) {
2303 + if ( ! self::is_valid_on_submit_action( $action ) ) {
2336 2304 continue;
2337 2305 }
2338 2306
2339 2307 if ( 'redirect' === $action_type ) {
@@ -2363,30 +2331,45 @@
2363 2331 return $met_actions;
2364 2332 }
2365 2333
2366 2334 /**
2335 + * Runs frm_redirect_url filter and prepare the URL.
2336 + * This ensures that filter just fires once per form and action.
2337 + *
2338 + * @since 6.2
2339 + *
2340 + * @param string $url The URL.
2341 + * @param object $form Form object.
2342 + * @param array $args Args from {@see FrmFormsController::run_success_action()}. `$args['action']` is required.
2343 + */
2344 + private static function run_redirect_url_filter( $url, $form, $args ) {
2345 + if ( empty( $args['action'] ) || ! is_string( $args['action'] ) ) {
2346 + return $url;
2347 + }
2348 +
2349 + if ( in_array( $form->id . '_' . $args['action'], self::$ran_redirect_url_filter, true ) ) {
2350 + return $url;
2351 + }
2352 +
2353 + self::$ran_redirect_url_filter[] = $form->id . '_' . $args['action'];
2354 +
2355 + add_filter( 'frm_redirect_url', 'FrmEntriesController::prepare_redirect_url' );
2356 + return apply_filters( 'frm_redirect_url', $url, $form, $args );
2357 + }
2358 +
2359 + /**
2367 2360 * Checks if a Confirmation action has the valid data.
2368 2361 *
2369 2362 * @since 6.1.2
2370 2363 *
2371 2364 * @param object $action Form action object.
2372 - * @param array $args See {@see FrmFormsController::run_success_action()}.
2373 - * @param string $event Form event. Default is `create`.
2374 2365 * @return bool
2375 2366 */
2376 - private static function is_valid_on_submit_action( $action, $args, $event = 'create' ) {
2367 + private static function is_valid_on_submit_action( $action ) {
2377 2368 $action_type = FrmOnSubmitHelper::get_action_type( $action );
2378 2369
2379 - if ( 'redirect' === $action_type ) {
2380 - // Run through frm_redirect_url filter. This is used for the valid action check.
2381 - $action->post_content['success_url'] = apply_filters(
2382 - 'frm_redirect_url',
2383 - $action->post_content['success_url'],
2384 - $args['form'],
2385 - $args + array( 'action' => $event )
2386 - );
2387 -
2388 - return ! empty( $action->post_content['success_url'] );
2370 + if ( 'redirect' === $action_type && empty( $action->post_content['success_url'] ) ) {
2371 + return false;
2389 2372 }
2390 2373
2391 2374 if ( 'page' === $action_type ) {
2392 2375 if ( empty( $action->post_content['success_page_id'] ) ) {
@@ -2550,25 +2533,18 @@
2550 2533
2551 2534 $args['id'] = $args['entry_id'];
2552 2535 FrmEntriesController::delete_entry_before_redirect( $success_url, $args['form'], $args );
2553 2536
2554 - add_filter( 'frm_redirect_url', 'FrmEntriesController::prepare_redirect_url' );
2555 - $success_url = apply_filters( 'frm_redirect_url', $success_url, $args['form'], $args );
2537 + $success_url = self::run_redirect_url_filter( $success_url, $args['form'], $args );
2556 2538
2557 2539 $doing_ajax = FrmAppHelper::doing_ajax();
2558 2540
2559 2541 if ( ! empty( $args['ajax'] ) && $doing_ajax && empty( $args['force_delay_redirect'] ) ) { // Is AJAX submit and there is just one Redirect action runs.
2560 - echo json_encode( self::get_ajax_redirect_response_data( $args + compact( 'success_url' ) ) );
2542 + echo json_encode( array( 'redirect' => $success_url ) );
2561 2543 wp_die();
2562 2544 }
2563 2545
2564 2546 if ( ! headers_sent() && empty( $args['force_delay_redirect'] ) ) { // Not AJAX submit, no headers sent, and there is just one Redirect action runs.
2565 - if ( ! empty( $args['form']->options['open_in_new_tab'] ) ) {
2566 - self::print_open_in_new_tab_js_with_fallback_handler( $success_url, $args );
2567 - self::$redirected_in_new_tab[ $args['form']->id ] = 1;
2568 - return;
2569 - }
2570 -
2571 2547 wp_redirect( esc_url_raw( $success_url ) );
2572 2548 die(); // do not use wp_die or redirect fails
2573 2549 }
2574 2550
@@ -2576,63 +2552,8 @@
2576 2552 self::redirect_after_submit_using_js( $args + compact( 'success_url', 'doing_ajax' ) );
2577 2553 }
2578 2554
2579 2555 /**
2580 - * Prints open in new tab js with fallback handler.
2581 - *
2582 - * @since 6.3.1
2583 - *
2584 - * @param string $success_url Success URL.
2585 - * @param array $args See {@see FrmFormsController::redirect_after_submit()}.
2586 - */
2587 - private static function print_open_in_new_tab_js_with_fallback_handler( $success_url, $args ) {
2588 - echo '<script>var newTab = window.open("' . esc_url_raw( $success_url ) . '", "_blank");';
2589 - echo 'if ( ! newTab ) {';
2590 -
2591 - $data = array(
2592 - 'formId' => intval( $args['form']->id ),
2593 - 'message' => self::get_redirect_fallback_message( $success_url, $args ),
2594 - );
2595 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2596 - echo 'frmShowNewTabFallback = ' . FrmAppHelper::maybe_json_encode( $data ) . ';';
2597 - echo '}</script>';
2598 - }
2599 -
2600 - /**
2601 - * Gets response data for redirect action when AJAX submitting.
2602 - *
2603 - * @since 6.3.1
2604 - *
2605 - * @param array $args See {@see FrmFormsController::run_success_action()}.
2606 - * @return array
2607 - */
2608 - private static function get_ajax_redirect_response_data( $args ) {
2609 - $response_data = array( 'redirect' => $args['success_url'] );
2610 -
2611 - if ( ! empty( $args['form']->options['open_in_new_tab'] ) ) {
2612 - $response_data['openInNewTab'] = 1;
2613 -
2614 - $args['message'] = FrmOnSubmitHelper::get_default_new_tab_msg();
2615 -
2616 - $args['form']->options['success_msg'] = $args['message'];
2617 - $args['form']->options['edit_msg'] = $args['message'];
2618 - if ( ! isset( $args['fields'] ) ) {
2619 - $args['fields'] = FrmField::get_all_for_form( $args['form']->id );
2620 - }
2621 -
2622 - $args['message'] = self::prepare_submit_message( $args['form'], $args['entry_id'], $args );
2623 -
2624 - ob_start();
2625 - self::show_lone_success_messsage( $args );
2626 - $response_data['content'] = ob_get_clean();
2627 -
2628 - $response_data['fallbackMsg'] = self::get_redirect_fallback_message( $args['success_url'], $args );
2629 - }
2630 -
2631 - return $response_data;
2632 - }
2633 -
2634 - /**
2635 2556 * Redirects after submitting using JS. This is used when showing message before redirecting.
2636 2557 *
2637 2558 * @since 6.0
2638 2559 *
@@ -2640,9 +2561,8 @@
2640 2561 */
2641 2562 private static function redirect_after_submit_using_js( $args ) {
2642 2563 $success_msg = FrmOnSubmitHelper::get_default_redirect_msg();
2643 2564 $redirect_msg = self::get_redirect_message( $args['success_url'], $success_msg, $args );
2644 - $success_url = esc_url_raw( $args['success_url'] );
2645 2565
2646 2566 /**
2647 2567 * Filters the delay time before redirecting when On Submit Redirect action is delayed.
2648 2568 *
@@ -2651,14 +2571,8 @@
2651 2571 * @param int $delay_time Delay time in miliseconds.
2652 2572 */
2653 2573 $delay_time = apply_filters( 'frm_redirect_delay_time', 8000 );
2654 2574
2655 - if ( ! empty( $args['form']->options['open_in_new_tab'] ) ) {
2656 - $redirect_js = 'window.open("' . $success_url . '", "_blank")';
2657 - } else {
2658 - $redirect_js = 'window.location="' . $success_url . '";';
2659 - }
2660 -
2661 2575 add_filter( 'frm_use_wpautop', '__return_true' );
2662 2576
2663 2577 echo FrmAppHelper::maybe_kses( $redirect_msg ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2664 2578 echo '<script>';
@@ -2664,9 +2578,9 @@
2664 2578 echo '<script>';
2665 2579 if ( empty( $args['doing_ajax'] ) ) { // Not AJAX submit, delay JS until window.load.
2666 2580 echo 'window.onload=function(){';
2667 2581 }
2668 - echo 'setTimeout(function(){' . $redirect_js . '}, ' . intval( $delay_time ) . ');'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2582 + echo 'setTimeout(function(){window.location="' . esc_url_raw( $args['success_url'] ) . '";}, ' . intval( $delay_time ) . ');';
2669 2583 if ( empty( $args['doing_ajax'] ) ) {
2670 2584 echo '};';
2671 2585 }
2672 2586 echo '</script>';
@@ -2680,9 +2594,10 @@
2680 2594 * @param array $args
2681 2595 */
2682 2596 private static function get_redirect_message( $success_url, $success_msg, $args ) {
2683 2597 $redirect_msg = '<div class="' . esc_attr( FrmFormsHelper::get_form_style_class( $args['form'] ) ) . '"><div class="frm-redirect-msg" role="status">' . $success_msg . '<br/>' .
2684 - self::get_redirect_fallback_message( $success_url, $args ) .
2598 + /* translators: %1$s: Start link HTML, %2$s: End link HTML */
2599 + sprintf( __( '%1$sClick here%2$s if you are not automatically redirected.', 'formidable' ), '<a href="' . esc_url( $success_url ) . '">', '</a>' ) .
2685 2600 '</div></div>';
2686 2601
2687 2602 $redirect_args = array(
2688 2603 'entry_id' => $args['entry_id'],
@@ -2690,31 +2605,8 @@
2690 2605 'form' => $args['form'],
2691 2606 );
2692 2607
2693 2608 return apply_filters( 'frm_redirect_msg', $redirect_msg, $redirect_args );
2694 - }
2695 -
2696 - /**
2697 - * Gets fallback message when redirecting failed.
2698 - *
2699 - * @since 6.3.1
2700 - *
2701 - * @param string $success_url Redirect URL.
2702 - * @param array $args Contains `form` object.
2703 - * @return string
2704 - */
2705 - private static function get_redirect_fallback_message( $success_url, $args ) {
2706 - $target = '';
2707 - if ( ! empty( $args['form']->options['open_in_new_tab'] ) ) {
2708 - $target = ' target="_blank"';
2709 - }
2710 -
2711 - return sprintf(
2712 - /* translators: %1$s: Start link HTML, %2$s: End link HTML */
2713 - __( '%1$sClick here%2$s if you are not automatically redirected.', 'formidable' ),
2714 - '<a href="' . esc_url( $success_url ) . '"' . $target . '>',
2715 - '</a>'
2716 - );
2717 2609 }
2718 2610
2719 2611 /**
2720 2612 * Prepare to show the success message and empty form after submit