PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 5.0.16
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v5.0.16
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 / classes / controllers / FrmFormsController.php

FrmFormsController.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 5.0.16, at classes/controllers/FrmFormsController.php

2,337 lines 67.8 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 FrmFormsController {
7
8 public static function menu() {
9 $menu_label = __( 'Forms', 'formidable' );
10 if ( ! FrmAppHelper::pro_is_installed() ) {
11 $menu_label .= ' (Lite)';
12 }
13 add_submenu_page( 'formidable', 'Formidable | ' . $menu_label, $menu_label, 'frm_view_forms', 'formidable', 'FrmFormsController::route' );
14
15 self::maybe_load_listing_hooks();
16 }
17
18 public static function maybe_load_listing_hooks() {
19 $action = FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
20 if ( ! empty( $action ) && ! in_array( $action, array( 'list', 'trash', 'untrash', 'destroy' ) ) ) {
21 return;
22 }
23
24 add_filter( 'get_user_option_managetoplevel_page_formidablecolumnshidden', 'FrmFormsController::hidden_columns' );
25
26 add_filter( 'manage_toplevel_page_formidable_columns', 'FrmFormsController::get_columns', 0 );
27 add_filter( 'manage_toplevel_page_formidable_sortable_columns', 'FrmFormsController::get_sortable_columns' );
28 }
29
30 public static function head() {
31 if ( wp_is_mobile() ) {
32 wp_enqueue_script( 'jquery-touch-punch' );
33 }
34 }
35
36 public static function register_widgets() {
37 require_once( FrmAppHelper::plugin_path() . '/classes/widgets/FrmShowForm.php' );
38 register_widget( 'FrmShowForm' );
39 }
40
41 /**
42 * Show a message about conditional logic
43 *
44 * @since 4.06.03
45 */
46 public static function logic_tip() {
47 $images_url = FrmAppHelper::plugin_url() . '/images/';
48 $data_message = __( 'Only show the fields you need and create branching forms. Upgrade to get conditional logic and question branching.', 'formidable' );
49 $data_message .= ' <img src="' . esc_attr( $images_url ) . '/survey-logic.png" srcset="' . esc_attr( $images_url ) . 'survey-logic@2x.png 2x" alt="' . esc_attr__( 'Conditional Logic options', 'formidable' ) . '"/>';
50 echo '<a href="javascript:void(0)" class="frm_noallow frm_show_upgrade frm_add_logic_link" data-upgrade="' . esc_attr__( 'Conditional Logic options', 'formidable' ) . '" data-message="' . esc_attr( $data_message ) . '" data-medium="builder" data-content="logic">';
51 FrmAppHelper::icon_by_class( 'frmfont frm_swap_icon' );
52 esc_html_e( 'Add Conditional Logic', 'formidable' );
53 echo '</a>';
54 }
55
56 /**
57 * By default, Divi processes form shortcodes on the edit post page.
58 * Now that won't do.
59 *
60 * @since 3.01
61 */
62 public static function prevent_divi_conflict( $shortcodes ) {
63 $shortcodes[] = 'formidable';
64
65 return $shortcodes;
66 }
67
68 public static function list_form() {
69 FrmAppHelper::permission_check( 'frm_view_forms' );
70
71 $message = '';
72 $params = FrmForm::list_page_params();
73 $errors = self::process_bulk_form_actions( array() );
74 if ( isset( $errors['message'] ) ) {
75 $message = $errors['message'];
76 unset( $errors['message'] );
77 }
78 $errors = apply_filters( 'frm_admin_list_form_action', $errors );
79
80 return self::display_forms_list( $params, $message, $errors );
81 }
82
83 /**
84 * Load the scripts before a modal can be triggered.
85 *
86 * @since 4.0
87 */
88 private static function init_modal() {
89 wp_enqueue_script( 'jquery-ui-dialog' );
90 wp_enqueue_style( 'jquery-ui-dialog' );
91 }
92
93 /**
94 * Create the default email action
95 *
96 * @since 2.02.11
97 *
98 * @param object|int $form
99 */
100 private static function create_default_email_action( $form ) {
101 FrmForm::maybe_get_form( $form );
102 $create_email = apply_filters( 'frm_create_default_email_action', true, $form );
103
104 if ( $create_email ) {
105 $action_control = FrmFormActionsController::get_form_actions( 'email' );
106 $action_control->create( $form->id );
107 }
108 }
109
110 public static function edit( $values = false ) {
111 FrmAppHelper::permission_check( 'frm_edit_forms' );
112
113 $id = isset( $values['id'] ) ? absint( $values['id'] ) : FrmAppHelper::get_param( 'id', '', 'get', 'absint' );
114
115 return self::get_edit_vars( $id );
116 }
117
118 public static function settings( $id = false, $message = '' ) {
119 FrmAppHelper::permission_check( 'frm_edit_forms' );
120
121 if ( ! $id || ! is_numeric( $id ) ) {
122 $id = FrmAppHelper::get_param( 'id', '', 'get', 'absint' );
123 }
124
125 return self::get_settings_vars( $id, array(), $message );
126 }
127
128 public static function update_settings() {
129 FrmAppHelper::permission_check( 'frm_edit_forms' );
130
131 $id = FrmAppHelper::get_param( 'id', '', 'get', 'absint' );
132
133 $errors = FrmForm::validate( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
134 $warnings = FrmFormsHelper::check_for_warnings( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
135
136 if ( count( $errors ) > 0 ) {
137 return self::get_settings_vars( $id, $errors, compact( 'warnings' ) );
138 }
139
140 do_action( 'frm_before_update_form_settings', $id );
141
142 $antispam_was_on = self::antispam_was_on( $id );
143
144 FrmForm::update( $id, $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
145
146 $antispam_is_on = ! empty( $_POST['options']['antispam'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
147 if ( $antispam_is_on !== $antispam_was_on ) {
148 FrmAntiSpam::clear_caches();
149 }
150
151 $message = __( 'Settings Successfully Updated', 'formidable' );
152
153 return self::get_settings_vars( $id, array(), compact( 'message', 'warnings' ) );
154 }
155
156 /**
157 * @param int $form_id
158 * @return bool
159 */
160 private static function antispam_was_on( $form_id ) {
161 $form = FrmForm::getOne( $form_id );
162 return ! empty( $form->options['antispam'] );
163 }
164
165 public static function update( $values = array() ) {
166 if ( empty( $values ) ) {
167 $values = $_POST; // phpcs:ignore WordPress.Security.NonceVerification.Missing
168 }
169
170 // Set radio button and checkbox meta equal to "other" value.
171 if ( FrmAppHelper::pro_is_installed() ) {
172 $values = FrmProEntry::mod_other_vals( $values, 'back' );
173 }
174
175 $errors = FrmForm::validate( $values );
176 $permission_error = FrmAppHelper::permission_nonce_error( 'frm_edit_forms', 'frm_save_form', 'frm_save_form_nonce' );
177 if ( $permission_error !== false ) {
178 $errors['form'] = $permission_error;
179 }
180
181 $id = isset( $values['id'] ) ? absint( $values['id'] ) : FrmAppHelper::get_param( 'id', '', 'get', 'absint' );
182
183 if ( count( $errors ) > 0 ) {
184 return self::get_edit_vars( $id, $errors );
185 } else {
186 FrmForm::update( $id, $values );
187 $message = __( 'Form was successfully updated.', 'formidable' );
188
189 if ( self::is_too_long( $values ) ) {
190 $message .= '<br/> ' . sprintf(
191 /* translators: %1$s: Start link HTML, %2$s: end link HTML */
192 __( 'However, your form is very long and may be %1$sreaching server limits%2$s.', 'formidable' ),
193 '<a href="https://formidableforms.com/knowledgebase/i-have-a-long-form-why-did-the-options-at-the-end-of-the-form-stop-saving/?utm_source=WordPress&utm_medium=builder&utm_campaign=liteplugin" target="_blank" rel="noopener">',
194 '</a>'
195 );
196 }
197
198 if ( defined( 'DOING_AJAX' ) ) {
199 wp_die( FrmAppHelper::kses( $message, array( 'a' ) ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
200 }
201
202 return self::get_edit_vars( $id, array(), $message );
203 }
204 }
205
206 /**
207 * Check if the value at the end of the form was included.
208 * If it's missing, it means other values at the end of the form
209 * were likely not saved either.
210 *
211 * @since 3.06.01
212 */
213 private static function is_too_long( $values ) {
214 return ( ! isset( $values['frm_end'] ) ) || empty( $values['frm_end'] );
215 }
216
217 /**
218 * Redirect to the url for creating from a template
219 * Also delete the current form
220 *
221 * @since 2.0
222 * @deprecated 3.06
223 */
224 public static function _create_from_template() {
225 _deprecated_function( __FUNCTION__, '3.06' );
226
227 FrmAppHelper::permission_check( 'frm_edit_forms' );
228 check_ajax_referer( 'frm_ajax', 'nonce' );
229
230 $current_form = FrmAppHelper::get_param( 'this_form', '', 'get', 'absint' );
231 $template_id = FrmAppHelper::get_param( 'id', '', 'get', 'absint' );
232
233 if ( $current_form ) {
234 FrmForm::destroy( $current_form );
235 }
236
237 echo esc_url_raw( admin_url( 'admin.php?page=formidable&frm_action=duplicate&id=' . absint( $template_id ) ) );
238 wp_die();
239 }
240
241 public static function duplicate() {
242 FrmAppHelper::permission_check( 'frm_edit_forms' );
243
244 $params = FrmForm::list_page_params();
245 $form = FrmForm::duplicate( $params['id'], $params['template'], true );
246 $message = $params['template'] ? __( 'Form template was Successfully Created', 'formidable' ) : __( 'Form was Successfully Copied', 'formidable' );
247 if ( $form ) {
248 return self::get_edit_vars( $form, array(), $message, true );
249 } else {
250 return self::display_forms_list( $params, __( 'There was a problem creating the new template.', 'formidable' ) );
251 }
252 }
253
254 public static function page_preview() {
255 $params = FrmForm::list_page_params();
256 if ( ! $params['form'] ) {
257 return;
258 }
259
260 $form = FrmForm::getOne( $params['form'] );
261 if ( $form ) {
262 return self::show_form( $form->id, '', true, true );
263 }
264 }
265
266 /**
267 * @since 3.0
268 */
269 public static function show_page_preview() {
270 echo self::page_preview(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
271 }
272
273 public static function preview() {
274 do_action( 'frm_wp' );
275
276 global $frm_vars;
277 $frm_vars['preview'] = true;
278
279 $include_theme = FrmAppHelper::get_param( 'theme', '', 'get', 'absint' );
280 if ( $include_theme ) {
281 self::set_preview_query();
282 self::load_theme_preview();
283 } else {
284 self::load_direct_preview();
285 }
286
287 wp_die();
288 }
289
290 private static function set_preview_query() {
291 $random_page = get_posts(
292 array(
293 'numberposts' => 1,
294 'orderby' => 'date',
295 'order' => 'ASC',
296 'post_type' => 'page',
297 )
298 );
299
300 if ( ! empty( $random_page ) ) {
301 $random_page = reset( $random_page );
302 query_posts(
303 array(
304 'post_type' => 'page',
305 'page_id' => $random_page->ID,
306 )
307 );
308 }
309 }
310
311 /**
312 * @since 3.0
313 */
314 private static function load_theme_preview() {
315 add_filter( 'wp_title', 'FrmFormsController::preview_title', 9999 );
316 add_filter( 'the_title', 'FrmFormsController::preview_page_title', 9999 );
317 add_filter( 'the_content', 'FrmFormsController::preview_content', 9999 );
318 add_action( 'loop_no_results', 'FrmFormsController::show_page_preview' );
319 add_filter( 'is_active_sidebar', '__return_false' );
320 FrmStylesController::enqueue_css( 'enqueue', true );
321
322 if ( false === get_template_part( 'page' ) ) {
323 self::fallback_when_page_template_part_is_not_supported_by_theme();
324 }
325 }
326
327 /**
328 * Not every theme supports get_template_part( 'page' ).
329 * When this is not supported, false is returned, and we can handle a fallback.
330 */
331 private static function fallback_when_page_template_part_is_not_supported_by_theme() {
332 if ( have_posts() ) {
333 the_post();
334 get_header( '' );
335 // add some generic class names to the container to add some natural padding to the content.
336 // .entry-content catches the WordPress TwentyTwenty theme.
337 // .container catches Customizr content.
338 echo '<div class="container entry-content">';
339 the_content();
340 echo '</div>';
341 get_footer();
342 }
343 }
344
345 /**
346 * Set the page title for the theme preview page
347 *
348 * @since 3.0
349 */
350 public static function preview_page_title( $title ) {
351 if ( in_the_loop() ) {
352 $title = self::preview_title( $title );
353 }
354
355 return $title;
356 }
357
358 /**
359 * Set the page title for the theme preview page
360 *
361 * @since 3.0
362 */
363 public static function preview_title( $title ) {
364 return __( 'Form Preview', 'formidable' );
365 }
366
367 /**
368 * Set the page content for the theme preview page
369 *
370 * @since 3.0
371 */
372 public static function preview_content( $content ) {
373 if ( in_the_loop() ) {
374 $content = self::show_page_preview();
375 }
376
377 return $content;
378 }
379
380 /**
381 * @since 3.0
382 */
383 private static function load_direct_preview() {
384 header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
385
386 $key = FrmAppHelper::simple_get( 'form', 'sanitize_title' );
387 if ( $key == '' ) {
388 $key = FrmAppHelper::get_post_param( 'form', '', 'sanitize_title' );
389 }
390
391 $form = FrmForm::getAll( array( 'form_key' => $key ), '', 1 );
392 if ( empty( $form ) ) {
393 $form = FrmForm::getAll( array(), '', 1 );
394 }
395
396 require( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/direct.php' );
397 }
398
399 public static function untrash() {
400 self::change_form_status( 'untrash' );
401 }
402
403 public static function bulk_untrash( $ids ) {
404 FrmAppHelper::permission_check( 'frm_edit_forms' );
405
406 $count = FrmForm::set_status( $ids, 'published' );
407
408 /* translators: %1$s: Number of forms */
409 $message = sprintf( _n( '%1$s form restored from the Trash.', '%1$s forms restored from the Trash.', $count, 'formidable' ), 1 );
410
411 return $message;
412 }
413
414 /**
415 * @since 3.06
416 */
417 public static function ajax_trash() {
418 FrmAppHelper::permission_check( 'frm_delete_forms' );
419 check_ajax_referer( 'frm_ajax', 'nonce' );
420 $form_id = FrmAppHelper::get_param( 'id', '', 'post', 'absint' );
421 FrmForm::set_status( $form_id, 'trash' );
422 wp_die();
423 }
424
425 public static function trash() {
426 self::change_form_status( 'trash' );
427 }
428
429 /**
430 * @param string $status
431 *
432 * @return void
433 */
434 public static function change_form_status( $status ) {
435 $available_status = array(
436 'untrash' => array(
437 'permission' => 'frm_edit_forms',
438 'new_status' => 'published',
439 ),
440 'trash' => array(
441 'permission' => 'frm_delete_forms',
442 'new_status' => 'trash',
443 ),
444 );
445
446 if ( ! isset( $available_status[ $status ] ) ) {
447 return;
448 }
449
450 FrmAppHelper::permission_check( $available_status[ $status ]['permission'] );
451
452 $params = FrmForm::list_page_params();
453
454 //check nonce url
455 check_admin_referer( $status . '_form_' . $params['id'] );
456
457 $count = 0;
458 if ( FrmForm::set_status( $params['id'], $available_status[ $status ]['new_status'] ) ) {
459 $count ++;
460 }
461
462 $form_type = FrmAppHelper::get_simple_request(
463 array(
464 'param' => 'form_type',
465 'type' => 'request',
466 )
467 );
468
469 /* translators: %1$s: Number of forms */
470 $available_status['untrash']['message'] = sprintf( _n( '%1$s form restored from the Trash.', '%1$s forms restored from the Trash.', $count, 'formidable' ), $count );
471
472 /* translators: %1$s: Number of forms, %2$s: Start link HTML, %3$s: End link HTML */
473 $available_status['trash']['message'] = sprintf( _n( '%1$s form moved to the Trash. %2$sUndo%3$s', '%1$s forms moved to the Trash. %2$sUndo%3$s', $count, 'formidable' ), $count, '<a href="' . esc_url( wp_nonce_url( '?page=formidable&frm_action=untrash&form_type=' . $form_type . '&id=' . $params['id'], 'untrash_form_' . $params['id'] ) ) . '">', '</a>' );
474
475 $message = $available_status[ $status ]['message'];
476
477 self::display_forms_list( $params, $message );
478 }
479
480 public static function bulk_trash( $ids ) {
481 FrmAppHelper::permission_check( 'frm_delete_forms' );
482
483 $count = 0;
484 foreach ( $ids as $id ) {
485 if ( FrmForm::trash( $id ) ) {
486 $count ++;
487 }
488 }
489
490 $current_page = FrmAppHelper::get_simple_request(
491 array(
492 'param' => 'form_type',
493 'type' => 'request',
494 )
495 );
496 $message = sprintf(
497 /* translators: %1$s: Number of forms, %2$s: Start link HTML, %3$s: End link HTML */
498 _n( '%1$s form moved to the Trash. %2$sUndo%3$s', '%1$s forms moved to the Trash. %2$sUndo%3$s', $count, 'formidable' ),
499 $count,
500 '<a href="' . esc_url( wp_nonce_url( '?page=formidable&frm_action=list&action=bulk_untrash&form_type=' . $current_page . '&item-action=' . implode( ',', $ids ), 'bulk-toplevel_page_formidable' ) ) . '">',
501 '</a>'
502 );
503
504 return $message;
505 }
506
507 public static function destroy() {
508 FrmAppHelper::permission_check( 'frm_delete_forms' );
509
510 $params = FrmForm::list_page_params();
511
512 // Check nonce url.
513 check_admin_referer( 'destroy_form_' . $params['id'] );
514
515 $count = 0;
516 if ( FrmForm::destroy( $params['id'] ) ) {
517 $count ++;
518 }
519
520 /* translators: %1$s: Number of forms */
521 $message = sprintf( _n( '%1$s Form Permanently Deleted', '%1$s Forms Permanently Deleted', $count, 'formidable' ), $count );
522
523 self::display_forms_list( $params, $message );
524 }
525
526 public static function bulk_destroy( $ids ) {
527 FrmAppHelper::permission_check( 'frm_delete_forms' );
528
529 $count = 0;
530 foreach ( $ids as $id ) {
531 $d = FrmForm::destroy( $id );
532 if ( $d ) {
533 $count ++;
534 }
535 }
536
537 /* translators: %1$s: Number of forms */
538 $message = sprintf( _n( '%1$s form permanently deleted.', '%1$s forms permanently deleted.', $count, 'formidable' ), $count );
539
540 return $message;
541 }
542
543 private static function delete_all() {
544 // Check nonce url.
545 $permission_error = FrmAppHelper::permission_nonce_error( 'frm_delete_forms', '_wpnonce', 'bulk-toplevel_page_formidable' );
546 if ( $permission_error !== false ) {
547 self::display_forms_list( array(), '', array( $permission_error ) );
548
549 return;
550 }
551
552 $count = FrmForm::scheduled_delete( time() );
553
554 /* translators: %1$s: Number of forms */
555 $message = sprintf( _n( '%1$s form permanently deleted.', '%1$s forms permanently deleted.', $count, 'formidable' ), $count );
556
557 self::display_forms_list( array(), $message );
558 }
559
560 /**
561 * Create a new form from the modal.
562 *
563 * @since 4.0
564 */
565 public static function build_new_form() {
566 global $wpdb;
567
568 FrmAppHelper::permission_check( 'frm_edit_forms' );
569 check_ajax_referer( 'frm_ajax', 'nonce' );
570
571 $new_values = self::get_modal_values();
572 $new_values['form_key'] = $new_values['name'];
573 $new_values['options'] = array(
574 'antispam' => 1,
575 );
576
577 $form_id = FrmForm::create( $new_values );
578
579 self::create_default_email_action( $form_id );
580
581 $response = array(
582 'redirect' => FrmForm::get_edit_link( $form_id ),
583 );
584
585 echo wp_json_encode( $response );
586 wp_die();
587 }
588
589 /**
590 * Create a custom template from a form
591 *
592 * @since 3.06
593 */
594 public static function build_template() {
595 global $wpdb;
596
597 FrmAppHelper::permission_check( 'frm_edit_forms' );
598 check_ajax_referer( 'frm_ajax', 'nonce' );
599
600 $form_id = FrmAppHelper::get_param( 'xml', '', 'post', 'absint' );
601 $new_form_id = FrmForm::duplicate( $form_id, 1, true );
602 if ( ! $new_form_id ) {
603 $response = array(
604 'message' => __( 'There was an error creating a template.', 'formidable' ),
605 );
606 } else {
607 $new_values = self::get_modal_values();
608 $query_results = $wpdb->update( $wpdb->prefix . 'frm_forms', $new_values, array( 'id' => $new_form_id ) );
609 if ( $query_results ) {
610 FrmForm::clear_form_cache();
611 }
612
613 $response = array(
614 'redirect' => admin_url( 'admin.php?page=formidable&frm_action=duplicate&id=' . $new_form_id ),
615 );
616 }
617
618 echo wp_json_encode( $response );
619 wp_die();
620 }
621
622 /**
623 * Before creating a new form, get the name and description from the modal.
624 *
625 * @since 4.0
626 */
627 private static function get_modal_values() {
628 $name = FrmAppHelper::get_param( 'name', '', 'post', 'sanitize_text_field' );
629 $desc = FrmAppHelper::get_param( 'desc', '', 'post', 'sanitize_textarea_field' );
630
631 return array(
632 'name' => $name,
633 'description' => $desc,
634 );
635 }
636
637 /**
638 * Inserts Formidable button
639 * Hook exists since 2.5.0
640 *
641 * @since 2.0.15
642 */
643 public static function insert_form_button() {
644 if ( current_user_can( 'frm_view_forms' ) ) {
645 FrmAppHelper::load_admin_wide_js();
646 $menu_name = FrmAppHelper::get_menu_name();
647 $icon = apply_filters( 'frm_media_icon', FrmAppHelper::svg_logo() );
648 echo '<a href="#TB_inline?width=50&height=50&inlineId=frm_insert_form" class="thickbox button add_media frm_insert_form" title="' . esc_attr__( 'Add forms and content', 'formidable' ) . '">' .
649 FrmAppHelper::kses( $icon, 'all' ) . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
650 ' ' . esc_html( $menu_name ) . '</a>';
651 }
652 }
653
654 /**
655 * @return void
656 */
657 public static function insert_form_popup() {
658 if ( ! self::should_insert_form_popup() ) {
659 return;
660 }
661
662 FrmAppHelper::load_admin_wide_js();
663
664 $shortcodes = array(
665 'formidable' => array(
666 'name' => __( 'Form', 'formidable' ),
667 'label' => __( 'Insert a Form', 'formidable' ),
668 ),
669 );
670 $shortcodes = apply_filters( 'frm_popup_shortcodes', $shortcodes );
671
672 include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/insert_form_popup.php';
673
674 if ( FrmAppHelper::is_form_builder_page() && ! class_exists( '_WP_Editors', false ) ) {
675 // initialize a wysiwyg so we have usable settings defined in tinyMCEPreInit.mceInit
676 require ABSPATH . WPINC . '/class-wp-editor.php';
677 ?>
678 <div class="frm_hidden">
679 <?php wp_editor( '', 'frm_description_placeholder', array() ); ?>
680 </div>
681 <?php
682 }
683 }
684
685 /**
686 * Check the page being loaded, determine if this is a page that should include the form popup.
687 *
688 * @since x.x
689 *
690 * @return bool
691 */
692 private static function should_insert_form_popup() {
693 if ( FrmAppHelper::is_form_builder_page() ) {
694 return true;
695 }
696 $page = basename( FrmAppHelper::get_server_value( 'PHP_SELF' ) );
697 return in_array( $page, array( 'post.php', 'page.php', 'page-new.php', 'post-new.php' ), true );
698 }
699
700 public static function get_shortcode_opts() {
701 FrmAppHelper::permission_check( 'frm_view_forms' );
702 check_ajax_referer( 'frm_ajax', 'nonce' );
703
704 $shortcode = FrmAppHelper::get_post_param( 'shortcode', '', 'sanitize_text_field' );
705 if ( empty( $shortcode ) ) {
706 wp_die();
707 }
708
709 echo '<div id="sc-opts-' . esc_attr( $shortcode ) . '" class="frm_shortcode_option">';
710 echo '<input type="radio" name="frmsc" value="' . esc_attr( $shortcode ) . '" id="sc-' . esc_attr( $shortcode ) . '" class="frm_hidden" />';
711
712 $form_id = '';
713 $opts = array();
714 switch ( $shortcode ) {
715 case 'formidable':
716 $opts = array(
717 'form_id' => 'id',
718 'title' => array(
719 'val' => 1,
720 'label' => __( 'Display form title', 'formidable' ),
721 ),
722 'description' => array(
723 'val' => 1,
724 'label' => __( 'Display form description', 'formidable' ),
725 ),
726 'minimize' => array(
727 'val' => 1,
728 'label' => __( 'Minimize form HTML', 'formidable' ),
729 ),
730 );
731 }
732 $opts = apply_filters( 'frm_sc_popup_opts', $opts, $shortcode );
733
734 if ( isset( $opts['form_id'] ) && is_string( $opts['form_id'] ) ) {
735 // allow other shortcodes to use the required form id option
736 $form_id = $opts['form_id'];
737 unset( $opts['form_id'] );
738 }
739
740 include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/shortcode_opts.php' );
741
742 echo '</div>';
743
744 wp_die();
745 }
746
747 public static function display_forms_list( $params = array(), $message = '', $errors = array() ) {
748 FrmAppHelper::permission_check( 'frm_view_forms' );
749
750 global $wpdb, $frm_vars;
751
752 if ( empty( $params ) ) {
753 $params = FrmForm::list_page_params();
754 }
755
756 $wp_list_table = new FrmFormsListHelper( compact( 'params' ) );
757
758 $pagenum = $wp_list_table->get_pagenum();
759
760 $wp_list_table->prepare_items();
761
762 $total_pages = $wp_list_table->get_pagination_arg( 'total_pages' );
763 if ( $pagenum > $total_pages && $total_pages > 0 ) {
764 wp_redirect( esc_url_raw( add_query_arg( 'paged', $total_pages ) ) );
765 die();
766 }
767
768 require( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/list.php' );
769 }
770
771 public static function get_columns( $columns ) {
772 $columns['cb'] = '<input type="checkbox" />';
773 $columns['id'] = 'ID';
774
775 $type = FrmAppHelper::get_simple_request(
776 array(
777 'param' => 'form_type',
778 'type' => 'request',
779 'default' => 'published',
780 )
781 );
782
783 if ( 'template' == $type ) {
784 $columns['name'] = __( 'Template Name', 'formidable' );
785 $columns['type'] = __( 'Type', 'formidable' );
786 $columns['form_key'] = __( 'Key', 'formidable' );
787 } else {
788 $columns['name'] = __( 'Form Title', 'formidable' );
789 $columns['entries'] = __( 'Entries', 'formidable' );
790 $columns['form_key'] = __( 'Key', 'formidable' );
791 $columns['shortcode'] = __( 'Shortcodes', 'formidable' );
792 }
793
794 $columns['created_at'] = __( 'Date', 'formidable' );
795
796 add_screen_option(
797 'per_page',
798 array(
799 'label' => __( 'Forms', 'formidable' ),
800 'default' => 20,
801 'option' => 'formidable_page_formidable_per_page',
802 )
803 );
804
805 return $columns;
806 }
807
808 public static function get_sortable_columns() {
809 return array(
810 'id' => 'id',
811 'name' => 'name',
812 'description' => 'description',
813 'form_key' => 'form_key',
814 'created_at' => 'created_at',
815 );
816 }
817
818 public static function hidden_columns( $hidden_columns ) {
819 $type = FrmAppHelper::get_simple_request(
820 array(
821 'param' => 'form_type',
822 'type' => 'request',
823 )
824 );
825
826 if ( $type === 'template' ) {
827 $hidden_columns[] = 'id';
828 $hidden_columns[] = 'form_key';
829 }
830
831 return $hidden_columns;
832 }
833
834 public static function save_per_page( $save, $option, $value ) {
835 if ( $option == 'formidable_page_formidable_per_page' ) {
836 $save = (int) $value;
837 }
838
839 return $save;
840 }
841
842 /**
843 * @return bool
844 */
845 public static function expired() {
846 global $frm_expired;
847 return $frm_expired;
848 }
849
850 /**
851 * Get data from api before rendering it so that we can flag the modal as expired
852 */
853 public static function before_list_templates() {
854 global $frm_templates;
855 global $frm_expired;
856 global $frm_license_type;
857
858 $api = new FrmFormTemplateApi();
859 $frm_templates = $api->get_api_info();
860 $expired = false;
861 $license_type = '';
862 if ( isset( $frm_templates['error'] ) ) {
863 $error = $frm_templates['error']['message'];
864 $error = str_replace( 'utm_medium=addons', 'utm_medium=form-templates', $error );
865 $expired = 'expired' === $frm_templates['error']['code'];
866 $license_type = isset( $frm_templates['error']['type'] ) ? $frm_templates['error']['type'] : '';
867 unset( $frm_templates['error'] );
868 }
869
870 $frm_expired = $expired;
871 $frm_license_type = $license_type;
872 }
873
874 public static function list_templates() {
875 global $frm_templates;
876 global $frm_license_type;
877
878 $templates = $frm_templates;
879 $custom_templates = array();
880 $templates_by_category = array();
881
882 self::add_user_templates( $custom_templates );
883
884 foreach ( $templates as $template ) {
885 if ( ! isset( $template['categories'] ) ) {
886 continue;
887 }
888
889 foreach ( $template['categories'] as $category ) {
890 if ( ! isset( $templates_by_category[ $category ] ) ) {
891 $templates_by_category[ $category ] = array();
892 }
893
894 $templates_by_category[ $category ][] = $template;
895 }
896 }
897 unset( $template );
898
899 // Subcategories that are included elsewhere.
900 $redundant_cats = array( 'PayPal', 'Stripe', 'Twilio' );
901
902 $categories = array_keys( $templates_by_category );
903 $categories = array_diff( $categories, FrmFormsHelper::ignore_template_categories() );
904 $categories = array_diff( $categories, $redundant_cats );
905 sort( $categories );
906
907 array_walk(
908 $custom_templates,
909 function( &$template ) {
910 $template['custom'] = true;
911 }
912 );
913
914 $my_templates_translation = __( 'My Templates', 'formidable' );
915 $categories = array_merge( array( $my_templates_translation ), $categories );
916 $pricing = FrmAppHelper::admin_upgrade_link( 'form-templates' );
917 $license_type = $frm_license_type;
918 $args = compact( 'pricing', 'license_type' );
919 $where = apply_filters( 'frm_forms_dropdown', array(), '' );
920 $forms = FrmForm::get_published_forms( $where );
921 $view_path = FrmAppHelper::plugin_path() . '/classes/views/frm-forms/';
922
923 $templates_by_category[ $my_templates_translation ] = $custom_templates;
924
925 unset( $pricing, $license_type, $where );
926 wp_enqueue_script( 'accordion' ); // register accordion for template groups
927 require $view_path . 'list-templates.php';
928 }
929
930 /**
931 * @since 4.03.01
932 */
933 private static function get_template_categories( $templates ) {
934 $categories = array();
935 foreach ( $templates as $template ) {
936 if ( isset( $template['categories'] ) ) {
937 $categories = array_merge( $categories, $template['categories'] );
938 }
939 }
940 $exclude_cats = FrmFormsHelper::ignore_template_categories();
941 $categories = array_unique( $categories );
942 $categories = array_diff( $categories, $exclude_cats );
943 sort( $categories );
944 return $categories;
945 }
946
947 private static function add_user_templates( &$templates ) {
948 $user_templates = array(
949 'is_template' => 1,
950 'default_template' => 0,
951 );
952 $user_templates = FrmForm::getAll( $user_templates, 'name' );
953 foreach ( $user_templates as $template ) {
954 $template = array(
955 'id' => $template->id,
956 'name' => $template->name,
957 'key' => $template->form_key,
958 'description' => $template->description,
959 'url' => admin_url( 'admin.php?page=formidable&frm_action=duplicate&id=' . absint( $template->id ) ),
960 'released' => $template->created_at,
961 'installed' => 1,
962 );
963 array_unshift( $templates, $template );
964 unset( $template );
965 }
966 }
967
968 private static function get_edit_vars( $id, $errors = array(), $message = '', $create_link = false ) {
969 global $frm_vars;
970
971 $form = FrmForm::getOne( $id );
972 if ( ! $form ) {
973 wp_die( esc_html__( 'You are trying to edit a form that does not exist.', 'formidable' ) );
974 }
975
976 if ( $form->parent_form_id ) {
977 /* translators: %1$s: Start link HTML, %2$s: End link HTML */
978 wp_die( sprintf( esc_html__( 'You are trying to edit a child form. Please edit from %1$shere%2$s', 'formidable' ), '<a href="' . esc_url( FrmForm::get_edit_link( $form->parent_form_id ) ) . '">', '</a>' ) );
979 }
980
981 $frm_field_selection = FrmField::field_selection();
982
983 $fields = FrmField::get_all_for_form( $form->id );
984
985 // Automatically add end section fields if they don't exist (2.0 migration).
986 $reset_fields = false;
987 FrmFormsHelper::auto_add_end_section_fields( $form, $fields, $reset_fields );
988
989 if ( $reset_fields ) {
990 $fields = FrmField::get_all_for_form( $form->id, '', 'exclude' );
991 }
992
993 unset( $reset_fields );
994
995 $args = array( 'parent_form_id' => $form->id );
996 $values = FrmAppHelper::setup_edit_vars( $form, 'forms', '', true, array(), $args );
997
998 /**
999 * Allows modifying the list of fields in the form builder.
1000 *
1001 * @since 5.0.04
1002 *
1003 * @param object[] $fields Array of fields.
1004 * @param array $args The arguments. Contains `form`.
1005 */
1006 $values['fields'] = apply_filters( 'frm_fields_in_form_builder', $fields, compact( 'form' ) );
1007
1008 $edit_message = __( 'Form was successfully updated.', 'formidable' );
1009 if ( $form->is_template && $message == $edit_message ) {
1010 $message = __( 'Template was successfully updated.', 'formidable' );
1011 }
1012
1013 $all_templates = FrmForm::getAll( array( 'is_template' => 1 ), 'name' );
1014 $has_fields = isset( $values['fields'] ) && ! empty( $values['fields'] );
1015
1016 if ( defined( 'DOING_AJAX' ) ) {
1017 wp_die();
1018 } else {
1019 require( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/edit.php' );
1020 }
1021 }
1022
1023 public static function get_settings_vars( $id, $errors = array(), $args = array() ) {
1024 FrmAppHelper::permission_check( 'frm_edit_forms' );
1025
1026 global $frm_vars;
1027
1028 if ( ! is_array( $args ) ) {
1029 // For reverse compatibility.
1030 $args = array(
1031 'message' => $args,
1032 );
1033 }
1034
1035 $defaults = array(
1036 'message' => '',
1037 'warnings' => array(),
1038 );
1039 $args = array_merge( $defaults, $args );
1040 $message = $args['message'];
1041 $warnings = $args['warnings'];
1042
1043 $form = FrmForm::getOne( $id );
1044 $fields = FrmField::get_all_for_form( $id );
1045 $values = FrmAppHelper::setup_edit_vars( $form, 'forms', $fields, true );
1046
1047 /**
1048 * Allows changing fields in the form settings.
1049 *
1050 * @since 5.0.04
1051 *
1052 * @param array $fields Array of fields.
1053 * @param array $args The arguments. Contains `form`.
1054 */
1055 $values['fields'] = apply_filters( 'frm_fields_in_settings', $values['fields'], compact( 'form' ) );
1056
1057 self::clean_submit_html( $values );
1058
1059 $sections = self::get_settings_tabs( $values );
1060 $current = FrmAppHelper::simple_get( 't', 'sanitize_title', 'advanced_settings' );
1061
1062 require( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/settings.php' );
1063 }
1064
1065 /**
1066 * @since 4.0
1067 */
1068 public static function form_publish_button( $atts ) {
1069 $values = $atts['values'];
1070 include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/_publish_box.php' );
1071 }
1072
1073 /**
1074 * Get a list of all the settings tabs for the form settings page.
1075 *
1076 * @since 4.0
1077 *
1078 * @param array $values
1079 * @return array
1080 */
1081 private static function get_settings_tabs( $values ) {
1082 $sections = array(
1083 'advanced' => array(
1084 'name' => __( 'General', 'formidable' ),
1085 'title' => __( 'General Form Settings', 'formidable' ),
1086 'function' => array( __CLASS__, 'advanced_settings' ),
1087 'icon' => 'frm_icon_font frm_settings_icon',
1088 ),
1089 'email' => array(
1090 'name' => __( 'Actions & Notifications', 'formidable' ),
1091 'function' => array( 'FrmFormActionsController', 'email_settings' ),
1092 'id' => 'frm_notification_settings',
1093 'icon' => 'frm_icon_font frm_mail_bulk_icon',
1094 ),
1095 'permissions' => array(
1096 'name' => __( 'Form Permissions', 'formidable' ),
1097 'icon' => 'frm_icon_font frm_lock_icon',
1098 'html_class' => 'frm_show_upgrade frm_noallow',
1099 'data' => array(
1100 'medium' => 'permissions',
1101 'upgrade' => __( 'Form Permissions', 'formidable' ),
1102 'message' => __( 'Allow editing, protect forms and files, limit entries, and save drafts. Upgrade to get form and entry permissions.', 'formidable' ),
1103 ),
1104 ),
1105 'scheduling' => array(
1106 'name' => __( 'Form Scheduling', 'formidable' ),
1107 'icon' => 'frm_icon_font frm_calendar_icon',
1108 'html_class' => 'frm_show_upgrade frm_noallow',
1109 'data' => array(
1110 'medium' => 'scheduling',
1111 'upgrade' => __( 'Form scheduling settings', 'formidable' ),
1112 ),
1113 ),
1114 'buttons' => array(
1115 'name' => __( 'Styling & Buttons', 'formidable' ),
1116 'class' => __CLASS__,
1117 'function' => 'buttons_settings',
1118 'icon' => 'frm_icon_font frm_pallet_icon',
1119 ),
1120 'landing' => array(
1121 'name' => __( 'Form Landing Page', 'formidable' ),
1122 'icon' => 'frm_icon_font frm_file_text_icon',
1123 'html_class' => 'frm_show_upgrade frm_noallow',
1124 'data' => FrmAppHelper::get_landing_page_upgrade_data_params(),
1125 ),
1126 'html' => array(
1127 'name' => __( 'Customize HTML', 'formidable' ),
1128 'class' => __CLASS__,
1129 'function' => 'html_settings',
1130 'icon' => 'frm_icon_font frm_code_icon',
1131 ),
1132 );
1133
1134 if ( ! FrmAppHelper::show_landing_pages() ) {
1135 unset( $sections['landing'] );
1136 }
1137
1138 $sections = apply_filters( 'frm_add_form_settings_section', $sections, $values );
1139
1140 if ( FrmAppHelper::pro_is_installed() && ! FrmAppHelper::meets_min_pro_version( '4.0' ) ) {
1141 // Prevent settings from showing in 2 spots.
1142 unset( $sections['permissions'], $sections['scheduling'] );
1143 }
1144
1145 foreach ( $sections as $key => $section ) {
1146 $defaults = array(
1147 'html_class' => '',
1148 'name' => ucfirst( $key ),
1149 'icon' => 'frm_icon_font frm_settings_icon',
1150 );
1151
1152 $section = array_merge( $defaults, $section );
1153
1154 if ( ! isset( $section['anchor'] ) ) {
1155 $section['anchor'] = $key;
1156 }
1157 $section['anchor'] .= '_settings';
1158
1159 if ( ! isset( $section['title'] ) ) {
1160 $section['title'] = $section['name'];
1161 }
1162
1163 if ( ! isset( $section['id'] ) ) {
1164 $section['id'] = $section['anchor'];
1165 }
1166
1167 $sections[ $key ] = $section;
1168 }
1169
1170 return $sections;
1171 }
1172
1173 /**
1174 * @since 4.0
1175 *
1176 * @param array $values
1177 */
1178 public static function advanced_settings( $values ) {
1179 $first_h3 = 'frm_first_h3';
1180
1181 include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/settings-advanced.php';
1182 }
1183
1184 /**
1185 * @param array $values
1186 */
1187 private static function render_spam_settings( $values ) {
1188 if ( function_exists( 'akismet_http_post' ) ) {
1189 include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/spam-settings/akismet.php';
1190 }
1191 include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/spam-settings/honeypot.php';
1192 include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/spam-settings/antispam.php';
1193 }
1194
1195 /**
1196 * @since 4.0
1197 *
1198 * @param array $values
1199 */
1200 public static function buttons_settings( $values ) {
1201 $styles = apply_filters( 'frm_get_style_opts', array() );
1202
1203 $frm_settings = FrmAppHelper::get_settings();
1204 $no_global_style = $frm_settings->load_style === 'none';
1205
1206 include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/settings-buttons.php' );
1207 }
1208
1209 /**
1210 * @since 4.0
1211 *
1212 * @param array $values
1213 */
1214 public static function html_settings( $values ) {
1215 include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/settings-html.php' );
1216 }
1217
1218 /**
1219 * Replace old Submit Button href with new href to avoid errors in Chrome
1220 *
1221 * @since 2.03.08
1222 *
1223 * @param array|boolean $values
1224 */
1225 private static function clean_submit_html( &$values ) {
1226 if ( is_array( $values ) && isset( $values['submit_html'] ) ) {
1227 $values['submit_html'] = str_replace( 'javascript:void(0)', '#', $values['submit_html'] );
1228 }
1229 }
1230
1231 public static function mb_tags_box( $form_id, $class = '' ) {
1232 $fields = FrmField::get_all_for_form( $form_id, '', 'include' );
1233
1234 /**
1235 * Allows modifying the list of fields in the tags box.
1236 *
1237 * @since 5.0.04
1238 *
1239 * @param array $fields The list of fields.
1240 * @param array $args The arguments. Contains `form_id`.
1241 */
1242 $fields = apply_filters( 'frm_fields_in_tags_box', $fields, compact( 'form_id' ) );
1243 $linked_forms = array();
1244 $col = 'one';
1245 $settings_tab = FrmAppHelper::is_admin_page( 'formidable' ) ? true : false;
1246
1247 $cond_shortcodes = apply_filters( 'frm_conditional_shortcodes', array() );
1248 $entry_shortcodes = self::get_shortcode_helpers( $settings_tab );
1249
1250 $advanced_helpers = self::advanced_helpers( compact( 'fields', 'form_id' ) );
1251
1252 include( FrmAppHelper::plugin_path() . '/classes/views/shared/mb_adv_info.php' );
1253 }
1254
1255 /**
1256 * @since 3.04.01
1257 */
1258 private static function advanced_helpers( $atts ) {
1259 $advanced_helpers = array(
1260 'default' => array(
1261 'heading' => __( 'Customize field values with the following parameters.', 'formidable' ),
1262 'codes' => self::get_advanced_shortcodes(),
1263 ),
1264 );
1265
1266 $user_fields = self::user_shortcodes();
1267 if ( ! empty( $user_fields ) ) {
1268 $user_helpers = array();
1269 foreach ( $user_fields as $uk => $uf ) {
1270 $user_helpers[ '|user_id| show="' . $uk . '"' ] = $uf;
1271 unset( $uk, $uf );
1272 }
1273
1274 $advanced_helpers['user_id'] = array(
1275 'codes' => $user_helpers,
1276 );
1277 }
1278
1279 /**
1280 * Add extra helper shortcodes on the Advanced tab in form settings and views
1281 *
1282 * @since 3.04.01
1283 *
1284 * @param array $atts - Includes fields and form_id
1285 */
1286 return apply_filters( 'frm_advanced_helpers', $advanced_helpers, $atts );
1287 }
1288
1289 /**
1290 * Get an array of the options to display in the advanced tab
1291 * of the customization panel
1292 *
1293 * @since 2.0.6
1294 */
1295 private static function get_advanced_shortcodes() {
1296 $adv_shortcodes = array(
1297 'x sep=", "' => array(
1298 'label' => __( 'Separator', 'formidable' ),
1299 'title' => __( 'Use a different separator for checkbox fields', 'formidable' ),
1300 ),
1301 'x format="d-m-Y"' => array(
1302 'label' => __( 'Date Format', 'formidable' ),
1303 ),
1304 'x show="field_label"' => array(
1305 'label' => __( 'Field Label', 'formidable' ),
1306 ),
1307 'x wpautop=0' => array(
1308 'label' => __( 'No Auto P', 'formidable' ),
1309 'title' => __( 'Do not automatically add any paragraphs or line breaks', 'formidable' ),
1310 ),
1311 );
1312 $adv_shortcodes = apply_filters( 'frm_advanced_shortcodes', $adv_shortcodes );
1313
1314 // __( 'Leave blank instead of defaulting to User Login', 'formidable' ) : blank=1
1315
1316 return $adv_shortcodes;
1317 }
1318
1319 /**
1320 * @since 3.04.01
1321 */
1322 private static function user_shortcodes() {
1323 $options = array(
1324 'ID' => __( 'User ID', 'formidable' ),
1325 'first_name' => __( 'First Name', 'formidable' ),
1326 'last_name' => __( 'Last Name', 'formidable' ),
1327 'display_name' => __( 'Display Name', 'formidable' ),
1328 'user_login' => __( 'User Login', 'formidable' ),
1329 'user_email' => __( 'Email', 'formidable' ),
1330 'avatar' => __( 'Avatar', 'formidable' ),
1331 'author_link' => __( 'Author Link', 'formidable' ),
1332 );
1333
1334 return apply_filters( 'frm_user_shortcodes', $options );
1335 }
1336
1337 /**
1338 * Get an array of the helper shortcodes to display in the customization panel
1339 *
1340 * @since 2.0.6
1341 */
1342 private static function get_shortcode_helpers( $settings_tab ) {
1343 $entry_shortcodes = array(
1344 'id' => __( 'Entry ID', 'formidable' ),
1345 'key' => __( 'Entry Key', 'formidable' ),
1346 'post_id' => __( 'Post ID', 'formidable' ),
1347 'ip' => __( 'User IP', 'formidable' ),
1348 'created-at' => __( 'Entry created', 'formidable' ),
1349 'updated-at' => __( 'Entry updated', 'formidable' ),
1350 '' => '',
1351 'siteurl' => __( 'Site URL', 'formidable' ),
1352 'sitename' => __( 'Site Name', 'formidable' ),
1353 );
1354
1355 if ( ! FrmAppHelper::pro_is_installed() ) {
1356 unset( $entry_shortcodes['post_id'] );
1357 }
1358
1359 if ( $settings_tab ) {
1360 $entry_shortcodes['default-message'] = __( 'Default Msg', 'formidable' );
1361 $entry_shortcodes['default-html'] = __( 'Default HTML', 'formidable' );
1362 $entry_shortcodes['default-plain'] = __( 'Default Plain', 'formidable' );
1363 }
1364
1365 /**
1366 * Use this hook to add or remove buttons in the helpers section
1367 * in the customization panel
1368 *
1369 * @since 2.0.6
1370 */
1371 $entry_shortcodes = apply_filters( 'frm_helper_shortcodes', $entry_shortcodes, $settings_tab );
1372
1373 return $entry_shortcodes;
1374 }
1375
1376 /**
1377 * Insert the form class setting into the form
1378 */
1379 public static function form_classes( $form ) {
1380 if ( isset( $form->options['form_class'] ) ) {
1381 echo esc_attr( sanitize_text_field( $form->options['form_class'] ) );
1382 }
1383
1384 if ( ! empty( $form->options['js_validate'] ) ) {
1385 echo ' frm_js_validate ';
1386 self::add_js_validate_form_to_global_vars( $form );
1387 }
1388 }
1389
1390 /**
1391 * @since 5.0.03
1392 *
1393 * @param stdClass $form
1394 */
1395 public static function add_js_validate_form_to_global_vars( $form ) {
1396 global $frm_vars;
1397 if ( ! isset( $frm_vars['js_validate_forms'] ) ) {
1398 $frm_vars['js_validate_forms'] = array();
1399 }
1400 $frm_vars['js_validate_forms'][ $form->id ] = $form;
1401 }
1402
1403 public static function get_email_html() {
1404 FrmAppHelper::permission_check( 'frm_view_forms' );
1405 check_ajax_referer( 'frm_ajax', 'nonce' );
1406
1407 echo FrmEntriesController::show_entry_shortcode( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1408 array(
1409 'form_id' => FrmAppHelper::get_post_param( 'form_id', '', 'absint' ),
1410 'default_email' => true,
1411 'plain_text' => FrmAppHelper::get_post_param( 'plain_text', '', 'absint' ),
1412 )
1413 );
1414 wp_die();
1415 }
1416
1417 public static function filter_content( $content, $form, $entry = false ) {
1418 self::get_entry_by_param( $entry );
1419 if ( ! $entry ) {
1420 return $content;
1421 }
1422
1423 if ( is_object( $form ) ) {
1424 $form = $form->id;
1425 }
1426
1427 $shortcodes = FrmFieldsHelper::get_shortcodes( $content, $form );
1428 $content = apply_filters( 'frm_replace_content_shortcodes', $content, $entry, $shortcodes );
1429
1430 return $content;
1431 }
1432
1433 private static function get_entry_by_param( &$entry ) {
1434 if ( ! $entry || ! is_object( $entry ) ) {
1435 if ( ! $entry || ! is_numeric( $entry ) ) {
1436 $entry = FrmAppHelper::get_post_param( 'id', false, 'sanitize_title' );
1437 }
1438
1439 FrmEntry::maybe_get_entry( $entry );
1440 }
1441 }
1442
1443 public static function replace_content_shortcodes( $content, $entry, $shortcodes ) {
1444 return FrmFieldsHelper::replace_content_shortcodes( $content, $entry, $shortcodes );
1445 }
1446
1447 public static function process_bulk_form_actions( $errors ) {
1448 if ( ! $_REQUEST ) {
1449 return $errors;
1450 }
1451
1452 $bulkaction = FrmAppHelper::get_param( 'action', '', 'get', 'sanitize_text_field' );
1453 if ( $bulkaction == - 1 ) {
1454 $bulkaction = FrmAppHelper::get_param( 'action2', '', 'get', 'sanitize_title' );
1455 }
1456
1457 if ( ! empty( $bulkaction ) && strpos( $bulkaction, 'bulk_' ) === 0 ) {
1458 FrmAppHelper::remove_get_action();
1459
1460 $bulkaction = str_replace( 'bulk_', '', $bulkaction );
1461 }
1462
1463 $ids = FrmAppHelper::get_param( 'item-action', '', 'get', 'sanitize_text_field' );
1464 if ( empty( $ids ) ) {
1465 $errors[] = __( 'No forms were specified', 'formidable' );
1466
1467 return $errors;
1468 }
1469
1470 $permission_error = FrmAppHelper::permission_nonce_error( '', '_wpnonce', 'bulk-toplevel_page_formidable' );
1471 if ( $permission_error !== false ) {
1472 $errors[] = $permission_error;
1473
1474 return $errors;
1475 }
1476
1477 if ( ! is_array( $ids ) ) {
1478 $ids = explode( ',', $ids );
1479 }
1480
1481 switch ( $bulkaction ) {
1482 case 'delete':
1483 $message = self::bulk_destroy( $ids );
1484 break;
1485 case 'trash':
1486 $message = self::bulk_trash( $ids );
1487 break;
1488 case 'untrash':
1489 $message = self::bulk_untrash( $ids );
1490 }
1491
1492 if ( isset( $message ) && ! empty( $message ) ) {
1493 $errors['message'] = $message;
1494 }
1495
1496 return $errors;
1497 }
1498
1499 public static function route() {
1500 $action = isset( $_REQUEST['frm_action'] ) ? 'frm_action' : 'action';
1501 $vars = array();
1502 FrmAppHelper::include_svg();
1503
1504 if ( isset( $_POST['frm_compact_fields'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
1505 FrmAppHelper::permission_check( 'frm_edit_forms' );
1506
1507 // Javascript needs to be allowed in some field settings.
1508 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
1509 $json_vars = htmlspecialchars_decode( nl2br( str_replace( '&quot;', '"', wp_unslash( $_POST['frm_compact_fields'] ) ) ) );
1510 $json_vars = json_decode( $json_vars, true );
1511 if ( empty( $json_vars ) ) {
1512 // json decoding failed so we should return an error message.
1513 $action = FrmAppHelper::get_param( $action, '', 'get', 'sanitize_title' );
1514 if ( 'edit' == $action ) {
1515 $action = 'update';
1516 }
1517
1518 add_filter( 'frm_validate_form', 'FrmFormsController::json_error' );
1519 } else {
1520 $vars = FrmAppHelper::json_to_array( $json_vars );
1521 $action = $vars[ $action ];
1522 unset( $_REQUEST['frm_compact_fields'], $_POST['frm_compact_fields'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
1523 $_REQUEST = array_merge( $_REQUEST, $vars ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
1524 $_POST = array_merge( $_POST, $_REQUEST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
1525 }
1526 } else {
1527 $action = FrmAppHelper::get_param( $action, '', 'get', 'sanitize_title' );
1528 if ( isset( $_REQUEST['delete_all'] ) ) {
1529 // Override the action for this page.
1530 $action = 'delete_all';
1531 }
1532 }
1533
1534 add_action( 'frm_load_form_hooks', 'FrmHooksController::trigger_load_form_hooks' );
1535 FrmAppHelper::trigger_hook_load( 'form' );
1536
1537 switch ( $action ) {
1538 case 'new':
1539 return self::new_form( $vars );
1540 case 'create':
1541 case 'edit':
1542 case 'update':
1543 case 'duplicate':
1544 case 'trash':
1545 case 'untrash':
1546 case 'destroy':
1547 case 'delete_all':
1548 case 'settings':
1549 case 'update_settings':
1550 return self::$action( $vars );
1551 case 'lite-reports':
1552 return self::no_reports( $vars );
1553 case 'views':
1554 return self::no_views( $vars );
1555 default:
1556 do_action( 'frm_form_action_' . $action );
1557 if ( apply_filters( 'frm_form_stop_action_' . $action, false ) ) {
1558 return;
1559 }
1560
1561 $action = FrmAppHelper::get_param( 'action', '', 'get', 'sanitize_text_field' );
1562 if ( $action == - 1 ) {
1563 $action = FrmAppHelper::get_param( 'action2', '', 'get', 'sanitize_title' );
1564 }
1565
1566 if ( strpos( $action, 'bulk_' ) === 0 ) {
1567 FrmAppHelper::remove_get_action();
1568
1569 return self::list_form();
1570 }
1571
1572 return self::display_forms_list();
1573 }
1574 }
1575
1576 public static function json_error( $errors ) {
1577 $errors['json'] = __( 'Abnormal HTML characters prevented your form from saving correctly', 'formidable' );
1578
1579 return $errors;
1580 }
1581
1582 /**
1583 * Education for premium features.
1584 *
1585 * @since 4.05
1586 */
1587 public static function add_form_style_tab_options() {
1588 include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/add_form_style_options.php' );
1589 }
1590
1591 /**
1592 * Add education about views.
1593 *
1594 * @since 4.07
1595 */
1596 public static function no_views( $values = array() ) {
1597 FrmAppHelper::include_svg();
1598 $id = FrmAppHelper::get_param( 'form', '', 'get', 'absint' );
1599 $form = $id ? FrmForm::getOne( $id ) : false;
1600
1601 include FrmAppHelper::plugin_path() . '/classes/views/shared/views-info.php';
1602 }
1603
1604 /**
1605 * Add education about reports.
1606 *
1607 * @since 4.07
1608 */
1609 public static function no_reports( $values = array() ) {
1610 $id = FrmAppHelper::get_param( 'form', '', 'get', 'absint' );
1611 $form = $id ? FrmForm::getOne( $id ) : false;
1612
1613 include FrmAppHelper::plugin_path() . '/classes/views/shared/reports-info.php';
1614 }
1615
1616 /* FRONT-END FORMS */
1617 public static function admin_bar_css() {
1618 if ( is_admin() || ! current_user_can( 'frm_edit_forms' ) ) {
1619 return;
1620 }
1621
1622 self::move_menu_to_footer();
1623
1624 add_action( 'wp_before_admin_bar_render', 'FrmFormsController::admin_bar_configure' );
1625 FrmAppHelper::load_font_style();
1626 }
1627
1628 /**
1629 * @since 4.05.02
1630 */
1631 private static function move_menu_to_footer() {
1632 $settings = FrmAppHelper::get_settings();
1633 if ( empty( $settings->admin_bar ) ) {
1634 remove_action( 'wp_body_open', 'wp_admin_bar_render', 0 );
1635 }
1636 }
1637
1638 public static function admin_bar_configure() {
1639 global $frm_vars;
1640 if ( empty( $frm_vars['forms_loaded'] ) ) {
1641 return;
1642 }
1643
1644 $actions = array();
1645 foreach ( $frm_vars['forms_loaded'] as $form ) {
1646 if ( is_object( $form ) ) {
1647 $actions[ $form->id ] = $form->name;
1648 }
1649 unset( $form );
1650 }
1651
1652 if ( empty( $actions ) ) {
1653 return;
1654 }
1655
1656 self::add_menu_to_admin_bar();
1657 self::add_forms_to_admin_bar( $actions );
1658 }
1659
1660 /**
1661 * @since 2.05.07
1662 */
1663 public static function add_menu_to_admin_bar() {
1664 global $wp_admin_bar;
1665
1666 $wp_admin_bar->add_node(
1667 array(
1668 'id' => 'frm-forms',
1669 'title' => '<span class="ab-icon"></span><span class="ab-label">' . FrmAppHelper::get_menu_name() . '</span>',
1670 'href' => admin_url( 'admin.php?page=formidable' ),
1671 'meta' => array(
1672 'title' => FrmAppHelper::get_menu_name(),
1673 ),
1674 )
1675 );
1676 }
1677
1678 /**
1679 * @since 2.05.07
1680 */
1681 private static function add_forms_to_admin_bar( $actions ) {
1682 global $wp_admin_bar;
1683
1684 asort( $actions );
1685
1686 foreach ( $actions as $form_id => $name ) {
1687
1688 $wp_admin_bar->add_node(
1689 array(
1690 'parent' => 'frm-forms',
1691 'id' => 'edit_form_' . $form_id,
1692 'title' => empty( $name ) ? __( '(no title)', 'formidable' ) : $name,
1693 'href' => FrmForm::get_edit_link( $form_id ),
1694 )
1695 );
1696 }
1697 }
1698
1699 /**
1700 * The formidable shortcode
1701 *
1702 * @param array $atts The params from the shortcode.
1703 */
1704 public static function get_form_shortcode( $atts ) {
1705 global $frm_vars;
1706 if ( isset( $frm_vars['skip_shortcode'] ) && $frm_vars['skip_shortcode'] ) {
1707 $sc = '[formidable';
1708 $sc .= FrmAppHelper::array_to_html_params( $atts );
1709 return $sc . ']';
1710 }
1711
1712 $shortcode_atts = shortcode_atts(
1713 array(
1714 'id' => '',
1715 'key' => '',
1716 'title' => false,
1717 'description' => false,
1718 'readonly' => false,
1719 'entry_id' => false,
1720 'fields' => array(),
1721 'exclude_fields' => array(),
1722 'minimize' => false,
1723 ),
1724 $atts
1725 );
1726 do_action( 'formidable_shortcode_atts', $shortcode_atts, $atts );
1727
1728 return self::show_form( $shortcode_atts['id'], $shortcode_atts['key'], $shortcode_atts['title'], $shortcode_atts['description'], $atts );
1729 }
1730
1731 public static function show_form( $id = '', $key = '', $title = false, $description = false, $atts = array() ) {
1732 if ( empty( $id ) ) {
1733 $id = $key;
1734 }
1735
1736 $form = self::maybe_get_form_to_show( $id );
1737 if ( ! $form ) {
1738 return __( 'Please select a valid form', 'formidable' );
1739 }
1740
1741 FrmAppController::maybe_update_styles();
1742
1743 add_action( 'frm_load_form_hooks', 'FrmHooksController::trigger_load_form_hooks' );
1744 FrmAppHelper::trigger_hook_load( 'form', $form );
1745
1746 $form = apply_filters( 'frm_pre_display_form', $form );
1747
1748 $frm_settings = FrmAppHelper::get_settings( array( 'current_form' => $form->id ) );
1749
1750 if ( self::is_viewable_draft_form( $form ) ) {
1751 // don't show a draft form on a page
1752 $form = __( 'Please select a valid form', 'formidable' );
1753 } elseif ( ! FrmForm::is_visible_to_user( $form ) ) {
1754 $form = do_shortcode( $frm_settings->login_msg );
1755 } else {
1756 do_action( 'frm_pre_get_form', $form );
1757 $form = self::get_form( $form, $title, $description, $atts );
1758
1759 /**
1760 * Use this shortcode to check for external shortcodes that may span
1761 * across multiple fields in the customizable HTML
1762 *
1763 * @since 2.0.8
1764 */
1765 $form = apply_filters( 'frm_filter_final_form', $form );
1766 }
1767
1768 return $form;
1769 }
1770
1771 private static function maybe_get_form_to_show( $id ) {
1772 $form = false;
1773
1774 if ( ! empty( $id ) ) { // no form id or key set
1775 $form = FrmForm::getOne( $id );
1776 if ( ! $form || $form->parent_form_id || $form->status == 'trash' ) {
1777 $form = false;
1778 }
1779 }
1780
1781 return $form;
1782 }
1783
1784 private static function is_viewable_draft_form( $form ) {
1785 return $form->status === 'draft' && current_user_can( 'frm_edit_forms' ) && ! FrmAppHelper::is_preview_page();
1786 }
1787
1788 public static function get_form( $form, $title, $description, $atts = array() ) {
1789 ob_start();
1790
1791 do_action( 'frm_before_get_form', $atts );
1792
1793 self::get_form_contents( $form, $title, $description, $atts );
1794 self::enqueue_scripts( FrmForm::get_params( $form ) );
1795
1796 $contents = ob_get_contents();
1797 ob_end_clean();
1798
1799 self::maybe_minimize_form( $atts, $contents );
1800
1801 return $contents;
1802 }
1803
1804 public static function enqueue_scripts( $params ) {
1805 do_action( 'frm_enqueue_form_scripts', $params );
1806 }
1807
1808 public static function get_form_contents( $form, $title, $description, $atts ) {
1809 $params = FrmForm::get_params( $form );
1810 $errors = self::get_saved_errors( $form, $params );
1811 $fields = FrmFieldsHelper::get_form_fields( $form->id, $errors );
1812 $reset = false;
1813 $pass_args = compact( 'form', 'fields', 'errors', 'title', 'description', 'reset' );
1814
1815 $handle_process_here = $params['action'] === 'create' && $params['posted_form_id'] == $form->id && $_POST; // phpcs:ignore WordPress.Security.NonceVerification.Missing
1816
1817 if ( ! $handle_process_here ) {
1818 do_action( 'frm_display_form_action', $params, $fields, $form, $title, $description );
1819 if ( apply_filters( 'frm_continue_to_new', true, $form->id, $params['action'] ) ) {
1820 self::show_form_after_submit( $pass_args );
1821 }
1822 } elseif ( ! empty( $errors ) ) {
1823 self::show_form_after_submit( $pass_args );
1824
1825 } else {
1826
1827 do_action( 'frm_validate_form_creation', $params, $fields, $form, $title, $description );
1828
1829 if ( apply_filters( 'frm_continue_to_create', true, $form->id ) ) {
1830 $entry_id = self::just_created_entry( $form->id );
1831 $pass_args['entry_id'] = $entry_id;
1832 $pass_args['reset'] = true;
1833 $pass_args['conf_method'] = self::get_confirmation_method( compact( 'form', 'entry_id' ) );
1834
1835 self::run_success_action( $pass_args );
1836
1837 do_action(
1838 'frm_after_entry_processed',
1839 array(
1840 'entry_id' => $entry_id,
1841 'form' => $form,
1842 )
1843 );
1844 }
1845 }
1846 }
1847
1848 /**
1849 * If the form was processed earlier (init), get the generated errors
1850 *
1851 * @since 2.05
1852 */
1853 private static function get_saved_errors( $form, $params ) {
1854 global $frm_vars;
1855
1856 if ( $params['posted_form_id'] == $form->id && $_POST && isset( $frm_vars['created_entries'][ $form->id ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
1857 $errors = $frm_vars['created_entries'][ $form->id ]['errors'];
1858 } else {
1859 $errors = array();
1860 }
1861
1862 return $errors;
1863 }
1864
1865 /**
1866 * @since 2.2.7
1867 */
1868 public static function just_created_entry( $form_id ) {
1869 global $frm_vars;
1870
1871 return ( isset( $frm_vars['created_entries'] ) && isset( $frm_vars['created_entries'][ $form_id ] ) && isset( $frm_vars['created_entries'][ $form_id ]['entry_id'] ) ) ? $frm_vars['created_entries'][ $form_id ]['entry_id'] : 0;
1872 }
1873
1874 /**
1875 * @since 3.0
1876 */
1877 private static function get_confirmation_method( $atts ) {
1878 $opt = 'success_action';
1879 $method = ( isset( $atts['form']->options[ $opt ] ) && ! empty( $atts['form']->options[ $opt ] ) ) ? $atts['form']->options[ $opt ] : 'message';
1880 $method = apply_filters( 'frm_success_filter', $method, $atts['form'], 'create' );
1881
1882 if ( $method != 'message' && ( ! $atts['entry_id'] || ! is_numeric( $atts['entry_id'] ) ) ) {
1883 $method = 'message';
1884 }
1885
1886 return $method;
1887 }
1888
1889 public static function maybe_trigger_redirect( $form, $params, $args ) {
1890 if ( ! isset( $params['id'] ) ) {
1891 global $frm_vars;
1892 $params['id'] = $frm_vars['created_entries'][ $form->id ]['entry_id'];
1893 }
1894
1895 $conf_method = self::get_confirmation_method(
1896 array(
1897 'form' => $form,
1898 'entry_id' => $params['id'],
1899 )
1900 );
1901
1902 if ( 'redirect' === $conf_method ) {
1903 self::trigger_redirect( $form, $params, $args );
1904 }
1905 }
1906
1907 public static function trigger_redirect( $form, $params, $args ) {
1908 $success_args = array(
1909 'action' => $params['action'],
1910 'conf_method' => 'redirect',
1911 'form' => $form,
1912 'entry_id' => $params['id'],
1913 );
1914
1915 if ( isset( $args['ajax'] ) ) {
1916 $success_args['ajax'] = $args['ajax'];
1917 }
1918
1919 self::run_success_action( $success_args );
1920 }
1921
1922 /**
1923 * Used when the success action is not 'message'
1924 *
1925 * @since 2.05
1926 */
1927 public static function run_success_action( $args ) {
1928 $extra_args = $args;
1929 unset( $extra_args['form'] );
1930
1931 do_action( 'frm_success_action', $args['conf_method'], $args['form'], $args['form']->options, $args['entry_id'], $extra_args );
1932
1933 $opt = ( ! isset( $args['action'] ) || $args['action'] === 'create' ) ? 'success' : 'edit';
1934
1935 $args['success_opt'] = $opt;
1936 if ( $args['conf_method'] === 'page' && is_numeric( $args['form']->options[ $opt . '_page_id' ] ) ) {
1937 self::load_page_after_submit( $args );
1938 } elseif ( $args['conf_method'] === 'redirect' ) {
1939 self::redirect_after_submit( $args );
1940 } else {
1941 self::show_message_after_save( $args );
1942 }
1943 }
1944
1945 /**
1946 * @since 3.0
1947 */
1948 private static function load_page_after_submit( $args ) {
1949 global $post;
1950 $opt = $args['success_opt'];
1951 if ( ! $post || $args['form']->options[ $opt . '_page_id' ] != $post->ID ) {
1952 $page = get_post( $args['form']->options[ $opt . '_page_id' ] );
1953 $old_post = $post;
1954 $post = $page;
1955 $content = apply_filters( 'frm_content', $page->post_content, $args['form'], $args['entry_id'] );
1956 echo apply_filters( 'the_content', $content ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1957 $post = $old_post;
1958 }
1959 }
1960
1961 /**
1962 * @since 3.0
1963 */
1964 private static function redirect_after_submit( $args ) {
1965 global $frm_vars;
1966
1967 add_filter( 'frm_use_wpautop', '__return_false' );
1968
1969 $opt = $args['success_opt'];
1970 $success_url = trim( $args['form']->options[ $opt . '_url' ] );
1971 $success_url = apply_filters( 'frm_content', $success_url, $args['form'], $args['entry_id'] );
1972 $success_url = do_shortcode( $success_url );
1973
1974 $success_msg = isset( $args['form']->options[ $opt . '_msg' ] ) ? $args['form']->options[ $opt . '_msg' ] : __( 'Please wait while you are redirected.', 'formidable' );
1975
1976 $redirect_msg = self::get_redirect_message( $success_url, $success_msg, $args );
1977
1978 $args['id'] = $args['entry_id'];
1979 FrmEntriesController::delete_entry_before_redirect( $success_url, $args['form'], $args );
1980
1981 add_filter( 'frm_redirect_url', 'FrmEntriesController::prepare_redirect_url' );
1982 $success_url = apply_filters( 'frm_redirect_url', $success_url, $args['form'], $args );
1983
1984 $doing_ajax = FrmAppHelper::doing_ajax();
1985
1986 if ( isset( $args['ajax'] ) && $args['ajax'] && $doing_ajax ) {
1987 echo json_encode( array( 'redirect' => $success_url ) );
1988 wp_die();
1989 } elseif ( ! headers_sent() ) {
1990 wp_redirect( esc_url_raw( $success_url ) );
1991 die(); // do not use wp_die or redirect fails
1992 } else {
1993 add_filter( 'frm_use_wpautop', '__return_true' );
1994 echo FrmAppHelper::maybe_kses( $redirect_msg ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1995 echo "<script type='text/javascript'>window.onload = function(){setTimeout(window.location='" . esc_url_raw( $success_url ) . "', 8000);}</script>";
1996 }
1997 }
1998
1999 /**
2000 * @since 3.0
2001 *
2002 * @param string $success_url
2003 * @param string $success_msg
2004 * @param array $args
2005 */
2006 private static function get_redirect_message( $success_url, $success_msg, $args ) {
2007 $redirect_msg = '<div class="' . esc_attr( FrmFormsHelper::get_form_style_class( $args['form'] ) ) . '"><div class="frm-redirect-msg frm_message" role="status">' . $success_msg . '<br/>' .
2008 /* translators: %1$s: Start link HTML, %2$s: End link HTML */
2009 sprintf( __( '%1$sClick here%2$s if you are not automatically redirected.', 'formidable' ), '<a href="' . esc_url( $success_url ) . '">', '</a>' ) .
2010 '</div></div>';
2011
2012 $redirect_args = array(
2013 'entry_id' => $args['entry_id'],
2014 'form_id' => $args['form']->id,
2015 'form' => $args['form'],
2016 );
2017
2018 return apply_filters( 'frm_redirect_msg', $redirect_msg, $redirect_args );
2019 }
2020
2021 /**
2022 * Prepare to show the success message and empty form after submit
2023 *
2024 * @since 2.05
2025 */
2026 public static function show_message_after_save( $atts ) {
2027 $atts['message'] = self::prepare_submit_message( $atts['form'], $atts['entry_id'] );
2028
2029 if ( ! isset( $atts['form']->options['show_form'] ) || $atts['form']->options['show_form'] ) {
2030 self::show_form_after_submit( $atts );
2031 } else {
2032 self::show_lone_success_messsage( $atts );
2033 }
2034 }
2035
2036 /**
2037 * Show an empty form
2038 *
2039 * @since 2.05
2040 */
2041 private static function show_form_after_submit( $args ) {
2042 self::fill_atts_for_form_display( $args );
2043
2044 $errors = $args['errors'];
2045 $message = $args['message'];
2046 $form = $args['form'];
2047 $title = $args['title'];
2048 $description = $args['description'];
2049
2050 if ( empty( $args['fields'] ) ) {
2051 $values = array(
2052 'custom_style' => FrmAppHelper::custom_style_value( array() ),
2053 );
2054 } else {
2055 $values = FrmEntriesHelper::setup_new_vars( $args['fields'], $form, $args['reset'] );
2056 }
2057 unset( $args );
2058
2059 $include_form_tag = apply_filters( 'frm_include_form_tag', true, $form );
2060
2061 $frm_settings = FrmAppHelper::get_settings();
2062 $submit = isset( $form->options['submit_value'] ) ? $form->options['submit_value'] : $frm_settings->submit_value;
2063
2064 global $frm_vars;
2065 self::maybe_load_css( $form, $values['custom_style'], $frm_vars['load_css'] );
2066
2067 $message_placement = self::message_placement( $form, $message );
2068
2069 include FrmAppHelper::plugin_path() . '/classes/views/frm-entries/new.php';
2070 }
2071
2072 /**
2073 * @return string - 'before', 'after', or 'submit'
2074 *
2075 * @since 4.05.02
2076 */
2077 private static function message_placement( $form, $message ) {
2078 $place = 'before';
2079
2080 if ( $message && isset( $form->options['form_class'] ) ) {
2081 if ( strpos( $form->options['form_class'], 'frm_below_success' ) !== false ) {
2082 $place = 'after';
2083 } elseif ( strpos( $form->options['form_class'], 'frm_inline_success' ) !== false ) {
2084 $place = 'submit';
2085 }
2086 }
2087
2088 /**
2089 * @return string - 'before' or 'after'
2090 *
2091 * @since 4.05.02
2092 */
2093 return apply_filters( 'frm_message_placement', $place, compact( 'form', 'message' ) );
2094 }
2095
2096 /**
2097 * Get all the values needed on the new.php entry page
2098 *
2099 * @since 2.05
2100 */
2101 private static function fill_atts_for_form_display( &$args ) {
2102 $defaults = array(
2103 'errors' => array(),
2104 'message' => '',
2105 'fields' => array(),
2106 'form' => array(),
2107 'title' => true,
2108 'description' => false,
2109 'reset' => false,
2110 );
2111 $args = wp_parse_args( $args, $defaults );
2112 }
2113
2114 /**
2115 * Show the success message without the form
2116 *
2117 * @since 2.05
2118 */
2119 private static function show_lone_success_messsage( $atts ) {
2120 global $frm_vars;
2121 $values = FrmEntriesHelper::setup_new_vars( $atts['fields'], $atts['form'], true );
2122 self::maybe_load_css( $atts['form'], $values['custom_style'], $frm_vars['load_css'] );
2123
2124 $include_extra_container = 'frm_forms' . FrmFormsHelper::get_form_style_class( $values );
2125
2126 $errors = array();
2127 $form = $atts['form'];
2128 $message = $atts['message'];
2129
2130 include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/errors.php' );
2131 }
2132
2133 /**
2134 * Prepare the success message before it's shown
2135 *
2136 * @since 2.05
2137 */
2138 private static function prepare_submit_message( $form, $entry_id ) {
2139 $frm_settings = FrmAppHelper::get_settings( array( 'current_form' => $form->id ) );
2140
2141 if ( $entry_id && is_numeric( $entry_id ) ) {
2142 $message = isset( $form->options['success_msg'] ) ? $form->options['success_msg'] : $frm_settings->success_msg;
2143 $class = 'frm_message';
2144 } else {
2145 $message = $frm_settings->failed_msg;
2146 $class = FrmFormsHelper::form_error_class();
2147 }
2148
2149 $message = FrmFormsHelper::get_success_message( compact( 'message', 'form', 'entry_id', 'class' ) );
2150
2151 return apply_filters( 'frm_main_feedback', $message, $form, $entry_id );
2152 }
2153
2154 public static function front_head() {
2155 $version = FrmAppHelper::plugin_version();
2156 $suffix = FrmAppHelper::js_suffix();
2157
2158 if ( ! empty( $suffix ) && self::has_combo_js_file() ) {
2159 wp_register_script( 'formidable', FrmAppHelper::plugin_url() . '/js/frm.min.js', array( 'jquery' ), $version, true );
2160 } else {
2161 wp_register_script( 'formidable', FrmAppHelper::plugin_url() . "/js/formidable{$suffix}.js", array( 'jquery' ), $version, true );
2162 }
2163
2164 add_filter( 'script_loader_tag', 'FrmFormsController::defer_script_loading', 10, 2 );
2165
2166 if ( FrmAppHelper::is_admin() ) {
2167 // don't load this in back-end
2168 return;
2169 }
2170
2171 FrmAppHelper::localize_script( 'front' );
2172 FrmStylesController::enqueue_css( 'register' );
2173 }
2174
2175 /**
2176 * @since 3.0
2177 */
2178 public static function has_combo_js_file() {
2179 return is_readable( FrmAppHelper::plugin_path() . '/js/frm.min.js' );
2180 }
2181
2182 public static function maybe_load_css( $form, $this_load, $global_load ) {
2183 $load_css = FrmForm::is_form_loaded( $form, $this_load, $global_load );
2184
2185 if ( ! $load_css ) {
2186 return;
2187 }
2188
2189 global $frm_vars;
2190 self::footer_js( 'header' );
2191 $frm_vars['css_loaded'] = true;
2192
2193 self::load_late_css();
2194 }
2195
2196 /**
2197 * If css is loaded only on applicable pages, include it before the form loads
2198 * to prevent a flash of unstyled form.
2199 *
2200 * @since 4.01
2201 */
2202 private static function load_late_css() {
2203 $frm_settings = FrmAppHelper::get_settings();
2204 $late_css = $frm_settings->load_style === 'dynamic';
2205 if ( ! $late_css ) {
2206 return;
2207 }
2208
2209 global $wp_styles;
2210 if ( is_array( $wp_styles->queue ) && in_array( 'formidable', $wp_styles->queue ) ) {
2211 wp_print_styles( 'formidable' );
2212 }
2213 }
2214
2215 public static function defer_script_loading( $tag, $handle ) {
2216 if ( 'recaptcha-api' == $handle && ! strpos( $tag, 'defer' ) ) {
2217 $tag = str_replace( ' src', ' defer="defer" async="async" src', $tag );
2218 }
2219
2220 return $tag;
2221 }
2222
2223 public static function footer_js( $location = 'footer' ) {
2224 global $frm_vars;
2225
2226 FrmStylesController::enqueue_css();
2227
2228 if ( ! FrmAppHelper::is_admin() && $location != 'header' && ! empty( $frm_vars['forms_loaded'] ) ) {
2229 // load formidable js
2230 wp_enqueue_script( 'formidable' );
2231 }
2232 }
2233
2234 /**
2235 * @since 2.0.8
2236 */
2237 private static function maybe_minimize_form( $atts, &$content ) {
2238 // check if minimizing is turned on
2239 if ( self::is_minification_on( $atts ) ) {
2240 $content = str_replace( array( "\r\n", "\r", "\n", "\t", ' ' ), '', $content );
2241 }
2242 }
2243
2244 /**
2245 * @since 2.0.8
2246 * @return boolean
2247 */
2248 private static function is_minification_on( $atts ) {
2249 return isset( $atts['minimize'] ) && ! empty( $atts['minimize'] );
2250 }
2251
2252 /**
2253 * @since 5.0.16
2254 *
2255 * @return void
2256 */
2257 public static function landing_page_preview_option() {
2258 $dir = apply_filters( 'frm_landing_page_preview_option', false );
2259 if ( false === $dir || ! file_exists( $dir . 'landing-page-preview-option.php' ) ) {
2260 $dir = self::get_form_views_path();
2261 }
2262 include $dir . 'landing-page-preview-option.php';
2263 }
2264
2265 /**
2266 * @since 5.0.16
2267 *
2268 * @return string
2269 */
2270 private static function get_form_views_path() {
2271 return FrmAppHelper::plugin_path() . '/classes/views/frm-forms/';
2272 }
2273
2274 /**
2275 * @deprecated 4.0
2276 */
2277 public static function new_form( $values = array() ) {
2278 FrmDeprecated::new_form( $values );
2279 }
2280
2281 /**
2282 * @deprecated 4.0
2283 */
2284 public static function create( $values = array() ) {
2285 _deprecated_function( __METHOD__, '4.0', 'FrmFormsController::update' );
2286 self::update( $values );
2287 }
2288
2289 /**
2290 * @deprecated 1.07.05
2291 * @codeCoverageIgnore
2292 */
2293 public static function add_default_templates( $path, $default = true, $template = true ) {
2294 FrmDeprecated::add_default_templates( $path, $default, $template );
2295 }
2296
2297 /**
2298 * @deprecated 3.0
2299 * @codeCoverageIgnore
2300 */
2301 public static function bulk_create_template( $ids ) {
2302 return FrmDeprecated::bulk_create_template( $ids );
2303 }
2304
2305 /**
2306 * @deprecated 2.03
2307 * @codeCoverageIgnore
2308 */
2309 public static function register_pro_scripts() {
2310 FrmDeprecated::register_pro_scripts();
2311 }
2312
2313 /**
2314 * @deprecated 3.0
2315 * @codeCoverageIgnore
2316 */
2317 public static function edit_key() {
2318 FrmDeprecated::edit_key();
2319 }
2320
2321 /**
2322 * @deprecated 3.0
2323 * @codeCoverageIgnore
2324 */
2325 public static function edit_description() {
2326 FrmDeprecated::edit_description();
2327 }
2328
2329 /**
2330 * @deprecated 4.08
2331 * @since 3.06
2332 */
2333 public static function add_new() {
2334 _deprecated_function( __FUNCTION__, '4.08' );
2335 }
2336 }
2337