| @@ -4,8 +4,17 @@ | ||
| 4 | 4 | } |
| 5 | 5 | |
| 6 | 6 | class FrmFormsController { |
| 7 | 7 | |
| 8 | + /** | |
| 9 | + * Track the form and action that ran frm_redirect_url filter. Each item in array is {form_id}_create or {form_id}_update. | |
| 10 | + * | |
| 11 | + * @since 6.2 | |
| 12 | + * | |
| 13 | + * @var array | |
| 14 | + */ | |
| 15 | + private static $ran_redirect_url_filter = array(); | |
| 16 | + | |
| 8 | 17 | public static function menu() { |
| 9 | 18 | $menu_label = __( 'Forms', 'formidable' ); |
| 10 | 19 | if ( ! FrmAppHelper::pro_is_installed() ) { |
| 11 | 20 | $menu_label .= ' (Lite)'; |
| @@ -2281,11 +2290,18 @@ | ||
| 2281 | 2290 | if ( 'redirect' === $action_type ) { |
| 2282 | 2291 | if ( $has_redirect ) { // Do not process because we run the first redirect action only. |
| 2283 | 2292 | continue; |
| 2284 | 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 | + ); | |
| 2285 | 2301 | } |
| 2286 | 2302 | |
| 2287 | - if ( ! self::is_valid_on_submit_action( $action, $args, $event ) ) { | |
| 2303 | + if ( ! self::is_valid_on_submit_action( $action ) ) { | |
| 2288 | 2304 | continue; |
| 2289 | 2305 | } |
| 2290 | 2306 | |
| 2291 | 2307 | if ( 'redirect' === $action_type ) { |
| @@ -2315,30 +2331,45 @@ | ||
| 2315 | 2331 | return $met_actions; |
| 2316 | 2332 | } |
| 2317 | 2333 | |
| 2318 | 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 | + /** | |
| 2319 | 2360 | * Checks if a Confirmation action has the valid data. |
| 2320 | 2361 | * |
| 2321 | 2362 | * @since 6.1.2 |
| 2322 | 2363 | * |
| 2323 | 2364 | * @param object $action Form action object. |
| 2324 | - * @param array $args See {@see FrmFormsController::run_success_action()}. | |
| 2325 | - * @param string $event Form event. Default is `create`. | |
| 2326 | 2365 | * @return bool |
| 2327 | 2366 | */ |
| 2328 | - private static function is_valid_on_submit_action( $action, $args, $event = 'create' ) { | |
| 2367 | + private static function is_valid_on_submit_action( $action ) { | |
| 2329 | 2368 | $action_type = FrmOnSubmitHelper::get_action_type( $action ); |
| 2330 | 2369 | |
| 2331 | - if ( 'redirect' === $action_type ) { | |
| 2332 | - // Run through frm_redirect_url filter. This is used for the valid action check. | |
| 2333 | - $action->post_content['success_url'] = apply_filters( | |
| 2334 | - 'frm_redirect_url', | |
| 2335 | - $action->post_content['success_url'], | |
| 2336 | - $args['form'], | |
| 2337 | - $args + array( 'action' => $event ) | |
| 2338 | - ); | |
| 2339 | - | |
| 2340 | - return ! empty( $action->post_content['success_url'] ); | |
| 2370 | + if ( 'redirect' === $action_type && empty( $action->post_content['success_url'] ) ) { | |
| 2371 | + return false; | |
| 2341 | 2372 | } |
| 2342 | 2373 | |
| 2343 | 2374 | if ( 'page' === $action_type ) { |
| 2344 | 2375 | if ( empty( $action->post_content['success_page_id'] ) ) { |
| @@ -2502,10 +2533,9 @@ | ||
| 2502 | 2533 | |
| 2503 | 2534 | $args['id'] = $args['entry_id']; |
| 2504 | 2535 | FrmEntriesController::delete_entry_before_redirect( $success_url, $args['form'], $args ); |
| 2505 | 2536 | |
| 2506 | - add_filter( 'frm_redirect_url', 'FrmEntriesController::prepare_redirect_url' ); | |
| 2507 | - $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 ); | |
| 2508 | 2538 | |
| 2509 | 2539 | $doing_ajax = FrmAppHelper::doing_ajax(); |
| 2510 | 2540 | |
| 2511 | 2541 | if ( ! empty( $args['ajax'] ) && $doing_ajax && empty( $args['force_delay_redirect'] ) ) { // Is AJAX submit and there is just one Redirect action runs. |