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

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