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

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