PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 4.01.02
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v4.01.02
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / classes / controllers / FrmFormsController.php

FrmFormsController.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 4.01.02, at classes/controllers/FrmFormsController.php

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