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

2,279 lines 66.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 die( 'You are not allowed to call this page directly.' );
4 }
5
6 class FrmFormsController {
7
8 public static function menu() {
9 $menu_label = __( 'Forms', 'formidable' );
10 if ( ! FrmAppHelper::pro_is_installed() ) {
11 $menu_label .= ' (Lite)';
12 }
13 add_submenu_page( 'formidable', 'Formidable | ' . $menu_label, $menu_label, 'frm_view_forms', 'formidable', 'FrmFormsController::route' );
14
15 self::maybe_load_listing_hooks();
16 }
17
18 public static function maybe_load_listing_hooks() {
19 $action = FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
20 if ( ! empty( $action ) && ! in_array( $action, array( 'list', 'trash', 'untrash', 'destroy' ) ) ) {
21 return;
22 }
23
24 add_filter( 'get_user_option_managetoplevel_page_formidablecolumnshidden', 'FrmFormsController::hidden_columns' );
25
26 add_filter( 'manage_toplevel_page_formidable_columns', 'FrmFormsController::get_columns', 0 );
27 add_filter( 'manage_toplevel_page_formidable_sortable_columns', 'FrmFormsController::get_sortable_columns' );
28 }
29
30 public static function head() {
31 if ( wp_is_mobile() ) {
32 wp_enqueue_script( 'jquery-touch-punch' );
33 }
34 }
35
36 public static function register_widgets() {
37 require_once( FrmAppHelper::plugin_path() . '/classes/widgets/FrmShowForm.php' );
38 register_widget( 'FrmShowForm' );
39 }
40
41 /**
42 * Show a message about conditional logic
43 *
44 * @since 4.06.03
45 */
46 public static function logic_tip() {
47 $images_url = FrmAppHelper::plugin_url() . '/images/';
48 $data_message = __( 'Only show the fields you need and create branching forms. Upgrade to get conditional logic and question branching.', 'formidable' );
49 $data_message .= ' <img src="' . esc_attr( $images_url ) . '/survey-logic.png" srcset="' . esc_attr( $images_url ) . 'survey-logic@2x.png 2x" alt="' . esc_attr__( 'Conditional Logic options', 'formidable' ) . '"/>';
50 echo '<a href="javascript:void(0)" class="frm_noallow frm_show_upgrade frm_add_logic_link" data-upgrade="' . esc_attr__( 'Conditional Logic options', 'formidable' ) . '" data-message="' . esc_attr( $data_message ) . '" data-medium="builder" data-content="logic">';
51 FrmAppHelper::icon_by_class( 'frmfont frm_swap_icon' );
52 esc_html_e( 'Add Conditional Logic', 'formidable' );
53 echo '</a>';
54 }
55
56 /**
57 * By default, Divi processes form shortcodes on the edit post page.
58 * Now that won't do.
59 *
60 * @since 3.01
61 */
62 public static function prevent_divi_conflict( $shortcodes ) {
63 $shortcodes[] = 'formidable';
64
65 return $shortcodes;
66 }
67
68 public static function list_form() {
69 FrmAppHelper::permission_check( 'frm_view_forms' );
70
71 $message = '';
72 $params = FrmForm::list_page_params();
73 $errors = self::process_bulk_form_actions( array() );
74 if ( isset( $errors['message'] ) ) {
75 $message = $errors['message'];
76 unset( $errors['message'] );
77 }
78 $errors = apply_filters( 'frm_admin_list_form_action', $errors );
79
80 return self::display_forms_list( $params, $message, $errors );
81 }
82
83 /**
84 * Load the scripts before a modal can be triggered.
85 *
86 * @since 4.0
87 */
88 private static function init_modal() {
89 wp_enqueue_script( 'jquery-ui-dialog' );
90 wp_enqueue_style( 'jquery-ui-dialog' );
91 }
92
93 /**
94 * Create the default email action
95 *
96 * @since 2.02.11
97 *
98 * @param object|int $form
99 */
100 private static function create_default_email_action( $form ) {
101 FrmForm::maybe_get_form( $form );
102 $create_email = apply_filters( 'frm_create_default_email_action', true, $form );
103
104 if ( $create_email ) {
105 $action_control = FrmFormActionsController::get_form_actions( 'email' );
106 $action_control->create( $form->id );
107 }
108 }
109
110 public static function edit( $values = false ) {
111 FrmAppHelper::permission_check( 'frm_edit_forms' );
112
113 $id = isset( $values['id'] ) ? absint( $values['id'] ) : FrmAppHelper::get_param( 'id', '', 'get', 'absint' );
114
115 return self::get_edit_vars( $id );
116 }
117
118 public static function settings( $id = false, $message = '' ) {
119 FrmAppHelper::permission_check( 'frm_edit_forms' );
120
121 if ( ! $id || ! is_numeric( $id ) ) {
122 $id = FrmAppHelper::get_param( 'id', '', 'get', 'absint' );
123 }
124
125 return self::get_settings_vars( $id, array(), $message );
126 }
127
128 public static function update_settings() {
129 FrmAppHelper::permission_check( 'frm_edit_forms' );
130
131 $id = FrmAppHelper::get_param( 'id', '', 'get', 'absint' );
132
133 $errors = FrmForm::validate( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
134 $warnings = FrmFormsHelper::check_for_warnings( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
135
136 if ( count( $errors ) > 0 ) {
137 return self::get_settings_vars( $id, $errors, compact( 'warnings' ) );
138 }
139
140 do_action( 'frm_before_update_form_settings', $id );
141
142 $antispam_was_on = self::antispam_was_on( $id );
143
144 FrmForm::update( $id, $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
145
146 $antispam_is_on = ! empty( $_POST['options']['antispam'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
147 if ( $antispam_is_on !== $antispam_was_on ) {
148 FrmAntiSpam::clear_caches();
149 }
150
151 $message = __( 'Settings Successfully Updated', 'formidable' );
152
153 return self::get_settings_vars( $id, array(), compact( 'message', 'warnings' ) );
154 }
155
156 /**
157 * @param int $form_id
158 * @return bool
159 */
160 private static function antispam_was_on( $form_id ) {
161 $form = FrmForm::getOne( $form_id );
162 return ! empty( $form->options['antispam'] );
163 }
164
165 public static function update( $values = array() ) {
166 if ( empty( $values ) ) {
167 $values = $_POST; // phpcs:ignore WordPress.Security.NonceVerification.Missing
168 }
169
170 // Set radio button and checkbox meta equal to "other" value.
171 if ( FrmAppHelper::pro_is_installed() ) {
172 $values = FrmProEntry::mod_other_vals( $values, 'back' );
173 }
174
175 $errors = FrmForm::validate( $values );
176 $permission_error = FrmAppHelper::permission_nonce_error( 'frm_edit_forms', 'frm_save_form', 'frm_save_form_nonce' );
177 if ( $permission_error !== false ) {
178 $errors['form'] = $permission_error;
179 }
180
181 $id = isset( $values['id'] ) ? absint( $values['id'] ) : FrmAppHelper::get_param( 'id', '', 'get', 'absint' );
182
183 if ( count( $errors ) > 0 ) {
184 return self::get_edit_vars( $id, $errors );
185 } else {
186 FrmForm::update( $id, $values );
187 $message = __( 'Form was successfully updated.', 'formidable' );
188
189 if ( self::is_too_long( $values ) ) {
190 $message .= '<br/> ' . sprintf(
191 /* translators: %1$s: Start link HTML, %2$s: end link HTML */
192 __( 'However, your form is very long and may be %1$sreaching server limits%2$s.', 'formidable' ),
193 '<a href="https://formidableforms.com/knowledgebase/i-have-a-long-form-why-did-the-options-at-the-end-of-the-form-stop-saving/?utm_source=WordPress&utm_medium=builder&utm_campaign=liteplugin" target="_blank" rel="noopener">',
194 '</a>'
195 );
196 }
197
198 if ( defined( 'DOING_AJAX' ) ) {
199 wp_die( FrmAppHelper::kses( $message, array( 'a' ) ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
200 }
201
202 return self::get_edit_vars( $id, array(), $message );
203 }
204 }
205
206 /**
207 * Check if the value at the end of the form was included.
208 * If it's missing, it means other values at the end of the form
209 * were likely not saved either.
210 *
211 * @since 3.06.01
212 */
213 private static function is_too_long( $values ) {
214 return ( ! isset( $values['frm_end'] ) ) || empty( $values['frm_end'] );
215 }
216
217 /**
218 * Redirect to the url for creating from a template
219 * Also delete the current form
220 *
221 * @since 2.0
222 * @deprecated 3.06
223 */
224 public static function _create_from_template() {
225 _deprecated_function( __FUNCTION__, '3.06' );
226
227 FrmAppHelper::permission_check( 'frm_edit_forms' );
228 check_ajax_referer( 'frm_ajax', 'nonce' );
229
230 $current_form = FrmAppHelper::get_param( 'this_form', '', 'get', 'absint' );
231 $template_id = FrmAppHelper::get_param( 'id', '', 'get', 'absint' );
232
233 if ( $current_form ) {
234 FrmForm::destroy( $current_form );
235 }
236
237 echo esc_url_raw( admin_url( 'admin.php?page=formidable&frm_action=duplicate&id=' . absint( $template_id ) ) );
238 wp_die();
239 }
240
241 public static function duplicate() {
242 FrmAppHelper::permission_check( 'frm_edit_forms' );
243
244 $params = FrmForm::list_page_params();
245 $form = FrmForm::duplicate( $params['id'], $params['template'], true );
246 $message = $params['template'] ? __( 'Form template was Successfully Created', 'formidable' ) : __( 'Form was Successfully Copied', 'formidable' );
247 if ( $form ) {
248 return self::get_edit_vars( $form, array(), $message, true );
249 } else {
250 return self::display_forms_list( $params, __( 'There was a problem creating the new template.', 'formidable' ) );
251 }
252 }
253
254 public static function page_preview() {
255 $params = FrmForm::list_page_params();
256 if ( ! $params['form'] ) {
257 return;
258 }
259
260 $form = FrmForm::getOne( $params['form'] );
261 if ( $form ) {
262 return self::show_form( $form->id, '', true, true );
263 }
264 }
265
266 /**
267 * @since 3.0
268 */
269 public static function show_page_preview() {
270 echo self::page_preview(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
271 }
272
273 public static function preview() {
274 do_action( 'frm_wp' );
275
276 global $frm_vars;
277 $frm_vars['preview'] = true;
278
279 $include_theme = FrmAppHelper::get_param( 'theme', '', 'get', 'absint' );
280 if ( $include_theme ) {
281 self::set_preview_query();
282 self::load_theme_preview();
283 } else {
284 self::load_direct_preview();
285 }
286
287 wp_die();
288 }
289
290 private static function set_preview_query() {
291 $random_page = get_posts(
292 array(
293 'numberposts' => 1,
294 'orderby' => 'date',
295 'order' => 'ASC',
296 'post_type' => 'page',
297 )
298 );
299
300 if ( ! empty( $random_page ) ) {
301 $random_page = reset( $random_page );
302 query_posts(
303 array(
304 'post_type' => 'page',
305 'page_id' => $random_page->ID,
306 )
307 );
308 }
309 }
310
311 /**
312 * @since 3.0
313 */
314 private static function load_theme_preview() {
315 add_filter( 'wp_title', 'FrmFormsController::preview_title', 9999 );
316 add_filter( 'the_title', 'FrmFormsController::preview_page_title', 9999 );
317 add_filter( 'the_content', 'FrmFormsController::preview_content', 9999 );
318 add_action( 'loop_no_results', 'FrmFormsController::show_page_preview' );
319 add_filter( 'is_active_sidebar', '__return_false' );
320 FrmStylesController::enqueue_css( 'enqueue', true );
321
322 if ( false === get_template_part( 'page' ) ) {
323 self::fallback_when_page_template_part_is_not_supported_by_theme();
324 }
325 }
326
327 /**
328 * Not every theme supports get_template_part( 'page' ).
329 * When this is not supported, false is returned, and we can handle a fallback.
330 */
331 private static function fallback_when_page_template_part_is_not_supported_by_theme() {
332 if ( have_posts() ) {
333 the_post();
334 get_header( '' );
335 // add some generic class names to the container to add some natural padding to the content.
336 // .entry-content catches the WordPress TwentyTwenty theme.
337 // .container catches Customizr content.
338 echo '<div class="container entry-content">';
339 the_content();
340 echo '</div>';
341 get_footer();
342 }
343 }
344
345 /**
346 * Set the page title for the theme preview page
347 *
348 * @since 3.0
349 */
350 public static function preview_page_title( $title ) {
351 if ( in_the_loop() ) {
352 $title = self::preview_title( $title );
353 }
354
355 return $title;
356 }
357
358 /**
359 * Set the page title for the theme preview page
360 *
361 * @since 3.0
362 */
363 public static function preview_title( $title ) {
364 return __( 'Form Preview', 'formidable' );
365 }
366
367 /**
368 * Set the page content for the theme preview page
369 *
370 * @since 3.0
371 */
372 public static function preview_content( $content ) {
373 if ( in_the_loop() ) {
374 $content = self::show_page_preview();
375 }
376
377 return $content;
378 }
379
380 /**
381 * @since 3.0
382 */
383 private static function load_direct_preview() {
384 header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
385
386 $key = FrmAppHelper::simple_get( 'form', 'sanitize_title' );
387 if ( $key == '' ) {
388 $key = FrmAppHelper::get_post_param( 'form', '', 'sanitize_title' );
389 }
390
391 $form = FrmForm::getAll( array( 'form_key' => $key ), '', 1 );
392 if ( empty( $form ) ) {
393 $form = FrmForm::getAll( array(), '', 1 );
394 }
395
396 require( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/direct.php' );
397 }
398
399 public static function untrash() {
400 self::change_form_status( 'untrash' );
401 }
402
403 public static function bulk_untrash( $ids ) {
404 FrmAppHelper::permission_check( 'frm_edit_forms' );
405
406 $count = FrmForm::set_status( $ids, 'published' );
407
408 /* translators: %1$s: Number of forms */
409 $message = sprintf( _n( '%1$s form restored from the Trash.', '%1$s forms restored from the Trash.', $count, 'formidable' ), 1 );
410
411 return $message;
412 }
413
414 /**
415 * @since 3.06
416 */
417 public static function ajax_trash() {
418 FrmAppHelper::permission_check( 'frm_delete_forms' );
419 check_ajax_referer( 'frm_ajax', 'nonce' );
420 $form_id = FrmAppHelper::get_param( 'id', '', 'post', 'absint' );
421 FrmForm::set_status( $form_id, 'trash' );
422 wp_die();
423 }
424
425 public static function trash() {
426 self::change_form_status( 'trash' );
427 }
428
429 /**
430 * @param string $status
431 *
432 * @return void
433 */
434 public static function change_form_status( $status ) {
435 $available_status = array(
436 'untrash' => array(
437 'permission' => 'frm_edit_forms',
438 'new_status' => 'published',
439 ),
440 'trash' => array(
441 'permission' => 'frm_delete_forms',
442 'new_status' => 'trash',
443 ),
444 );
445
446 if ( ! isset( $available_status[ $status ] ) ) {
447 return;
448 }
449
450 FrmAppHelper::permission_check( $available_status[ $status ]['permission'] );
451
452 $params = FrmForm::list_page_params();
453
454 //check nonce url
455 check_admin_referer( $status . '_form_' . $params['id'] );
456
457 $count = 0;
458 if ( FrmForm::set_status( $params['id'], $available_status[ $status ]['new_status'] ) ) {
459 $count ++;
460 }
461
462 $form_type = FrmAppHelper::get_simple_request(
463 array(
464 'param' => 'form_type',
465 'type' => 'request',
466 )
467 );
468
469 /* translators: %1$s: Number of forms */
470 $available_status['untrash']['message'] = sprintf( _n( '%1$s form restored from the Trash.', '%1$s forms restored from the Trash.', $count, 'formidable' ), $count );
471
472 /* translators: %1$s: Number of forms, %2$s: Start link HTML, %3$s: End link HTML */
473 $available_status['trash']['message'] = sprintf( _n( '%1$s form moved to the Trash. %2$sUndo%3$s', '%1$s forms moved to the Trash. %2$sUndo%3$s', $count, 'formidable' ), $count, '<a href="' . esc_url( wp_nonce_url( '?page=formidable&frm_action=untrash&form_type=' . $form_type . '&id=' . $params['id'], 'untrash_form_' . $params['id'] ) ) . '">', '</a>' );
474
475 $message = $available_status[ $status ]['message'];
476
477 self::display_forms_list( $params, $message );
478 }
479
480 public static function bulk_trash( $ids ) {
481 FrmAppHelper::permission_check( 'frm_delete_forms' );
482
483 $count = 0;
484 foreach ( $ids as $id ) {
485 if ( FrmForm::trash( $id ) ) {
486 $count ++;
487 }
488 }
489
490 $current_page = FrmAppHelper::get_simple_request(
491 array(
492 'param' => 'form_type',
493 'type' => 'request',
494 )
495 );
496 $message = sprintf(
497 /* translators: %1$s: Number of forms, %2$s: Start link HTML, %3$s: End link HTML */
498 _n( '%1$s form moved to the Trash. %2$sUndo%3$s', '%1$s forms moved to the Trash. %2$sUndo%3$s', $count, 'formidable' ),
499 $count,
500 '<a href="' . esc_url( wp_nonce_url( '?page=formidable&frm_action=list&action=bulk_untrash&form_type=' . $current_page . '&item-action=' . implode( ',', $ids ), 'bulk-toplevel_page_formidable' ) ) . '">',
501 '</a>'
502 );
503
504 return $message;
505 }
506
507 public static function destroy() {
508 FrmAppHelper::permission_check( 'frm_delete_forms' );
509
510 $params = FrmForm::list_page_params();
511
512 // Check nonce url.
513 check_admin_referer( 'destroy_form_' . $params['id'] );
514
515 $count = 0;
516 if ( FrmForm::destroy( $params['id'] ) ) {
517 $count ++;
518 }
519
520 /* translators: %1$s: Number of forms */
521 $message = sprintf( _n( '%1$s Form Permanently Deleted', '%1$s Forms Permanently Deleted', $count, 'formidable' ), $count );
522
523 self::display_forms_list( $params, $message );
524 }
525
526 public static function bulk_destroy( $ids ) {
527 FrmAppHelper::permission_check( 'frm_delete_forms' );
528
529 $count = 0;
530 foreach ( $ids as $id ) {
531 $d = FrmForm::destroy( $id );
532 if ( $d ) {
533 $count ++;
534 }
535 }
536
537 /* translators: %1$s: Number of forms */
538 $message = sprintf( _n( '%1$s form permanently deleted.', '%1$s forms permanently deleted.', $count, 'formidable' ), $count );
539
540 return $message;
541 }
542
543 private static function delete_all() {
544 // Check nonce url.
545 $permission_error = FrmAppHelper::permission_nonce_error( 'frm_delete_forms', '_wpnonce', 'bulk-toplevel_page_formidable' );
546 if ( $permission_error !== false ) {
547 self::display_forms_list( array(), '', array( $permission_error ) );
548
549 return;
550 }
551
552 $count = FrmForm::scheduled_delete( time() );
553
554 /* translators: %1$s: Number of forms */
555 $message = sprintf( _n( '%1$s form permanently deleted.', '%1$s forms permanently deleted.', $count, 'formidable' ), $count );
556
557 self::display_forms_list( array(), $message );
558 }
559
560 /**
561 * Create a new form from the modal.
562 *
563 * @since 4.0
564 */
565 public static function build_new_form() {
566 global $wpdb;
567
568 FrmAppHelper::permission_check( 'frm_edit_forms' );
569 check_ajax_referer( 'frm_ajax', 'nonce' );
570
571 $new_values = self::get_modal_values();
572 $new_values['form_key'] = $new_values['name'];
573 $new_values['options'] = array(
574 'antispam' => 1,
575 );
576
577 $form_id = FrmForm::create( $new_values );
578
579 self::create_default_email_action( $form_id );
580
581 $response = array(
582 'redirect' => FrmForm::get_edit_link( $form_id ),
583 );
584
585 echo wp_json_encode( $response );
586 wp_die();
587 }
588
589 /**
590 * Create a custom template from a form
591 *
592 * @since 3.06
593 */
594 public static function build_template() {
595 global $wpdb;
596
597 FrmAppHelper::permission_check( 'frm_edit_forms' );
598 check_ajax_referer( 'frm_ajax', 'nonce' );
599
600 $form_id = FrmAppHelper::get_param( 'xml', '', 'post', 'absint' );
601 $new_form_id = FrmForm::duplicate( $form_id, 1, true );
602 if ( ! $new_form_id ) {
603 $response = array(
604 'message' => __( 'There was an error creating a template.', 'formidable' ),
605 );
606 } else {
607 $new_values = self::get_modal_values();
608 $query_results = $wpdb->update( $wpdb->prefix . 'frm_forms', $new_values, array( 'id' => $new_form_id ) );
609 if ( $query_results ) {
610 FrmForm::clear_form_cache();
611 }
612
613 $response = array(
614 'redirect' => admin_url( 'admin.php?page=formidable&frm_action=duplicate&id=' . $new_form_id ),
615 );
616 }
617
618 echo wp_json_encode( $response );
619 wp_die();
620 }
621
622 /**
623 * Before creating a new form, get the name and description from the modal.
624 *
625 * @since 4.0
626 */
627 private static function get_modal_values() {
628 $name = FrmAppHelper::get_param( 'name', '', 'post', 'sanitize_text_field' );
629 $desc = FrmAppHelper::get_param( 'desc', '', 'post', 'sanitize_textarea_field' );
630
631 return array(
632 'name' => $name,
633 'description' => $desc,
634 );
635 }
636
637 /**
638 * Inserts Formidable button
639 * Hook exists since 2.5.0
640 *
641 * @since 2.0.15
642 */
643 public static function insert_form_button() {
644 if ( current_user_can( 'frm_view_forms' ) ) {
645 FrmAppHelper::load_admin_wide_js();
646 $menu_name = FrmAppHelper::get_menu_name();
647 $icon = apply_filters( 'frm_media_icon', FrmAppHelper::svg_logo() );
648 echo '<a href="#TB_inline?width=50&height=50&inlineId=frm_insert_form" class="thickbox button add_media frm_insert_form" title="' . esc_attr__( 'Add forms and content', 'formidable' ) . '">' .
649 FrmAppHelper::kses( $icon, 'all' ) . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
650 ' ' . esc_html( $menu_name ) . '</a>';
651 }
652 }
653
654 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( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
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'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
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, WordPress.Security.NonceVerification.Missing
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'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
1487 $_REQUEST = array_merge( $_REQUEST, $vars ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
1488 $_POST = array_merge( $_POST, $_REQUEST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
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; // phpcs:ignore WordPress.Security.NonceVerification.Missing
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 ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
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 ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
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 echo FrmAppHelper::maybe_kses( $redirect_msg ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1959 echo "<script type='text/javascript'>window.onload = function(){setTimeout(window.location='" . esc_url_raw( $success_url ) . "', 8000);}</script>";
1960 }
1961 }
1962
1963 /**
1964 * @since 3.0
1965 *
1966 * @param string $success_url
1967 * @param string $success_msg
1968 * @param array $args
1969 */
1970 private static function get_redirect_message( $success_url, $success_msg, $args ) {
1971 $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/>' .
1972 /* translators: %1$s: Start link HTML, %2$s: End link HTML */
1973 sprintf( __( '%1$sClick here%2$s if you are not automatically redirected.', 'formidable' ), '<a href="' . esc_url( $success_url ) . '">', '</a>' ) .
1974 '</div></div>';
1975
1976 $redirect_args = array(
1977 'entry_id' => $args['entry_id'],
1978 'form_id' => $args['form']->id,
1979 'form' => $args['form'],
1980 );
1981
1982 return apply_filters( 'frm_redirect_msg', $redirect_msg, $redirect_args );
1983 }
1984
1985 /**
1986 * Prepare to show the success message and empty form after submit
1987 *
1988 * @since 2.05
1989 */
1990 public static function show_message_after_save( $atts ) {
1991 $atts['message'] = self::prepare_submit_message( $atts['form'], $atts['entry_id'] );
1992
1993 if ( ! isset( $atts['form']->options['show_form'] ) || $atts['form']->options['show_form'] ) {
1994 self::show_form_after_submit( $atts );
1995 } else {
1996 self::show_lone_success_messsage( $atts );
1997 }
1998 }
1999
2000 /**
2001 * Show an empty form
2002 *
2003 * @since 2.05
2004 */
2005 private static function show_form_after_submit( $args ) {
2006 self::fill_atts_for_form_display( $args );
2007
2008 $errors = $args['errors'];
2009 $message = $args['message'];
2010 $form = $args['form'];
2011 $title = $args['title'];
2012 $description = $args['description'];
2013
2014 if ( empty( $args['fields'] ) ) {
2015 $values = array(
2016 'custom_style' => FrmAppHelper::custom_style_value( array() ),
2017 );
2018 } else {
2019 $values = FrmEntriesHelper::setup_new_vars( $args['fields'], $form, $args['reset'] );
2020 }
2021 unset( $args );
2022
2023 $include_form_tag = apply_filters( 'frm_include_form_tag', true, $form );
2024
2025 $frm_settings = FrmAppHelper::get_settings();
2026 $submit = isset( $form->options['submit_value'] ) ? $form->options['submit_value'] : $frm_settings->submit_value;
2027
2028 global $frm_vars;
2029 self::maybe_load_css( $form, $values['custom_style'], $frm_vars['load_css'] );
2030
2031 $message_placement = self::message_placement( $form, $message );
2032
2033 include FrmAppHelper::plugin_path() . '/classes/views/frm-entries/new.php';
2034 }
2035
2036 /**
2037 * @return string - 'before', 'after', or 'submit'
2038 *
2039 * @since 4.05.02
2040 */
2041 private static function message_placement( $form, $message ) {
2042 $place = 'before';
2043
2044 if ( $message && isset( $form->options['form_class'] ) ) {
2045 if ( strpos( $form->options['form_class'], 'frm_below_success' ) !== false ) {
2046 $place = 'after';
2047 } elseif ( strpos( $form->options['form_class'], 'frm_inline_success' ) !== false ) {
2048 $place = 'submit';
2049 }
2050 }
2051
2052 /**
2053 * @return string - 'before' or 'after'
2054 *
2055 * @since 4.05.02
2056 */
2057 return apply_filters( 'frm_message_placement', $place, compact( 'form', 'message' ) );
2058 }
2059
2060 /**
2061 * Get all the values needed on the new.php entry page
2062 *
2063 * @since 2.05
2064 */
2065 private static function fill_atts_for_form_display( &$args ) {
2066 $defaults = array(
2067 'errors' => array(),
2068 'message' => '',
2069 'fields' => array(),
2070 'form' => array(),
2071 'title' => true,
2072 'description' => false,
2073 'reset' => false,
2074 );
2075 $args = wp_parse_args( $args, $defaults );
2076 }
2077
2078 /**
2079 * Show the success message without the form
2080 *
2081 * @since 2.05
2082 */
2083 private static function show_lone_success_messsage( $atts ) {
2084 global $frm_vars;
2085 $values = FrmEntriesHelper::setup_new_vars( $atts['fields'], $atts['form'], true );
2086 self::maybe_load_css( $atts['form'], $values['custom_style'], $frm_vars['load_css'] );
2087
2088 $include_extra_container = 'frm_forms' . FrmFormsHelper::get_form_style_class( $values );
2089
2090 $errors = array();
2091 $form = $atts['form'];
2092 $message = $atts['message'];
2093
2094 include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/errors.php' );
2095 }
2096
2097 /**
2098 * Prepare the success message before it's shown
2099 *
2100 * @since 2.05
2101 */
2102 private static function prepare_submit_message( $form, $entry_id ) {
2103 $frm_settings = FrmAppHelper::get_settings( array( 'current_form' => $form->id ) );
2104
2105 if ( $entry_id && is_numeric( $entry_id ) ) {
2106 $message = isset( $form->options['success_msg'] ) ? $form->options['success_msg'] : $frm_settings->success_msg;
2107 $class = 'frm_message';
2108 } else {
2109 $message = $frm_settings->failed_msg;
2110 $class = FrmFormsHelper::form_error_class();
2111 }
2112
2113 $message = FrmFormsHelper::get_success_message( compact( 'message', 'form', 'entry_id', 'class' ) );
2114
2115 return apply_filters( 'frm_main_feedback', $message, $form, $entry_id );
2116 }
2117
2118 public static function front_head() {
2119 $version = FrmAppHelper::plugin_version();
2120 $suffix = FrmAppHelper::js_suffix();
2121
2122 if ( ! empty( $suffix ) && self::has_combo_js_file() ) {
2123 wp_register_script( 'formidable', FrmAppHelper::plugin_url() . '/js/frm.min.js', array( 'jquery' ), $version, true );
2124 } else {
2125 wp_register_script( 'formidable', FrmAppHelper::plugin_url() . "/js/formidable{$suffix}.js", array( 'jquery' ), $version, true );
2126 }
2127
2128 add_filter( 'script_loader_tag', 'FrmFormsController::defer_script_loading', 10, 2 );
2129
2130 if ( FrmAppHelper::is_admin() ) {
2131 // don't load this in back-end
2132 return;
2133 }
2134
2135 FrmAppHelper::localize_script( 'front' );
2136 FrmStylesController::enqueue_css( 'register' );
2137 }
2138
2139 /**
2140 * @since 3.0
2141 */
2142 public static function has_combo_js_file() {
2143 return is_readable( FrmAppHelper::plugin_path() . '/js/frm.min.js' );
2144 }
2145
2146 public static function maybe_load_css( $form, $this_load, $global_load ) {
2147 $load_css = FrmForm::is_form_loaded( $form, $this_load, $global_load );
2148
2149 if ( ! $load_css ) {
2150 return;
2151 }
2152
2153 global $frm_vars;
2154 self::footer_js( 'header' );
2155 $frm_vars['css_loaded'] = true;
2156
2157 self::load_late_css();
2158 }
2159
2160 /**
2161 * If css is loaded only on applicable pages, include it before the form loads
2162 * to prevent a flash of unstyled form.
2163 *
2164 * @since 4.01
2165 */
2166 private static function load_late_css() {
2167 $frm_settings = FrmAppHelper::get_settings();
2168 $late_css = $frm_settings->load_style === 'dynamic';
2169 if ( ! $late_css ) {
2170 return;
2171 }
2172
2173 global $wp_styles;
2174 if ( is_array( $wp_styles->queue ) && in_array( 'formidable', $wp_styles->queue ) ) {
2175 wp_print_styles( 'formidable' );
2176 }
2177 }
2178
2179 public static function defer_script_loading( $tag, $handle ) {
2180 if ( 'recaptcha-api' == $handle && ! strpos( $tag, 'defer' ) ) {
2181 $tag = str_replace( ' src', ' defer="defer" async="async" src', $tag );
2182 }
2183
2184 return $tag;
2185 }
2186
2187 public static function footer_js( $location = 'footer' ) {
2188 global $frm_vars;
2189
2190 FrmStylesController::enqueue_css();
2191
2192 if ( ! FrmAppHelper::is_admin() && $location != 'header' && ! empty( $frm_vars['forms_loaded'] ) ) {
2193 // load formidable js
2194 wp_enqueue_script( 'formidable' );
2195 }
2196 }
2197
2198 /**
2199 * @since 2.0.8
2200 */
2201 private static function maybe_minimize_form( $atts, &$content ) {
2202 // check if minimizing is turned on
2203 if ( self::is_minification_on( $atts ) ) {
2204 $content = str_replace( array( "\r\n", "\r", "\n", "\t", ' ' ), '', $content );
2205 }
2206 }
2207
2208 /**
2209 * @since 2.0.8
2210 * @return boolean
2211 */
2212 private static function is_minification_on( $atts ) {
2213 return isset( $atts['minimize'] ) && ! empty( $atts['minimize'] );
2214 }
2215
2216 /**
2217 * @deprecated 4.0
2218 */
2219 public static function new_form( $values = array() ) {
2220 FrmDeprecated::new_form( $values );
2221 }
2222
2223 /**
2224 * @deprecated 4.0
2225 */
2226 public static function create( $values = array() ) {
2227 _deprecated_function( __METHOD__, '4.0', 'FrmFormsController::update' );
2228 self::update( $values );
2229 }
2230
2231 /**
2232 * @deprecated 1.07.05
2233 * @codeCoverageIgnore
2234 */
2235 public static function add_default_templates( $path, $default = true, $template = true ) {
2236 FrmDeprecated::add_default_templates( $path, $default, $template );
2237 }
2238
2239 /**
2240 * @deprecated 3.0
2241 * @codeCoverageIgnore
2242 */
2243 public static function bulk_create_template( $ids ) {
2244 return FrmDeprecated::bulk_create_template( $ids );
2245 }
2246
2247 /**
2248 * @deprecated 2.03
2249 * @codeCoverageIgnore
2250 */
2251 public static function register_pro_scripts() {
2252 FrmDeprecated::register_pro_scripts();
2253 }
2254
2255 /**
2256 * @deprecated 3.0
2257 * @codeCoverageIgnore
2258 */
2259 public static function edit_key() {
2260 FrmDeprecated::edit_key();
2261 }
2262
2263 /**
2264 * @deprecated 3.0
2265 * @codeCoverageIgnore
2266 */
2267 public static function edit_description() {
2268 FrmDeprecated::edit_description();
2269 }
2270
2271 /**
2272 * @deprecated 4.08
2273 * @since 3.06
2274 */
2275 public static function add_new() {
2276 _deprecated_function( __FUNCTION__, '4.08' );
2277 }
2278 }
2279