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

2,277 lines 65.2 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 $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 );
134 $warnings = FrmFormsHelper::check_for_warnings( $_POST );
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 );
145
146 $antispam_is_on = ! empty( $_POST['options']['antispam'] );
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;
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' ) ) ); // WPCS: XSS ok.
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(); // WPCS: XSS ok.
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 int The number of forms changed
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
574 $form_id = FrmForm::create( $new_values );
575
576 self::create_default_email_action( $form_id );
577
578 $response = array(
579 'redirect' => FrmForm::get_edit_link( $form_id ),
580 );
581
582 echo wp_json_encode( $response );
583 wp_die();
584 }
585
586 /**
587 * Create a custom template from a form
588 *
589 * @since 3.06
590 */
591 public static function build_template() {
592 global $wpdb;
593
594 FrmAppHelper::permission_check( 'frm_edit_forms' );
595 check_ajax_referer( 'frm_ajax', 'nonce' );
596
597 $form_id = FrmAppHelper::get_param( 'xml', '', 'post', 'absint' );
598 $new_form_id = FrmForm::duplicate( $form_id, 1, true );
599 if ( ! $new_form_id ) {
600 $response = array(
601 'message' => __( 'There was an error creating a template.', 'formidable' ),
602 );
603 } else {
604 $new_values = self::get_modal_values();
605 $query_results = $wpdb->update( $wpdb->prefix . 'frm_forms', $new_values, array( 'id' => $new_form_id ) );
606 if ( $query_results ) {
607 FrmForm::clear_form_cache();
608 }
609
610 $response = array(
611 'redirect' => admin_url( 'admin.php?page=formidable&frm_action=duplicate&id=' . $new_form_id ),
612 );
613 }
614
615 echo wp_json_encode( $response );
616 wp_die();
617 }
618
619 /**
620 * Before creating a new form, get the name and description from the modal.
621 *
622 * @since 4.0
623 */
624 private static function get_modal_values() {
625 $name = FrmAppHelper::get_param( 'name', '', 'post', 'sanitize_text_field' );
626 $desc = FrmAppHelper::get_param( 'desc', '', 'post', 'sanitize_textarea_field' );
627
628 return array(
629 'name' => $name,
630 'description' => $desc,
631 );
632 }
633
634 /**
635 * Inserts Formidable button
636 * Hook exists since 2.5.0
637 *
638 * @since 2.0.15
639 */
640 public static function insert_form_button() {
641 if ( current_user_can( 'frm_view_forms' ) ) {
642 FrmAppHelper::load_admin_wide_js();
643 $menu_name = FrmAppHelper::get_menu_name();
644 $icon = apply_filters( 'frm_media_icon', FrmAppHelper::svg_logo() );
645 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' ) . '">' .
646 FrmAppHelper::kses( $icon, 'all' ) .
647 ' ' . esc_html( $menu_name ) . '</a>'; // WPCS: XSS ok.
648 }
649 }
650
651 public static function insert_form_popup() {
652 $page = basename( FrmAppHelper::get_server_value( 'PHP_SELF' ) );
653 if ( ! in_array( $page, array( 'post.php', 'page.php', 'page-new.php', 'post-new.php' ) ) ) {
654 return;
655 }
656
657 FrmAppHelper::load_admin_wide_js();
658
659 $shortcodes = array(
660 'formidable' => array(
661 'name' => __( 'Form', 'formidable' ),
662 'label' => __( 'Insert a Form', 'formidable' ),
663 ),
664 );
665
666 $shortcodes = apply_filters( 'frm_popup_shortcodes', $shortcodes );
667
668 include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/insert_form_popup.php' );
669 }
670
671 public static function get_shortcode_opts() {
672 FrmAppHelper::permission_check( 'frm_view_forms' );
673 check_ajax_referer( 'frm_ajax', 'nonce' );
674
675 $shortcode = FrmAppHelper::get_post_param( 'shortcode', '', 'sanitize_text_field' );
676 if ( empty( $shortcode ) ) {
677 wp_die();
678 }
679
680 echo '<div id="sc-opts-' . esc_attr( $shortcode ) . '" class="frm_shortcode_option">';
681 echo '<input type="radio" name="frmsc" value="' . esc_attr( $shortcode ) . '" id="sc-' . esc_attr( $shortcode ) . '" class="frm_hidden" />';
682
683 $form_id = '';
684 $opts = array();
685 switch ( $shortcode ) {
686 case 'formidable':
687 $opts = array(
688 'form_id' => 'id',
689 'title' => array(
690 'val' => 1,
691 'label' => __( 'Display form title', 'formidable' ),
692 ),
693 'description' => array(
694 'val' => 1,
695 'label' => __( 'Display form description', 'formidable' ),
696 ),
697 'minimize' => array(
698 'val' => 1,
699 'label' => __( 'Minimize form HTML', 'formidable' ),
700 ),
701 );
702 }
703 $opts = apply_filters( 'frm_sc_popup_opts', $opts, $shortcode );
704
705 if ( isset( $opts['form_id'] ) && is_string( $opts['form_id'] ) ) {
706 // allow other shortcodes to use the required form id option
707 $form_id = $opts['form_id'];
708 unset( $opts['form_id'] );
709 }
710
711 include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/shortcode_opts.php' );
712
713 echo '</div>';
714
715 wp_die();
716 }
717
718 public static function display_forms_list( $params = array(), $message = '', $errors = array() ) {
719 FrmAppHelper::permission_check( 'frm_view_forms' );
720
721 global $wpdb, $frm_vars;
722
723 if ( empty( $params ) ) {
724 $params = FrmForm::list_page_params();
725 }
726
727 $wp_list_table = new FrmFormsListHelper( compact( 'params' ) );
728
729 $pagenum = $wp_list_table->get_pagenum();
730
731 $wp_list_table->prepare_items();
732
733 $total_pages = $wp_list_table->get_pagination_arg( 'total_pages' );
734 if ( $pagenum > $total_pages && $total_pages > 0 ) {
735 wp_redirect( esc_url_raw( add_query_arg( 'paged', $total_pages ) ) );
736 die();
737 }
738
739 require( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/list.php' );
740 }
741
742 public static function get_columns( $columns ) {
743 $columns['cb'] = '<input type="checkbox" />';
744 $columns['id'] = 'ID';
745
746 $type = FrmAppHelper::get_simple_request(
747 array(
748 'param' => 'form_type',
749 'type' => 'request',
750 'default' => 'published',
751 )
752 );
753
754 if ( 'template' == $type ) {
755 $columns['name'] = __( 'Template Name', 'formidable' );
756 $columns['type'] = __( 'Type', 'formidable' );
757 $columns['form_key'] = __( 'Key', 'formidable' );
758 } else {
759 $columns['name'] = __( 'Form Title', 'formidable' );
760 $columns['entries'] = __( 'Entries', 'formidable' );
761 $columns['form_key'] = __( 'Key', 'formidable' );
762 $columns['shortcode'] = __( 'Shortcodes', 'formidable' );
763 }
764
765 $columns['created_at'] = __( 'Date', 'formidable' );
766
767 add_screen_option(
768 'per_page',
769 array(
770 'label' => __( 'Forms', 'formidable' ),
771 'default' => 20,
772 'option' => 'formidable_page_formidable_per_page',
773 )
774 );
775
776 return $columns;
777 }
778
779 public static function get_sortable_columns() {
780 return array(
781 'id' => 'id',
782 'name' => 'name',
783 'description' => 'description',
784 'form_key' => 'form_key',
785 'created_at' => 'created_at',
786 );
787 }
788
789 public static function hidden_columns( $hidden_columns ) {
790 $type = FrmAppHelper::get_simple_request(
791 array(
792 'param' => 'form_type',
793 'type' => 'request',
794 )
795 );
796
797 if ( $type === 'template' ) {
798 $hidden_columns[] = 'id';
799 $hidden_columns[] = 'form_key';
800 }
801
802 return $hidden_columns;
803 }
804
805 public static function save_per_page( $save, $option, $value ) {
806 if ( $option == 'formidable_page_formidable_per_page' ) {
807 $save = (int) $value;
808 }
809
810 return $save;
811 }
812
813 /**
814 * @return bool
815 */
816 public static function expired() {
817 global $frm_expired;
818 return $frm_expired;
819 }
820
821 /**
822 * Get data from api before rendering it so that we can flag the modal as expired
823 */
824 public static function before_list_templates() {
825 global $frm_templates;
826 global $frm_expired;
827 global $frm_license_type;
828
829 $api = new FrmFormTemplateApi();
830 $frm_templates = $api->get_api_info();
831 $expired = false;
832 $license_type = '';
833 if ( isset( $frm_templates['error'] ) ) {
834 $error = $frm_templates['error']['message'];
835 $error = str_replace( 'utm_medium=addons', 'utm_medium=form-templates', $error );
836 $expired = 'expired' === $frm_templates['error']['code'];
837 $license_type = isset( $frm_templates['error']['type'] ) ? $frm_templates['error']['type'] : '';
838 unset( $frm_templates['error'] );
839 }
840
841 $frm_expired = $expired;
842 $frm_license_type = $license_type;
843 }
844
845 public static function list_templates() {
846 global $frm_templates;
847 global $frm_license_type;
848
849 $templates = $frm_templates;
850 $custom_templates = array();
851 $templates_by_category = array();
852
853 self::add_user_templates( $custom_templates );
854
855 foreach ( $templates as $template ) {
856 if ( ! isset( $template['categories'] ) ) {
857 continue;
858 }
859
860 foreach ( $template['categories'] as $category ) {
861 if ( ! isset( $templates_by_category[ $category ] ) ) {
862 $templates_by_category[ $category ] = array();
863 }
864
865 $templates_by_category[ $category ][] = $template;
866 }
867 }
868 unset( $template );
869
870 // Subcategories that are included elsewhere.
871 $redundant_cats = array( 'PayPal', 'Stripe', 'Twilio' );
872
873 $categories = array_keys( $templates_by_category );
874 $categories = array_diff( $categories, FrmFormsHelper::ignore_template_categories() );
875 $categories = array_diff( $categories, $redundant_cats );
876 sort( $categories );
877
878 array_walk(
879 $custom_templates,
880 function( &$template ) {
881 $template['custom'] = true;
882 }
883 );
884
885 $my_templates_translation = __( 'My Templates', 'formidable' );
886 $categories = array_merge( array( $my_templates_translation ), $categories );
887 $pricing = FrmAppHelper::admin_upgrade_link( 'form-templates' );
888 $license_type = $frm_license_type;
889 $args = compact( 'pricing', 'license_type' );
890 $where = apply_filters( 'frm_forms_dropdown', array(), '' );
891 $forms = FrmForm::get_published_forms( $where );
892 $view_path = FrmAppHelper::plugin_path() . '/classes/views/frm-forms/';
893
894 $templates_by_category[ $my_templates_translation ] = $custom_templates;
895
896 unset( $pricing, $license_type, $where );
897 wp_enqueue_script( 'accordion' ); // register accordion for template groups
898 require $view_path . 'list-templates.php';
899 }
900
901 /**
902 * @since 4.03.01
903 */
904 private static function get_template_categories( $templates ) {
905 $categories = array();
906 foreach ( $templates as $template ) {
907 if ( isset( $template['categories'] ) ) {
908 $categories = array_merge( $categories, $template['categories'] );
909 }
910 }
911 $exclude_cats = FrmFormsHelper::ignore_template_categories();
912 $categories = array_unique( $categories );
913 $categories = array_diff( $categories, $exclude_cats );
914 sort( $categories );
915 return $categories;
916 }
917
918 private static function add_user_templates( &$templates ) {
919 $user_templates = array(
920 'is_template' => 1,
921 'default_template' => 0,
922 );
923 $user_templates = FrmForm::getAll( $user_templates, 'name' );
924 foreach ( $user_templates as $template ) {
925 $template = array(
926 'id' => $template->id,
927 'name' => $template->name,
928 'key' => $template->form_key,
929 'description' => $template->description,
930 'url' => admin_url( 'admin.php?page=formidable&frm_action=duplicate&id=' . absint( $template->id ) ),
931 'released' => $template->created_at,
932 'installed' => 1,
933 );
934 array_unshift( $templates, $template );
935 unset( $template );
936 }
937 }
938
939 private static function get_edit_vars( $id, $errors = array(), $message = '', $create_link = false ) {
940 global $frm_vars;
941
942 $form = FrmForm::getOne( $id );
943 if ( ! $form ) {
944 wp_die( esc_html__( 'You are trying to edit a form that does not exist.', 'formidable' ) );
945 }
946
947 if ( $form->parent_form_id ) {
948 /* translators: %1$s: Start link HTML, %2$s: End link HTML */
949 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>' ) );
950 }
951
952 $frm_field_selection = FrmField::field_selection();
953
954 $fields = FrmField::get_all_for_form( $form->id );
955
956 // Automatically add end section fields if they don't exist (2.0 migration).
957 $reset_fields = false;
958 FrmFormsHelper::auto_add_end_section_fields( $form, $fields, $reset_fields );
959
960 if ( $reset_fields ) {
961 $fields = FrmField::get_all_for_form( $form->id, '', 'exclude' );
962 }
963
964 unset( $reset_fields );
965
966 $args = array( 'parent_form_id' => $form->id );
967 $values = FrmAppHelper::setup_edit_vars( $form, 'forms', '', true, array(), $args );
968
969 /**
970 * Allows modifying the list of fields in the form builder.
971 *
972 * @since 5.0.04
973 *
974 * @param object[] $fields Array of fields.
975 * @param array $args The arguments. Contains `form`.
976 */
977 $values['fields'] = apply_filters( 'frm_fields_in_form_builder', $fields, compact( 'form' ) );
978
979 $edit_message = __( 'Form was successfully updated.', 'formidable' );
980 if ( $form->is_template && $message == $edit_message ) {
981 $message = __( 'Template was successfully updated.', 'formidable' );
982 }
983
984 $all_templates = FrmForm::getAll( array( 'is_template' => 1 ), 'name' );
985 $has_fields = isset( $values['fields'] ) && ! empty( $values['fields'] );
986
987 if ( defined( 'DOING_AJAX' ) ) {
988 wp_die();
989 } else {
990 require( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/edit.php' );
991 }
992 }
993
994 public static function get_settings_vars( $id, $errors = array(), $args = array() ) {
995 FrmAppHelper::permission_check( 'frm_edit_forms' );
996
997 global $frm_vars;
998
999 if ( ! is_array( $args ) ) {
1000 // For reverse compatibility.
1001 $args = array(
1002 'message' => $args,
1003 );
1004 }
1005
1006 $defaults = array(
1007 'message' => '',
1008 'warnings' => array(),
1009 );
1010 $args = array_merge( $defaults, $args );
1011 $message = $args['message'];
1012 $warnings = $args['warnings'];
1013
1014 $form = FrmForm::getOne( $id );
1015 $fields = FrmField::get_all_for_form( $id );
1016 $values = FrmAppHelper::setup_edit_vars( $form, 'forms', $fields, true );
1017
1018 /**
1019 * Allows changing fields in the form settings.
1020 *
1021 * @since 5.0.04
1022 *
1023 * @param array $fields Array of fields.
1024 * @param array $args The arguments. Contains `form`.
1025 */
1026 $values['fields'] = apply_filters( 'frm_fields_in_settings', $values['fields'], compact( 'form' ) );
1027
1028 self::clean_submit_html( $values );
1029
1030 $sections = self::get_settings_tabs( $values );
1031 $current = FrmAppHelper::simple_get( 't', 'sanitize_title', 'advanced_settings' );
1032
1033 require( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/settings.php' );
1034 }
1035
1036 /**
1037 * @since 4.0
1038 */
1039 public static function form_publish_button( $atts ) {
1040 $values = $atts['values'];
1041 include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/_publish_box.php' );
1042 }
1043
1044 /**
1045 * Get a list of all the settings tabs for the form settings page.
1046 *
1047 * @since 4.0
1048 *
1049 * @param array $values
1050 * @return array
1051 */
1052 private static function get_settings_tabs( $values ) {
1053 $sections = array(
1054 'advanced' => array(
1055 'name' => __( 'General', 'formidable' ),
1056 'title' => __( 'General Form Settings', 'formidable' ),
1057 'function' => array( __CLASS__, 'advanced_settings' ),
1058 'icon' => 'frm_icon_font frm_settings_icon',
1059 ),
1060 'email' => array(
1061 'name' => __( 'Actions & Notifications', 'formidable' ),
1062 'function' => array( 'FrmFormActionsController', 'email_settings' ),
1063 'id' => 'frm_notification_settings',
1064 'icon' => 'frm_icon_font frm_mail_bulk_icon',
1065 ),
1066 'permissions' => array(
1067 'name' => __( 'Form Permissions', 'formidable' ),
1068 'icon' => 'frm_icon_font frm_lock_icon',
1069 'html_class' => 'frm_show_upgrade frm_noallow',
1070 'data' => array(
1071 'medium' => 'permissions',
1072 'upgrade' => __( 'Form Permissions', 'formidable' ),
1073 'message' => __( 'Allow editing, protect forms and files, limit entries, and save drafts. Upgrade to get form and entry permissions.', 'formidable' ),
1074 ),
1075 ),
1076 'scheduling' => array(
1077 'name' => __( 'Form Scheduling', 'formidable' ),
1078 'icon' => 'frm_icon_font frm_calendar_icon',
1079 'html_class' => 'frm_show_upgrade frm_noallow',
1080 'data' => array(
1081 'medium' => 'scheduling',
1082 'upgrade' => __( 'Form scheduling settings', 'formidable' ),
1083 ),
1084 ),
1085 'buttons' => array(
1086 'name' => __( 'Styling & Buttons', 'formidable' ),
1087 'class' => __CLASS__,
1088 'function' => 'buttons_settings',
1089 'icon' => 'frm_icon_font frm_pallet_icon',
1090 ),
1091 'html' => array(
1092 'name' => __( 'Customize HTML', 'formidable' ),
1093 'class' => __CLASS__,
1094 'function' => 'html_settings',
1095 'icon' => 'frm_icon_font frm_code_icon',
1096 ),
1097 );
1098
1099 $sections = apply_filters( 'frm_add_form_settings_section', $sections, $values );
1100
1101 if ( FrmAppHelper::pro_is_installed() && ! FrmAppHelper::meets_min_pro_version( '4.0' ) ) {
1102 // Prevent settings from showing in 2 spots.
1103 unset( $sections['permissions'], $sections['scheduling'] );
1104 }
1105
1106 foreach ( $sections as $key => $section ) {
1107 $defaults = array(
1108 'html_class' => '',
1109 'name' => ucfirst( $key ),
1110 'icon' => 'frm_icon_font frm_settings_icon',
1111 );
1112
1113 $section = array_merge( $defaults, $section );
1114
1115 if ( ! isset( $section['anchor'] ) ) {
1116 $section['anchor'] = $key;
1117 }
1118 $section['anchor'] .= '_settings';
1119
1120 if ( ! isset( $section['title'] ) ) {
1121 $section['title'] = $section['name'];
1122 }
1123
1124 if ( ! isset( $section['id'] ) ) {
1125 $section['id'] = $section['anchor'];
1126 }
1127
1128 $sections[ $key ] = $section;
1129 }
1130
1131 return $sections;
1132 }
1133
1134 /**
1135 * @since 4.0
1136 *
1137 * @param array $values
1138 */
1139 public static function advanced_settings( $values ) {
1140 $first_h3 = 'frm_first_h3';
1141
1142 include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/settings-advanced.php';
1143 }
1144
1145 /**
1146 * @param array $values
1147 */
1148 private static function render_spam_settings( $values ) {
1149 if ( function_exists( 'akismet_http_post' ) ) {
1150 include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/spam-settings/akismet.php';
1151 }
1152 include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/spam-settings/honeypot.php';
1153 include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/spam-settings/antispam.php';
1154 }
1155
1156 /**
1157 * @since 4.0
1158 *
1159 * @param array $values
1160 */
1161 public static function buttons_settings( $values ) {
1162 $styles = apply_filters( 'frm_get_style_opts', array() );
1163
1164 $frm_settings = FrmAppHelper::get_settings();
1165 $no_global_style = $frm_settings->load_style === 'none';
1166
1167 include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/settings-buttons.php' );
1168 }
1169
1170 /**
1171 * @since 4.0
1172 *
1173 * @param array $values
1174 */
1175 public static function html_settings( $values ) {
1176 include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/settings-html.php' );
1177 }
1178
1179 /**
1180 * Replace old Submit Button href with new href to avoid errors in Chrome
1181 *
1182 * @since 2.03.08
1183 *
1184 * @param array|boolean $values
1185 */
1186 private static function clean_submit_html( &$values ) {
1187 if ( is_array( $values ) && isset( $values['submit_html'] ) ) {
1188 $values['submit_html'] = str_replace( 'javascript:void(0)', '#', $values['submit_html'] );
1189 }
1190 }
1191
1192 public static function mb_tags_box( $form_id, $class = '' ) {
1193 $fields = FrmField::get_all_for_form( $form_id, '', 'include' );
1194
1195 /**
1196 * Allows modifying the list of fields in the tags box.
1197 *
1198 * @since 5.0.04
1199 *
1200 * @param array $fields The list of fields.
1201 * @param array $args The arguments. Contains `form_id`.
1202 */
1203 $fields = apply_filters( 'frm_fields_in_tags_box', $fields, compact( 'form_id' ) );
1204 $linked_forms = array();
1205 $col = 'one';
1206 $settings_tab = FrmAppHelper::is_admin_page( 'formidable' ) ? true : false;
1207
1208 $cond_shortcodes = apply_filters( 'frm_conditional_shortcodes', array() );
1209 $entry_shortcodes = self::get_shortcode_helpers( $settings_tab );
1210
1211 $advanced_helpers = self::advanced_helpers( compact( 'fields', 'form_id' ) );
1212
1213 include( FrmAppHelper::plugin_path() . '/classes/views/shared/mb_adv_info.php' );
1214 }
1215
1216 /**
1217 * @since 3.04.01
1218 */
1219 private static function advanced_helpers( $atts ) {
1220 $advanced_helpers = array(
1221 'default' => array(
1222 'heading' => __( 'Customize field values with the following parameters.', 'formidable' ),
1223 'codes' => self::get_advanced_shortcodes(),
1224 ),
1225 );
1226
1227 $user_fields = self::user_shortcodes();
1228 if ( ! empty( $user_fields ) ) {
1229 $user_helpers = array();
1230 foreach ( $user_fields as $uk => $uf ) {
1231 $user_helpers[ '|user_id| show="' . $uk . '"' ] = $uf;
1232 unset( $uk, $uf );
1233 }
1234
1235 $advanced_helpers['user_id'] = array(
1236 'codes' => $user_helpers,
1237 );
1238 }
1239
1240 /**
1241 * Add extra helper shortcodes on the Advanced tab in form settings and views
1242 *
1243 * @since 3.04.01
1244 *
1245 * @param array $atts - Includes fields and form_id
1246 */
1247 return apply_filters( 'frm_advanced_helpers', $advanced_helpers, $atts );
1248 }
1249
1250 /**
1251 * Get an array of the options to display in the advanced tab
1252 * of the customization panel
1253 *
1254 * @since 2.0.6
1255 */
1256 private static function get_advanced_shortcodes() {
1257 $adv_shortcodes = array(
1258 'x sep=", "' => array(
1259 'label' => __( 'Separator', 'formidable' ),
1260 'title' => __( 'Use a different separator for checkbox fields', 'formidable' ),
1261 ),
1262 'x format="d-m-Y"' => array(
1263 'label' => __( 'Date Format', 'formidable' ),
1264 ),
1265 'x show="field_label"' => array(
1266 'label' => __( 'Field Label', 'formidable' ),
1267 ),
1268 'x wpautop=0' => array(
1269 'label' => __( 'No Auto P', 'formidable' ),
1270 'title' => __( 'Do not automatically add any paragraphs or line breaks', 'formidable' ),
1271 ),
1272 );
1273 $adv_shortcodes = apply_filters( 'frm_advanced_shortcodes', $adv_shortcodes );
1274
1275 // __( 'Leave blank instead of defaulting to User Login', 'formidable' ) : blank=1
1276
1277 return $adv_shortcodes;
1278 }
1279
1280 /**
1281 * @since 3.04.01
1282 */
1283 private static function user_shortcodes() {
1284 $options = array(
1285 'ID' => __( 'User ID', 'formidable' ),
1286 'first_name' => __( 'First Name', 'formidable' ),
1287 'last_name' => __( 'Last Name', 'formidable' ),
1288 'display_name' => __( 'Display Name', 'formidable' ),
1289 'user_login' => __( 'User Login', 'formidable' ),
1290 'user_email' => __( 'Email', 'formidable' ),
1291 'avatar' => __( 'Avatar', 'formidable' ),
1292 'author_link' => __( 'Author Link', 'formidable' ),
1293 );
1294
1295 return apply_filters( 'frm_user_shortcodes', $options );
1296 }
1297
1298 /**
1299 * Get an array of the helper shortcodes to display in the customization panel
1300 *
1301 * @since 2.0.6
1302 */
1303 private static function get_shortcode_helpers( $settings_tab ) {
1304 $entry_shortcodes = array(
1305 'id' => __( 'Entry ID', 'formidable' ),
1306 'key' => __( 'Entry Key', 'formidable' ),
1307 'post_id' => __( 'Post ID', 'formidable' ),
1308 'ip' => __( 'User IP', 'formidable' ),
1309 'created-at' => __( 'Entry created', 'formidable' ),
1310 'updated-at' => __( 'Entry updated', 'formidable' ),
1311 '' => '',
1312 'siteurl' => __( 'Site URL', 'formidable' ),
1313 'sitename' => __( 'Site Name', 'formidable' ),
1314 );
1315
1316 if ( ! FrmAppHelper::pro_is_installed() ) {
1317 unset( $entry_shortcodes['post_id'] );
1318 }
1319
1320 if ( $settings_tab ) {
1321 $entry_shortcodes['default-message'] = __( 'Default Msg', 'formidable' );
1322 $entry_shortcodes['default-html'] = __( 'Default HTML', 'formidable' );
1323 $entry_shortcodes['default-plain'] = __( 'Default Plain', 'formidable' );
1324 }
1325
1326 /**
1327 * Use this hook to add or remove buttons in the helpers section
1328 * in the customization panel
1329 *
1330 * @since 2.0.6
1331 */
1332 $entry_shortcodes = apply_filters( 'frm_helper_shortcodes', $entry_shortcodes, $settings_tab );
1333
1334 return $entry_shortcodes;
1335 }
1336
1337 /**
1338 * Insert the form class setting into the form
1339 */
1340 public static function form_classes( $form ) {
1341 if ( isset( $form->options['form_class'] ) ) {
1342 echo esc_attr( sanitize_text_field( $form->options['form_class'] ) );
1343 }
1344
1345 if ( ! empty( $form->options['js_validate'] ) ) {
1346 echo ' frm_js_validate ';
1347 self::add_js_validate_form_to_global_vars( $form );
1348 }
1349 }
1350
1351 /**
1352 * @since 5.0.03
1353 *
1354 * @param stdClass $form
1355 */
1356 public static function add_js_validate_form_to_global_vars( $form ) {
1357 global $frm_vars;
1358 if ( ! isset( $frm_vars['js_validate_forms'] ) ) {
1359 $frm_vars['js_validate_forms'] = array();
1360 }
1361 $frm_vars['js_validate_forms'][ $form->id ] = $form;
1362 }
1363
1364 public static function get_email_html() {
1365 FrmAppHelper::permission_check( 'frm_view_forms' );
1366 check_ajax_referer( 'frm_ajax', 'nonce' );
1367
1368 echo FrmEntriesController::show_entry_shortcode( // WPCS: XSS ok.
1369 array(
1370 'form_id' => FrmAppHelper::get_post_param( 'form_id', '', 'absint' ),
1371 'default_email' => true,
1372 'plain_text' => FrmAppHelper::get_post_param( 'plain_text', '', 'absint' ),
1373 )
1374 );
1375 wp_die();
1376 }
1377
1378 public static function filter_content( $content, $form, $entry = false ) {
1379 self::get_entry_by_param( $entry );
1380 if ( ! $entry ) {
1381 return $content;
1382 }
1383
1384 if ( is_object( $form ) ) {
1385 $form = $form->id;
1386 }
1387
1388 $shortcodes = FrmFieldsHelper::get_shortcodes( $content, $form );
1389 $content = apply_filters( 'frm_replace_content_shortcodes', $content, $entry, $shortcodes );
1390
1391 return $content;
1392 }
1393
1394 private static function get_entry_by_param( &$entry ) {
1395 if ( ! $entry || ! is_object( $entry ) ) {
1396 if ( ! $entry || ! is_numeric( $entry ) ) {
1397 $entry = FrmAppHelper::get_post_param( 'id', false, 'sanitize_title' );
1398 }
1399
1400 FrmEntry::maybe_get_entry( $entry );
1401 }
1402 }
1403
1404 public static function replace_content_shortcodes( $content, $entry, $shortcodes ) {
1405 return FrmFieldsHelper::replace_content_shortcodes( $content, $entry, $shortcodes );
1406 }
1407
1408 public static function process_bulk_form_actions( $errors ) {
1409 if ( ! $_REQUEST ) {
1410 return $errors;
1411 }
1412
1413 $bulkaction = FrmAppHelper::get_param( 'action', '', 'get', 'sanitize_text_field' );
1414 if ( $bulkaction == - 1 ) {
1415 $bulkaction = FrmAppHelper::get_param( 'action2', '', 'get', 'sanitize_title' );
1416 }
1417
1418 if ( ! empty( $bulkaction ) && strpos( $bulkaction, 'bulk_' ) === 0 ) {
1419 FrmAppHelper::remove_get_action();
1420
1421 $bulkaction = str_replace( 'bulk_', '', $bulkaction );
1422 }
1423
1424 $ids = FrmAppHelper::get_param( 'item-action', '', 'get', 'sanitize_text_field' );
1425 if ( empty( $ids ) ) {
1426 $errors[] = __( 'No forms were specified', 'formidable' );
1427
1428 return $errors;
1429 }
1430
1431 $permission_error = FrmAppHelper::permission_nonce_error( '', '_wpnonce', 'bulk-toplevel_page_formidable' );
1432 if ( $permission_error !== false ) {
1433 $errors[] = $permission_error;
1434
1435 return $errors;
1436 }
1437
1438 if ( ! is_array( $ids ) ) {
1439 $ids = explode( ',', $ids );
1440 }
1441
1442 switch ( $bulkaction ) {
1443 case 'delete':
1444 $message = self::bulk_destroy( $ids );
1445 break;
1446 case 'trash':
1447 $message = self::bulk_trash( $ids );
1448 break;
1449 case 'untrash':
1450 $message = self::bulk_untrash( $ids );
1451 }
1452
1453 if ( isset( $message ) && ! empty( $message ) ) {
1454 $errors['message'] = $message;
1455 }
1456
1457 return $errors;
1458 }
1459
1460 public static function route() {
1461 $action = isset( $_REQUEST['frm_action'] ) ? 'frm_action' : 'action';
1462 $vars = array();
1463 FrmAppHelper::include_svg();
1464
1465 if ( isset( $_POST['frm_compact_fields'] ) ) {
1466 FrmAppHelper::permission_check( 'frm_edit_forms' );
1467
1468 // Javascript needs to be allowed in some field settings.
1469 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1470 $json_vars = htmlspecialchars_decode( nl2br( str_replace( '&quot;', '"', wp_unslash( $_POST['frm_compact_fields'] ) ) ) );
1471 $json_vars = json_decode( $json_vars, true );
1472 if ( empty( $json_vars ) ) {
1473 // json decoding failed so we should return an error message.
1474 $action = FrmAppHelper::get_param( $action, '', 'get', 'sanitize_title' );
1475 if ( 'edit' == $action ) {
1476 $action = 'update';
1477 }
1478
1479 add_filter( 'frm_validate_form', 'FrmFormsController::json_error' );
1480 } else {
1481 $vars = FrmAppHelper::json_to_array( $json_vars );
1482 $action = $vars[ $action ];
1483 unset( $_REQUEST['frm_compact_fields'], $_POST['frm_compact_fields'] );
1484 $_REQUEST = array_merge( $_REQUEST, $vars );
1485 $_POST = array_merge( $_POST, $_REQUEST );
1486 }
1487 } else {
1488 $action = FrmAppHelper::get_param( $action, '', 'get', 'sanitize_title' );
1489 if ( isset( $_REQUEST['delete_all'] ) ) {
1490 // Override the action for this page.
1491 $action = 'delete_all';
1492 }
1493 }
1494
1495 add_action( 'frm_load_form_hooks', 'FrmHooksController::trigger_load_form_hooks' );
1496 FrmAppHelper::trigger_hook_load( 'form' );
1497
1498 switch ( $action ) {
1499 case 'new':
1500 return self::new_form( $vars );
1501 case 'create':
1502 case 'edit':
1503 case 'update':
1504 case 'duplicate':
1505 case 'trash':
1506 case 'untrash':
1507 case 'destroy':
1508 case 'delete_all':
1509 case 'settings':
1510 case 'update_settings':
1511 return self::$action( $vars );
1512 case 'lite-reports':
1513 return self::no_reports( $vars );
1514 case 'views':
1515 return self::no_views( $vars );
1516 default:
1517 do_action( 'frm_form_action_' . $action );
1518 if ( apply_filters( 'frm_form_stop_action_' . $action, false ) ) {
1519 return;
1520 }
1521
1522 $action = FrmAppHelper::get_param( 'action', '', 'get', 'sanitize_text_field' );
1523 if ( $action == - 1 ) {
1524 $action = FrmAppHelper::get_param( 'action2', '', 'get', 'sanitize_title' );
1525 }
1526
1527 if ( strpos( $action, 'bulk_' ) === 0 ) {
1528 FrmAppHelper::remove_get_action();
1529
1530 return self::list_form();
1531 }
1532
1533 return self::display_forms_list();
1534 }
1535 }
1536
1537 public static function json_error( $errors ) {
1538 $errors['json'] = __( 'Abnormal HTML characters prevented your form from saving correctly', 'formidable' );
1539
1540 return $errors;
1541 }
1542
1543 /**
1544 * Education for premium features.
1545 *
1546 * @since 4.05
1547 */
1548 public static function add_form_style_tab_options() {
1549 include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/add_form_style_options.php' );
1550 }
1551
1552 /**
1553 * Add education about views.
1554 *
1555 * @since 4.07
1556 */
1557 public static function no_views( $values = array() ) {
1558 FrmAppHelper::include_svg();
1559 $id = FrmAppHelper::get_param( 'form', '', 'get', 'absint' );
1560 $form = $id ? FrmForm::getOne( $id ) : false;
1561
1562 include FrmAppHelper::plugin_path() . '/classes/views/shared/views-info.php';
1563 }
1564
1565 /**
1566 * Add education about reports.
1567 *
1568 * @since 4.07
1569 */
1570 public static function no_reports( $values = array() ) {
1571 $id = FrmAppHelper::get_param( 'form', '', 'get', 'absint' );
1572 $form = $id ? FrmForm::getOne( $id ) : false;
1573
1574 include FrmAppHelper::plugin_path() . '/classes/views/shared/reports-info.php';
1575 }
1576
1577 /* FRONT-END FORMS */
1578 public static function admin_bar_css() {
1579 if ( is_admin() || ! current_user_can( 'frm_edit_forms' ) ) {
1580 return;
1581 }
1582
1583 self::move_menu_to_footer();
1584
1585 add_action( 'wp_before_admin_bar_render', 'FrmFormsController::admin_bar_configure' );
1586 FrmAppHelper::load_font_style();
1587 }
1588
1589 /**
1590 * @since 4.05.02
1591 */
1592 private static function move_menu_to_footer() {
1593 $settings = FrmAppHelper::get_settings();
1594 if ( empty( $settings->admin_bar ) ) {
1595 remove_action( 'wp_body_open', 'wp_admin_bar_render', 0 );
1596 }
1597 }
1598
1599 public static function admin_bar_configure() {
1600 global $frm_vars;
1601 if ( empty( $frm_vars['forms_loaded'] ) ) {
1602 return;
1603 }
1604
1605 $actions = array();
1606 foreach ( $frm_vars['forms_loaded'] as $form ) {
1607 if ( is_object( $form ) ) {
1608 $actions[ $form->id ] = $form->name;
1609 }
1610 unset( $form );
1611 }
1612
1613 if ( empty( $actions ) ) {
1614 return;
1615 }
1616
1617 self::add_menu_to_admin_bar();
1618 self::add_forms_to_admin_bar( $actions );
1619 }
1620
1621 /**
1622 * @since 2.05.07
1623 */
1624 public static function add_menu_to_admin_bar() {
1625 global $wp_admin_bar;
1626
1627 $wp_admin_bar->add_node(
1628 array(
1629 'id' => 'frm-forms',
1630 'title' => '<span class="ab-icon"></span><span class="ab-label">' . FrmAppHelper::get_menu_name() . '</span>',
1631 'href' => admin_url( 'admin.php?page=formidable' ),
1632 'meta' => array(
1633 'title' => FrmAppHelper::get_menu_name(),
1634 ),
1635 )
1636 );
1637 }
1638
1639 /**
1640 * @since 2.05.07
1641 */
1642 private static function add_forms_to_admin_bar( $actions ) {
1643 global $wp_admin_bar;
1644
1645 asort( $actions );
1646
1647 foreach ( $actions as $form_id => $name ) {
1648
1649 $wp_admin_bar->add_node(
1650 array(
1651 'parent' => 'frm-forms',
1652 'id' => 'edit_form_' . $form_id,
1653 'title' => empty( $name ) ? __( '(no title)', 'formidable' ) : $name,
1654 'href' => FrmForm::get_edit_link( $form_id ),
1655 )
1656 );
1657 }
1658 }
1659
1660 /**
1661 * The formidable shortcode
1662 *
1663 * @param array $atts The params from the shortcode.
1664 */
1665 public static function get_form_shortcode( $atts ) {
1666 global $frm_vars;
1667 if ( isset( $frm_vars['skip_shortcode'] ) && $frm_vars['skip_shortcode'] ) {
1668 $sc = '[formidable';
1669 $sc .= FrmAppHelper::array_to_html_params( $atts );
1670 return $sc . ']';
1671 }
1672
1673 $shortcode_atts = shortcode_atts(
1674 array(
1675 'id' => '',
1676 'key' => '',
1677 'title' => false,
1678 'description' => false,
1679 'readonly' => false,
1680 'entry_id' => false,
1681 'fields' => array(),
1682 'exclude_fields' => array(),
1683 'minimize' => false,
1684 ),
1685 $atts
1686 );
1687 do_action( 'formidable_shortcode_atts', $shortcode_atts, $atts );
1688
1689 return self::show_form( $shortcode_atts['id'], $shortcode_atts['key'], $shortcode_atts['title'], $shortcode_atts['description'], $atts );
1690 }
1691
1692 public static function show_form( $id = '', $key = '', $title = false, $description = false, $atts = array() ) {
1693 if ( empty( $id ) ) {
1694 $id = $key;
1695 }
1696
1697 $form = self::maybe_get_form_to_show( $id );
1698 if ( ! $form ) {
1699 return __( 'Please select a valid form', 'formidable' );
1700 }
1701
1702 FrmAppController::maybe_update_styles();
1703
1704 add_action( 'frm_load_form_hooks', 'FrmHooksController::trigger_load_form_hooks' );
1705 FrmAppHelper::trigger_hook_load( 'form', $form );
1706
1707 $form = apply_filters( 'frm_pre_display_form', $form );
1708
1709 $frm_settings = FrmAppHelper::get_settings( array( 'current_form' => $form->id ) );
1710
1711 if ( self::is_viewable_draft_form( $form ) ) {
1712 // don't show a draft form on a page
1713 $form = __( 'Please select a valid form', 'formidable' );
1714 } elseif ( ! FrmForm::is_visible_to_user( $form ) ) {
1715 $form = do_shortcode( $frm_settings->login_msg );
1716 } else {
1717 do_action( 'frm_pre_get_form', $form );
1718 $form = self::get_form( $form, $title, $description, $atts );
1719
1720 /**
1721 * Use this shortcode to check for external shortcodes that may span
1722 * across multiple fields in the customizable HTML
1723 *
1724 * @since 2.0.8
1725 */
1726 $form = apply_filters( 'frm_filter_final_form', $form );
1727 }
1728
1729 return $form;
1730 }
1731
1732 private static function maybe_get_form_to_show( $id ) {
1733 $form = false;
1734
1735 if ( ! empty( $id ) ) { // no form id or key set
1736 $form = FrmForm::getOne( $id );
1737 if ( ! $form || $form->parent_form_id || $form->status == 'trash' ) {
1738 $form = false;
1739 }
1740 }
1741
1742 return $form;
1743 }
1744
1745 private static function is_viewable_draft_form( $form ) {
1746 return $form->status == 'draft' && current_user_can( 'frm_edit_forms' ) && ! FrmAppHelper::is_preview_page();
1747 }
1748
1749 public static function get_form( $form, $title, $description, $atts = array() ) {
1750 ob_start();
1751
1752 do_action( 'frm_before_get_form', $atts );
1753
1754 self::get_form_contents( $form, $title, $description, $atts );
1755 self::enqueue_scripts( FrmForm::get_params( $form ) );
1756
1757 $contents = ob_get_contents();
1758 ob_end_clean();
1759
1760 self::maybe_minimize_form( $atts, $contents );
1761
1762 return $contents;
1763 }
1764
1765 public static function enqueue_scripts( $params ) {
1766 do_action( 'frm_enqueue_form_scripts', $params );
1767 }
1768
1769 public static function get_form_contents( $form, $title, $description, $atts ) {
1770 $params = FrmForm::get_params( $form );
1771 $errors = self::get_saved_errors( $form, $params );
1772 $fields = FrmFieldsHelper::get_form_fields( $form->id, $errors );
1773 $reset = false;
1774 $pass_args = compact( 'form', 'fields', 'errors', 'title', 'description', 'reset' );
1775
1776 $handle_process_here = $params['action'] == 'create' && $params['posted_form_id'] == $form->id && $_POST;
1777
1778 if ( ! $handle_process_here ) {
1779 do_action( 'frm_display_form_action', $params, $fields, $form, $title, $description );
1780 if ( apply_filters( 'frm_continue_to_new', true, $form->id, $params['action'] ) ) {
1781 self::show_form_after_submit( $pass_args );
1782 }
1783 } elseif ( ! empty( $errors ) ) {
1784 self::show_form_after_submit( $pass_args );
1785
1786 } else {
1787
1788 do_action( 'frm_validate_form_creation', $params, $fields, $form, $title, $description );
1789
1790 if ( apply_filters( 'frm_continue_to_create', true, $form->id ) ) {
1791 $entry_id = self::just_created_entry( $form->id );
1792 $pass_args['entry_id'] = $entry_id;
1793 $pass_args['reset'] = true;
1794 $pass_args['conf_method'] = self::get_confirmation_method( compact( 'form', 'entry_id' ) );
1795
1796 self::run_success_action( $pass_args );
1797
1798 do_action(
1799 'frm_after_entry_processed',
1800 array(
1801 'entry_id' => $entry_id,
1802 'form' => $form,
1803 )
1804 );
1805 }
1806 }
1807 }
1808
1809 /**
1810 * If the form was processed earlier (init), get the generated errors
1811 *
1812 * @since 2.05
1813 */
1814 private static function get_saved_errors( $form, $params ) {
1815 global $frm_vars;
1816
1817 if ( $params['posted_form_id'] == $form->id && $_POST && isset( $frm_vars['created_entries'][ $form->id ] ) ) {
1818 $errors = $frm_vars['created_entries'][ $form->id ]['errors'];
1819 } else {
1820 $errors = array();
1821 }
1822
1823 return $errors;
1824 }
1825
1826 /**
1827 * @since 2.2.7
1828 */
1829 public static function just_created_entry( $form_id ) {
1830 global $frm_vars;
1831
1832 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;
1833 }
1834
1835 /**
1836 * @since 3.0
1837 */
1838 private static function get_confirmation_method( $atts ) {
1839 $opt = 'success_action';
1840 $method = ( isset( $atts['form']->options[ $opt ] ) && ! empty( $atts['form']->options[ $opt ] ) ) ? $atts['form']->options[ $opt ] : 'message';
1841 $method = apply_filters( 'frm_success_filter', $method, $atts['form'], 'create' );
1842
1843 if ( $method != 'message' && ( ! $atts['entry_id'] || ! is_numeric( $atts['entry_id'] ) ) ) {
1844 $method = 'message';
1845 }
1846
1847 return $method;
1848 }
1849
1850 public static function maybe_trigger_redirect( $form, $params, $args ) {
1851 if ( ! isset( $params['id'] ) ) {
1852 global $frm_vars;
1853 $params['id'] = $frm_vars['created_entries'][ $form->id ]['entry_id'];
1854 }
1855
1856 $conf_method = self::get_confirmation_method(
1857 array(
1858 'form' => $form,
1859 'entry_id' => $params['id'],
1860 )
1861 );
1862
1863 if ( 'redirect' === $conf_method ) {
1864 self::trigger_redirect( $form, $params, $args );
1865 }
1866 }
1867
1868 public static function trigger_redirect( $form, $params, $args ) {
1869 $success_args = array(
1870 'action' => $params['action'],
1871 'conf_method' => 'redirect',
1872 'form' => $form,
1873 'entry_id' => $params['id'],
1874 );
1875
1876 if ( isset( $args['ajax'] ) ) {
1877 $success_args['ajax'] = $args['ajax'];
1878 }
1879
1880 self::run_success_action( $success_args );
1881 }
1882
1883 /**
1884 * Used when the success action is not 'message'
1885 *
1886 * @since 2.05
1887 */
1888 public static function run_success_action( $args ) {
1889 $extra_args = $args;
1890 unset( $extra_args['form'] );
1891
1892 do_action( 'frm_success_action', $args['conf_method'], $args['form'], $args['form']->options, $args['entry_id'], $extra_args );
1893
1894 $opt = ( ! isset( $args['action'] ) || $args['action'] === 'create' ) ? 'success' : 'edit';
1895
1896 $args['success_opt'] = $opt;
1897 if ( $args['conf_method'] === 'page' && is_numeric( $args['form']->options[ $opt . '_page_id' ] ) ) {
1898 self::load_page_after_submit( $args );
1899 } elseif ( $args['conf_method'] === 'redirect' ) {
1900 self::redirect_after_submit( $args );
1901 } else {
1902 self::show_message_after_save( $args );
1903 }
1904 }
1905
1906 /**
1907 * @since 3.0
1908 */
1909 private static function load_page_after_submit( $args ) {
1910 global $post;
1911 $opt = $args['success_opt'];
1912 if ( ! $post || $args['form']->options[ $opt . '_page_id' ] != $post->ID ) {
1913 $page = get_post( $args['form']->options[ $opt . '_page_id' ] );
1914 $old_post = $post;
1915 $post = $page;
1916 $content = apply_filters( 'frm_content', $page->post_content, $args['form'], $args['entry_id'] );
1917 echo apply_filters( 'the_content', $content ); // WPCS: XSS ok.
1918 $post = $old_post;
1919 }
1920 }
1921
1922 /**
1923 * @since 3.0
1924 */
1925 private static function redirect_after_submit( $args ) {
1926 global $frm_vars;
1927
1928 add_filter( 'frm_use_wpautop', '__return_false' );
1929
1930 $opt = $args['success_opt'];
1931 $success_url = trim( $args['form']->options[ $opt . '_url' ] );
1932 $success_url = apply_filters( 'frm_content', $success_url, $args['form'], $args['entry_id'] );
1933 $success_url = do_shortcode( $success_url );
1934
1935 $success_msg = isset( $args['form']->options[ $opt . '_msg' ] ) ? $args['form']->options[ $opt . '_msg' ] : __( 'Please wait while you are redirected.', 'formidable' );
1936
1937 $redirect_msg = self::get_redirect_message( $success_url, $success_msg, $args );
1938
1939 $args['id'] = $args['entry_id'];
1940 FrmEntriesController::delete_entry_before_redirect( $success_url, $args['form'], $args );
1941
1942 add_filter( 'frm_redirect_url', 'FrmEntriesController::prepare_redirect_url' );
1943 $success_url = apply_filters( 'frm_redirect_url', $success_url, $args['form'], $args );
1944
1945 $doing_ajax = FrmAppHelper::doing_ajax();
1946
1947 if ( isset( $args['ajax'] ) && $args['ajax'] && $doing_ajax ) {
1948 echo json_encode( array( 'redirect' => $success_url ) );
1949 wp_die();
1950 } elseif ( ! headers_sent() ) {
1951 wp_redirect( esc_url_raw( $success_url ) );
1952 die(); // do not use wp_die or redirect fails
1953 } else {
1954 add_filter( 'frm_use_wpautop', '__return_true' );
1955
1956 echo $redirect_msg; // WPCS: XSS ok.
1957 echo "<script type='text/javascript'>window.onload = function(){setTimeout(window.location='" . esc_url_raw( $success_url ) . "', 8000);}</script>";
1958 }
1959 }
1960
1961 /**
1962 * @since 3.0
1963 *
1964 * @param string $success_url
1965 * @param string $success_msg
1966 * @param array $args
1967 */
1968 private static function get_redirect_message( $success_url, $success_msg, $args ) {
1969 $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/>' .
1970 /* translators: %1$s: Start link HTML, %2$s: End link HTML */
1971 sprintf( __( '%1$sClick here%2$s if you are not automatically redirected.', 'formidable' ), '<a href="' . esc_url( $success_url ) . '">', '</a>' ) .
1972 '</div></div>';
1973
1974 $redirect_args = array(
1975 'entry_id' => $args['entry_id'],
1976 'form_id' => $args['form']->id,
1977 'form' => $args['form'],
1978 );
1979
1980 return apply_filters( 'frm_redirect_msg', $redirect_msg, $redirect_args );
1981 }
1982
1983 /**
1984 * Prepare to show the success message and empty form after submit
1985 *
1986 * @since 2.05
1987 */
1988 public static function show_message_after_save( $atts ) {
1989 $atts['message'] = self::prepare_submit_message( $atts['form'], $atts['entry_id'] );
1990
1991 if ( ! isset( $atts['form']->options['show_form'] ) || $atts['form']->options['show_form'] ) {
1992 self::show_form_after_submit( $atts );
1993 } else {
1994 self::show_lone_success_messsage( $atts );
1995 }
1996 }
1997
1998 /**
1999 * Show an empty form
2000 *
2001 * @since 2.05
2002 */
2003 private static function show_form_after_submit( $args ) {
2004 self::fill_atts_for_form_display( $args );
2005
2006 $errors = $args['errors'];
2007 $message = $args['message'];
2008 $form = $args['form'];
2009 $title = $args['title'];
2010 $description = $args['description'];
2011
2012 if ( empty( $args['fields'] ) ) {
2013 $values = array(
2014 'custom_style' => FrmAppHelper::custom_style_value( array() ),
2015 );
2016 } else {
2017 $values = FrmEntriesHelper::setup_new_vars( $args['fields'], $form, $args['reset'] );
2018 }
2019 unset( $args );
2020
2021 $include_form_tag = apply_filters( 'frm_include_form_tag', true, $form );
2022
2023 $frm_settings = FrmAppHelper::get_settings();
2024 $submit = isset( $form->options['submit_value'] ) ? $form->options['submit_value'] : $frm_settings->submit_value;
2025
2026 global $frm_vars;
2027 self::maybe_load_css( $form, $values['custom_style'], $frm_vars['load_css'] );
2028
2029 $message_placement = self::message_placement( $form, $message );
2030
2031 include FrmAppHelper::plugin_path() . '/classes/views/frm-entries/new.php';
2032 }
2033
2034 /**
2035 * @return string - 'before', 'after', or 'submit'
2036 *
2037 * @since 4.05.02
2038 */
2039 private static function message_placement( $form, $message ) {
2040 $place = 'before';
2041
2042 if ( $message && isset( $form->options['form_class'] ) ) {
2043 if ( strpos( $form->options['form_class'], 'frm_below_success' ) !== false ) {
2044 $place = 'after';
2045 } elseif ( strpos( $form->options['form_class'], 'frm_inline_success' ) !== false ) {
2046 $place = 'submit';
2047 }
2048 }
2049
2050 /**
2051 * @return string - 'before' or 'after'
2052 *
2053 * @since 4.05.02
2054 */
2055 return apply_filters( 'frm_message_placement', $place, compact( 'form', 'message' ) );
2056 }
2057
2058 /**
2059 * Get all the values needed on the new.php entry page
2060 *
2061 * @since 2.05
2062 */
2063 private static function fill_atts_for_form_display( &$args ) {
2064 $defaults = array(
2065 'errors' => array(),
2066 'message' => '',
2067 'fields' => array(),
2068 'form' => array(),
2069 'title' => true,
2070 'description' => false,
2071 'reset' => false,
2072 );
2073 $args = wp_parse_args( $args, $defaults );
2074 }
2075
2076 /**
2077 * Show the success message without the form
2078 *
2079 * @since 2.05
2080 */
2081 private static function show_lone_success_messsage( $atts ) {
2082 global $frm_vars;
2083 $values = FrmEntriesHelper::setup_new_vars( $atts['fields'], $atts['form'], true );
2084 self::maybe_load_css( $atts['form'], $values['custom_style'], $frm_vars['load_css'] );
2085
2086 $include_extra_container = 'frm_forms' . FrmFormsHelper::get_form_style_class( $values );
2087
2088 $errors = array();
2089 $form = $atts['form'];
2090 $message = $atts['message'];
2091
2092 include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/errors.php' );
2093 }
2094
2095 /**
2096 * Prepare the success message before it's shown
2097 *
2098 * @since 2.05
2099 */
2100 private static function prepare_submit_message( $form, $entry_id ) {
2101 $frm_settings = FrmAppHelper::get_settings( array( 'current_form' => $form->id ) );
2102
2103 if ( $entry_id && is_numeric( $entry_id ) ) {
2104 $message = isset( $form->options['success_msg'] ) ? $form->options['success_msg'] : $frm_settings->success_msg;
2105 $class = 'frm_message';
2106 } else {
2107 $message = $frm_settings->failed_msg;
2108 $class = FrmFormsHelper::form_error_class();
2109 }
2110
2111 $message = FrmFormsHelper::get_success_message( compact( 'message', 'form', 'entry_id', 'class' ) );
2112
2113 return apply_filters( 'frm_main_feedback', $message, $form, $entry_id );
2114 }
2115
2116 public static function front_head() {
2117 $version = FrmAppHelper::plugin_version();
2118 $suffix = FrmAppHelper::js_suffix();
2119
2120 if ( ! empty( $suffix ) && self::has_combo_js_file() ) {
2121 wp_register_script( 'formidable', FrmAppHelper::plugin_url() . '/js/frm.min.js', array( 'jquery' ), $version, true );
2122 } else {
2123 wp_register_script( 'formidable', FrmAppHelper::plugin_url() . "/js/formidable{$suffix}.js", array( 'jquery' ), $version, true );
2124 }
2125
2126 add_filter( 'script_loader_tag', 'FrmFormsController::defer_script_loading', 10, 2 );
2127
2128 if ( FrmAppHelper::is_admin() ) {
2129 // don't load this in back-end
2130 return;
2131 }
2132
2133 FrmAppHelper::localize_script( 'front' );
2134 FrmStylesController::enqueue_css( 'register' );
2135 }
2136
2137 /**
2138 * @since 3.0
2139 */
2140 public static function has_combo_js_file() {
2141 return is_readable( FrmAppHelper::plugin_path() . '/js/frm.min.js' );
2142 }
2143
2144 public static function maybe_load_css( $form, $this_load, $global_load ) {
2145 $load_css = FrmForm::is_form_loaded( $form, $this_load, $global_load );
2146
2147 if ( ! $load_css ) {
2148 return;
2149 }
2150
2151 global $frm_vars;
2152 self::footer_js( 'header' );
2153 $frm_vars['css_loaded'] = true;
2154
2155 self::load_late_css();
2156 }
2157
2158 /**
2159 * If css is loaded only on applicable pages, include it before the form loads
2160 * to prevent a flash of unstyled form.
2161 *
2162 * @since 4.01
2163 */
2164 private static function load_late_css() {
2165 $frm_settings = FrmAppHelper::get_settings();
2166 $late_css = $frm_settings->load_style === 'dynamic';
2167 if ( ! $late_css ) {
2168 return;
2169 }
2170
2171 global $wp_styles;
2172 if ( is_array( $wp_styles->queue ) && in_array( 'formidable', $wp_styles->queue ) ) {
2173 wp_print_styles( 'formidable' );
2174 }
2175 }
2176
2177 public static function defer_script_loading( $tag, $handle ) {
2178 if ( 'recaptcha-api' == $handle && ! strpos( $tag, 'defer' ) ) {
2179 $tag = str_replace( ' src', ' defer="defer" async="async" src', $tag );
2180 }
2181
2182 return $tag;
2183 }
2184
2185 public static function footer_js( $location = 'footer' ) {
2186 global $frm_vars;
2187
2188 FrmStylesController::enqueue_css();
2189
2190 if ( ! FrmAppHelper::is_admin() && $location != 'header' && ! empty( $frm_vars['forms_loaded'] ) ) {
2191 // load formidable js
2192 wp_enqueue_script( 'formidable' );
2193 }
2194 }
2195
2196 /**
2197 * @since 2.0.8
2198 */
2199 private static function maybe_minimize_form( $atts, &$content ) {
2200 // check if minimizing is turned on
2201 if ( self::is_minification_on( $atts ) ) {
2202 $content = str_replace( array( "\r\n", "\r", "\n", "\t", ' ' ), '', $content );
2203 }
2204 }
2205
2206 /**
2207 * @since 2.0.8
2208 * @return boolean
2209 */
2210 private static function is_minification_on( $atts ) {
2211 return isset( $atts['minimize'] ) && ! empty( $atts['minimize'] );
2212 }
2213
2214 /**
2215 * @deprecated 4.0
2216 */
2217 public static function new_form( $values = array() ) {
2218 FrmDeprecated::new_form( $values );
2219 }
2220
2221 /**
2222 * @deprecated 4.0
2223 */
2224 public static function create( $values = array() ) {
2225 _deprecated_function( __METHOD__, '4.0', 'FrmFormsController::update' );
2226 self::update( $values );
2227 }
2228
2229 /**
2230 * @deprecated 1.07.05
2231 * @codeCoverageIgnore
2232 */
2233 public static function add_default_templates( $path, $default = true, $template = true ) {
2234 FrmDeprecated::add_default_templates( $path, $default, $template );
2235 }
2236
2237 /**
2238 * @deprecated 3.0
2239 * @codeCoverageIgnore
2240 */
2241 public static function bulk_create_template( $ids ) {
2242 return FrmDeprecated::bulk_create_template( $ids );
2243 }
2244
2245 /**
2246 * @deprecated 2.03
2247 * @codeCoverageIgnore
2248 */
2249 public static function register_pro_scripts() {
2250 FrmDeprecated::register_pro_scripts();
2251 }
2252
2253 /**
2254 * @deprecated 3.0
2255 * @codeCoverageIgnore
2256 */
2257 public static function edit_key() {
2258 FrmDeprecated::edit_key();
2259 }
2260
2261 /**
2262 * @deprecated 3.0
2263 * @codeCoverageIgnore
2264 */
2265 public static function edit_description() {
2266 FrmDeprecated::edit_description();
2267 }
2268
2269 /**
2270 * @deprecated 4.08
2271 * @since 3.06
2272 */
2273 public static function add_new() {
2274 _deprecated_function( __FUNCTION__, '4.08' );
2275 }
2276 }
2277