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

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