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
← All changes | classes/controllers/FrmEntriesController.php +131 -105 6.34.01.02 View file →
@@ -1,8 +1,5 @@
1 1 <?php
2 -if ( ! defined( 'ABSPATH' ) ) {
3 - die( 'You are not allowed to call this page directly.' );
4 -}
5 2
6 3 class FrmEntriesController {
7 4
8 5 public static function menu() {
@@ -9,16 +6,9 @@
9 6 FrmAppHelper::force_capability( 'frm_view_entries' );
10 7
11 8 add_submenu_page( 'formidable', 'Formidable | ' . __( 'Entries', 'formidable' ), __( 'Entries', 'formidable' ), 'frm_view_entries', 'formidable-entries', 'FrmEntriesController::route' );
12 9
13 - $views_installed = is_callable( 'FrmProAppHelper::views_is_installed' ) ? FrmProAppHelper::views_is_installed() : FrmAppHelper::pro_is_installed();
14 - if ( ! $views_installed ) {
15 - add_submenu_page( 'formidable', 'Formidable | ' . __( 'Views', 'formidable' ), __( 'Views', 'formidable' ), 'frm_view_entries', 'formidable-views', 'FrmFormsController::no_views' );
16 - }
17 -
18 - if ( FrmAppHelper::is_admin_page( 'formidable-entries' ) ) {
19 - self::load_manage_entries_hooks();
20 - }
10 + self::load_manage_entries_hooks();
21 11 }
22 12
23 13 /**
24 14 * @since 2.05.07
@@ -23,9 +13,9 @@
23 13 /**
24 14 * @since 2.05.07
25 15 */
26 16 private static function load_manage_entries_hooks() {
27 - if ( ! in_array( FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' ), array( 'edit', 'show', 'new', 'duplicate' ), true ) ) {
17 + if ( ! in_array( FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' ), array( 'edit', 'show', 'new' ) ) ) {
28 18 $menu_name = FrmAppHelper::get_menu_name();
29 19 $base = self::base_column_key( $menu_name );
30 20
31 21 add_filter( 'manage_' . $base . '_columns', 'FrmEntriesController::manage_columns' );
@@ -43,8 +33,9 @@
43 33
44 34 switch ( $action ) {
45 35 case 'show':
46 36 case 'destroy':
37 + case 'destroy_all':
47 38 return self::$action();
48 39
49 40 default:
50 41 do_action( 'frm_entry_action_route', $action );
@@ -109,18 +100,8 @@
109 100
110 101 private static function get_columns_for_form( $form_id, &$columns ) {
111 102 $form_cols = FrmField::get_all_for_form( $form_id, '', 'include' );
112 103
113 - /**
114 - * Allows changing fields in the Entries list table heading.
115 - *
116 - * @since 5.0.04
117 - *
118 - * @param array $fields Array of fields.
119 - * @param array $args The arguments. Contains `form_id`.
120 - */
121 - $form_cols = apply_filters( 'frm_fields_in_entries_list_table', $form_cols, compact( 'form_id' ) );
122 -
123 104 foreach ( $form_cols as $form_col ) {
124 105 if ( FrmField::is_no_save_field( $form_col->type ) ) {
125 106 continue;
126 107 }
@@ -285,9 +266,10 @@
285 266 $form_id . '_is_draft' => 'is_draft',
286 267 );
287 268
288 269 foreach ( $fields as $field ) {
289 - if ( self::field_supports_sorting( $field ) ) {
270 + if ( $field->type != 'checkbox' && ( ! isset( $field->field_options['post_field'] ) || $field->field_options['post_field'] == '' ) ) {
271 + // Can't sort on checkboxes because they are stored serialized, or post fields
290 272 $columns[ $form_id . '_' . $field->field_key ] = 'meta_' . $field->id;
291 273 }
292 274 }
293 275
@@ -293,32 +275,9 @@
293 275
294 276 return $columns;
295 277 }
296 278
297 - /**
298 - * Can't sort on checkboxes because they are sorted serialized.
299 - * Some post content can be sorted but not everything.
300 - *
301 - * @param stdClass $field
302 - * @return bool
303 - */
304 - private static function field_supports_sorting( $field ) {
305 - $is_sortable = 'checkbox' !== $field->type && empty( $field->field_options['post_field'] );
306 - return apply_filters( 'frm_field_column_is_sortable', $is_sortable, $field );
307 - }
308 -
309 - /**
310 - * @param mixed $result Option value from database for hidden columns in entries table.
311 - * @return array
312 - */
313 279 public static function hidden_columns( $result ) {
314 - if ( ! is_array( $result ) ) {
315 - // Force an unexpected value to be an array.
316 - // Since $result is a filtered option and gets saved to the database, it's possible it could be a string.
317 - // Since this code expects an array it would break with a "Uncaught Error: [] operator not supported for strings" error.
318 - $result = array();
319 - }
320 -
321 280 $form_id = FrmForm::get_current_form_id();
322 281
323 282 $hidden = self::user_hidden_columns_for_form( $form_id, $result );
324 283
@@ -416,9 +375,9 @@
416 375 $total_pages = $wp_list_table->get_pagination_arg( 'total_pages' );
417 376 if ( $pagenum > $total_pages && $total_pages > 0 ) {
418 377 $url = add_query_arg( 'paged', $total_pages );
419 378 if ( headers_sent() ) {
420 - FrmAppHelper::js_redirect( $url, true );
379 + echo FrmAppHelper::js_redirect( $url ); // WPCS: XSS ok.
421 380 } else {
422 381 wp_redirect( esc_url_raw( $url ) );
423 382 }
424 383 die();
@@ -427,9 +386,9 @@
427 386 if ( empty( $message ) && isset( $_GET['import-message'] ) ) {
428 387 $message = __( 'Your import is complete', 'formidable' );
429 388 }
430 389
431 - require FrmAppHelper::plugin_path() . '/classes/views/frm-entries/list.php';
390 + require( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/list.php' );
432 391 }
433 392
434 393 private static function get_delete_form_time( $form, &$errors ) {
435 394 if ( 'trash' == $form->status ) {
@@ -461,9 +420,9 @@
461 420
462 421 return;
463 422 }
464 423
465 - $data = $entry->description;
424 + $data = maybe_unserialize( $entry->description );
466 425 if ( ! is_array( $data ) || ! isset( $data['referrer'] ) ) {
467 426 $data = array( 'referrer' => $data );
468 427 }
469 428
@@ -472,19 +431,10 @@
472 431
473 432 include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/show.php' );
474 433 }
475 434
476 - /**
477 - * Destroy an entry from the admin page.
478 - * This is triggered from the entries list from the "Delete" row action, and also from the "Delete Entry" trigger in the view/edit entry sidebar.
479 - *
480 - * @return void
481 - */
482 435 public static function destroy() {
483 - $permission_error = FrmAppHelper::permission_nonce_error( 'frm_delete_entries', '_wpnonce', -1 );
484 - if ( false !== $permission_error ) {
485 - wp_die( esc_html( $permission_error ) );
486 - }
436 + FrmAppHelper::permission_check( 'frm_delete_entries' );
487 437
488 438 $params = FrmForm::get_admin_params();
489 439
490 440 if ( isset( $params['keep_post'] ) && $params['keep_post'] ) {
@@ -492,27 +442,96 @@
492 442 }
493 443
494 444 $message = '';
495 445 if ( FrmEntry::destroy( $params['id'] ) ) {
496 - $message = __( 'Entry was successfully deleted', 'formidable' );
446 + $message = __( 'Entry was Successfully Deleted', 'formidable' );
497 447 }
498 448
499 449 self::display_list( $message );
500 450 }
501 451
452 + public static function destroy_all() {
453 + if ( ! current_user_can( 'frm_delete_entries' ) ) {
454 + $frm_settings = FrmAppHelper::get_settings();
455 + wp_die( esc_html( $frm_settings->admin_permission ) );
456 + }
457 +
458 + $params = FrmForm::get_admin_params();
459 + $message = '';
460 + $errors = array();
461 + $form_id = (int) $params['form'];
462 +
463 + if ( $form_id ) {
464 + $entry_ids = FrmDb::get_col( 'frm_items', array( 'form_id' => $form_id ) );
465 + $action = FrmFormAction::get_action_for_form( $form_id, 'wppost', 1 );
466 +
467 + if ( $action ) {
468 + // This action takes a while, so only trigger it if there are posts to delete.
469 + foreach ( $entry_ids as $entry_id ) {
470 + do_action( 'frm_before_destroy_entry', $entry_id );
471 + unset( $entry_id );
472 + }
473 + }
474 +
475 + $results = self::delete_form_entries( $form_id );
476 + if ( $results ) {
477 + FrmEntry::clear_cache();
478 + $message = __( 'Entries Successfully Deleted', 'formidable' );
479 + }
480 + } else {
481 + $errors = __( 'No Entries Selected', 'formidable' );
482 + }
483 +
484 + self::display_list( $message, $errors );
485 + }
486 +
502 487 /**
503 - * @deprecated 4.02.04 - Moved to Pro since it was unused in Lite.
488 + * @since 3.01
489 + *
490 + * @param int $form_id
504 491 */
505 - public static function destroy_all() {
506 - _deprecated_function( __METHOD__, '4.02.04', 'FrmProEntriesController::destroy_all' );
507 - if ( is_callable( 'FrmProEntriesController::destroy_all' ) ) {
508 - FrmProEntriesController::destroy_all();
492 + private static function delete_form_entries( $form_id ) {
493 + global $wpdb;
494 +
495 + $form_ids = self::get_child_form_ids( $form_id );
496 +
497 + $meta_query = $wpdb->prepare( "DELETE em.* FROM {$wpdb->prefix}frm_item_metas as em INNER JOIN {$wpdb->prefix}frm_items as e on (em.item_id=e.id) WHERE form_id=%d", $form_id );
498 + $entry_query = $wpdb->prepare( "DELETE FROM {$wpdb->prefix}frm_items WHERE form_id=%d", $form_id );
499 +
500 + if ( ! empty( $form_ids ) ) {
501 + $form_query = ' OR form_id in (' . $form_ids . ')';
502 + $meta_query .= $form_query;
503 + $entry_query .= $form_query;
509 504 }
505 +
506 + $wpdb->query( $meta_query ); // WPCS: unprepared SQL ok.
507 +
508 + return $wpdb->query( $entry_query ); // WPCS: unprepared SQL ok.
510 509 }
511 510
511 + /**
512 + * @since 3.01
513 + *
514 + * @param int $form_id
515 + * @param bool|string $implode
516 + */
517 + private static function get_child_form_ids( $form_id, $implode = ',' ) {
518 + $form_ids = array();
519 + $child_form_ids = FrmDb::get_col( 'frm_forms', array( 'parent_form_id' => $form_id ) );
520 + if ( $child_form_ids ) {
521 + $form_ids = $child_form_ids;
522 + }
523 + $form_ids = array_filter( $form_ids, 'is_numeric' );
524 + if ( $implode ) {
525 + $form_ids = implode( $implode, $form_ids );
526 + }
527 +
528 + return $form_ids;
529 + }
530 +
512 531 public static function process_entry( $errors = '', $ajax = false ) {
513 532 $form_id = FrmAppHelper::get_post_param( 'form_id', '', 'absint' );
514 - if ( FrmAppHelper::is_admin() || empty( $_POST ) || empty( $form_id ) || ! isset( $_POST['item_key'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
533 + if ( FrmAppHelper::is_admin() || empty( $_POST ) || empty( $form_id ) || ! isset( $_POST['item_key'] ) ) {
515 534 return;
516 535 }
517 536
518 537 global $frm_vars;
@@ -533,9 +552,9 @@
533 552 return;
534 553 }
535 554
536 555 if ( $errors == '' && ! $ajax ) {
537 - $errors = FrmEntryValidate::validate( wp_unslash( $_POST ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
556 + $errors = FrmEntryValidate::validate( wp_unslash( $_POST ) );
538 557 }
539 558
540 559 /**
541 560 * Use this filter to add trigger actions and add errors after
@@ -549,11 +568,11 @@
549 568
550 569 if ( empty( $errors ) ) {
551 570 $_POST['frm_skip_cookie'] = 1;
552 571 $do_success = false;
553 - if ( $params['action'] === 'create' ) {
572 + if ( $params['action'] == 'create' ) {
554 573 if ( apply_filters( 'frm_continue_to_create', true, $form_id ) && ! isset( $frm_vars['created_entries'][ $form_id ]['entry_id'] ) ) {
555 - $frm_vars['created_entries'][ $form_id ]['entry_id'] = FrmEntry::create( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
574 + $frm_vars['created_entries'][ $form_id ]['entry_id'] = FrmEntry::create( $_POST );
556 575
557 576 $params['id'] = $frm_vars['created_entries'][ $form_id ]['entry_id'];
558 577 $do_success = true;
559 578 }
@@ -562,9 +581,9 @@
562 581 do_action( 'frm_process_entry', $params, $errors, $form, array( 'ajax' => $ajax ) );
563 582 if ( $do_success ) {
564 583 FrmFormsController::maybe_trigger_redirect( $form, $params, array( 'ajax' => $ajax ) );
565 584 }
566 - unset( $_POST['frm_skip_cookie'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
585 + unset( $_POST['frm_skip_cookie'] );
567 586 }
568 587 }
569 588
570 589 /**
@@ -599,9 +618,9 @@
599 618 if ( ! $form ) {
600 619 return;
601 620 }
602 621
603 - FrmAppHelper::unserialize_or_decode( $form->options );
622 + $form->options = maybe_unserialize( $form->options );
604 623 if ( isset( $form->options['no_save'] ) && $form->options['no_save'] ) {
605 624 self::unlink_post( $entry_id );
606 625 FrmEntry::destroy( $entry_id );
607 626 }
@@ -622,34 +641,32 @@
622 641 * @return array|string
623 642 */
624 643 public static function show_entry_shortcode( $atts ) {
625 644 $defaults = array(
626 - 'id' => false,
627 - 'entry' => false,
628 - 'fields' => false,
629 - 'plain_text' => false,
630 - 'user_info' => false,
631 - 'include_blank' => false,
632 - 'default_email' => false,
633 - 'form_id' => false,
634 - 'format' => 'text',
635 - 'array_key' => 'key',
636 - 'direction' => 'ltr',
637 - 'font_size' => '',
638 - 'text_color' => '',
639 - 'border_width' => '',
640 - 'border_color' => '',
641 - 'bg_color' => '',
642 - 'alt_bg_color' => '',
643 - 'class' => '',
644 - 'clickable' => false,
645 - 'exclude_fields' => '',
646 - 'include_fields' => '',
647 - 'include_extras' => '',
648 - 'inline_style' => 1,
649 - 'child_array' => false, // return embedded fields as nested array
650 - 'line_breaks' => true,
651 - 'array_separator' => ', ',
645 + 'id' => false,
646 + 'entry' => false,
647 + 'fields' => false,
648 + 'plain_text' => false,
649 + 'user_info' => false,
650 + 'include_blank' => false,
651 + 'default_email' => false,
652 + 'form_id' => false,
653 + 'format' => 'text',
654 + 'array_key' => 'key',
655 + 'direction' => 'ltr',
656 + 'font_size' => '',
657 + 'text_color' => '',
658 + 'border_width' => '',
659 + 'border_color' => '',
660 + 'bg_color' => '',
661 + 'alt_bg_color' => '',
662 + 'class' => '',
663 + 'clickable' => false,
664 + 'exclude_fields' => '',
665 + 'include_fields' => '',
666 + 'include_extras' => '',
667 + 'inline_style' => 1,
668 + 'child_array' => false, // return embedded fields as nested array
652 669 );
653 670 $defaults = apply_filters( 'frm_show_entry_defaults', $defaults );
654 671
655 672 $atts = shortcode_atts( $defaults, $atts );
@@ -681,19 +698,12 @@
681 698 $time_format = get_option( 'time_format' );
682 699
683 700 if ( $entry ) {
684 701 $id = $entry->id;
685 - $data = $entry->description;
702 + $data = maybe_unserialize( $entry->description );
686 703 if ( isset( $data['browser'] ) ) {
687 704 $browser = FrmEntriesHelper::get_browser( $data['browser'] );
688 705 }
689 - /**
690 - * Add or remove information in the entry sidebar.
691 - *
692 - * @since 5.5.2
693 - * @param array $data
694 - */
695 - $data = apply_filters( 'frm_sidebar_data', $data, compact( 'entry' ) );
696 706 }
697 707
698 708 include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/sidebar-shared.php' );
699 709 }
@@ -703,6 +713,22 @@
703 713 */
704 714 public static function contextual_help( $help, $screen_id, $screen ) {
705 715 _deprecated_function( __METHOD__, '4.0' );
706 716 return $help;
717 + }
718 +
719 + /**
720 + * @deprecated 1.07.05
721 + * @codeCoverageIgnore
722 + */
723 + public static function show_form( $id = '', $key = '', $title = false, $description = false ) {
724 + return FrmDeprecated::show_form( $id, $key, $title, $description );
725 + }
726 +
727 + /**
728 + * @deprecated 1.07.05
729 + * @codeCoverageIgnore
730 + */
731 + public static function get_form( $filename, $form, $title, $description ) {
732 + return FrmDeprecated::get_form( $filename, $form, $title, $description );
707 733 }
708 734 }