Файловый менеджер - Редактировать - /home/avadvi5/public_html/fcolliver.com/wp-content/plugins/wpforms/src/Pro/Admin/Entries/Page.php
Ðазад
<?php namespace WPForms\Pro\Admin\Entries; use WPForms\Admin\Notice; use WPForms\Pro\Admin\Entries\Table\DataObjects\Column; use WPForms\Pro\Admin\Entries\Table\Facades\Columns; use WPForms\Pro\Admin\DashboardWidget; use WPForms\Pro\AntiSpam\SpamEntry; use WPForms\Pro\Forms\Fields\FileUpload\Field as FileUploadField; use WPForms_Form_Handler; /** * Display list of all entries for a single form. * * @since 1.8.6 */ class Page { use FilterSearch; /** * Entry trash status. * * @since 1.8.5 */ const TRASH_ENTRY_STATUS = 'trash'; /** * Store admin alerts. * * @since 1.8.6 * * @var array */ public $alerts = []; /** * Abort. Bail on proceeding to process the page. * * @since 1.8.6 * * @var bool */ public $abort = false; /** * The human-readable error message. * * @since 1.8.6 * * @var string */ private $abort_message; /** * Form ID. * * @since 1.8.6 * * @var int */ public $form_id; /** * Form object. * * @since 1.8.6 * * @var WPForms_Form_Handler */ public $form; /** * Forms object. * * @since 1.8.6 * * @var WPForms_Form_Handler[] */ public $forms; /** * Entries object. * * @since 1.8.6 * * @var ListTable */ public $entries; /** * Primary class constructor. * * @since 1.8.6 */ public function __construct() { $this->hooks(); } /** * Register hooks. * * @since 1.8.6 */ private function hooks() { // Heartbeat doesn't pass $_GET parameters checked by $this->init() condition. add_filter( 'heartbeat_received', [ $this, 'heartbeat_new_entries_check' ], 10, 3 ); // AJAX-callbacks. add_action( 'wp_ajax_wpforms_entry_list_process_delete_all', [ $this, 'process_delete' ] ); add_action( 'wp_ajax_wpforms_entry_list_process_trash_all', [ $this, 'process_trash' ] ); } /** * Determine if the user is viewing the entries list page, if so, party on. * * @since 1.8.6 */ public function init() { // phpcs:disable WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks // Only load if we are actually on the overview page. if ( ! wpforms_is_admin_page( 'entries', 'list' ) ) { return; } $form_id = $this->get_filtered_form_id(); if ( empty( $form_id ) ) { wp_safe_redirect( admin_url( 'admin.php?page=wpforms-entries' ) ); exit; } if ( ! wpforms_current_user_can( 'view_entries_form_single', $form_id ) ) { wp_die( esc_html__( 'You do not have permission to view this form\'s entries.', 'wpforms' ), 403 ); } $form = wpforms()->obj( 'form' )->get( $form_id ); if ( empty( $form ) || $form->post_status === self::TRASH_ENTRY_STATUS ) { $this->abort_message = esc_html__( 'It looks like the form you are trying to access is no longer available.', 'wpforms' ); $this->abort = true; } $this->remove_get_parameters(); set_screen_options(); // Load the classes that build the entries' table. add_action( 'current_screen', [ $this, 'load_entries_list_table' ], 5 ); // Processing and setup. add_action( 'wpforms_entries_init', [ $this, 'process_filter_dates' ], 7, 1 ); add_action( 'wpforms_entries_init', [ $this, 'process_filter_search' ], 7, 1 ); add_action( 'wpforms_entries_init', [ $this, 'process_read' ], 8, 1 ); add_action( 'wpforms_entries_init', [ $this, 'setup' ], 10, 1 ); add_action( 'wpforms_entries_init', [ $this, 'register_alerts' ], 20, 1 ); /** * Fires on init entries list page. * * @since 1.0.0 * * @param string $context Current context. */ do_action( 'wpforms_entries_init', 'list' ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName // Output. add_action( 'wpforms_admin_page', [ $this, 'list_all' ] ); add_action( 'wpforms_admin_page', [ $this, 'display_abort_message' ] ); add_action( 'wpforms_admin_page', [ $this, 'field_column_setting' ] ); add_action( 'wpforms_entry_list_title', [ $this, 'list_form_actions' ], 10, 1 ); // Enqueues. add_action( 'admin_enqueue_scripts', [ $this, 'enqueues' ] ); add_filter( 'wpforms_admin_strings', [ $this, 'js_strings' ] ); // Apply filter to search by date on Entries page. add_filter( 'wpforms_entry_handler_get_entries_args', [ $this, 'get_filtered_entry_table_args' ] ); } // phpcs:enable WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks /** * Remove unnecessary $_GET parameters for shorter URL. * * @since 1.8.6 */ private function remove_get_parameters() { $remove_args = [ '_wp_http_referer', 'action', 'action2', '_wpnonce', 'read', 'unread', 'spam', 'unspam', 'unstarred', 'starred', 'deleted', 'trashed', 'restored', ]; // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['paged'] ) && (int) $_GET['paged'] < 2 ) { $remove_args[] = 'paged'; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash if ( ! isset( $_GET['search']['term'] ) || wpforms_is_empty_string( $_GET['search']['term'] ) ) { $remove_args[] = 'search'; } if ( empty( $this->get_filtered_dates() ) ) { $remove_args[] = 'date'; } // phpcs:ignore WordPress.Security.ValidatedSanitizedInput $_SERVER['REQUEST_URI'] = remove_query_arg( $remove_args, $_SERVER['REQUEST_URI'] ); } /** * Load the PHP classes and initialize an entries table. * * @since 1.8.6 */ public function load_entries_list_table() { // Create an `ListTable` instance and process bulk actions. $this->entries = new ListTable(); $this->entries->process_bulk_actions(); } /** * Enqueue assets for the entries pages. * * @since 1.8.6 */ public function enqueues() { // JavaScript. wp_enqueue_script( 'wpforms-htmx', WPFORMS_PLUGIN_URL . 'assets/lib/htmx.min.js', [], WPFORMS_VERSION, true ); wp_enqueue_script( 'wpforms-flatpickr', WPFORMS_PLUGIN_URL . 'assets/lib/flatpickr/flatpickr.min.js', [ 'jquery' ], '4.6.9', false ); // CSS. wp_enqueue_style( 'wpforms-flatpickr', WPFORMS_PLUGIN_URL . 'assets/lib/flatpickr/flatpickr.min.css', [], '4.6.9' ); $min = wpforms_get_min_suffix(); wp_enqueue_style( 'wpforms-admin-list-table-ext', WPFORMS_PLUGIN_URL . "assets/css/admin-list-table-ext{$min}.css", [ 'wpforms-multiselect-checkboxes' ], WPFORMS_VERSION ); wp_enqueue_script( 'wpforms-admin-list-table-ext', WPFORMS_PLUGIN_URL . "assets/js/admin/share/list-table-ext{$min}.js", [ 'jquery', 'jquery-ui-sortable', 'underscore', 'wpforms-multiselect-checkboxes', 'wpforms-htmx' ], WPFORMS_VERSION, true ); wp_enqueue_script( 'wpforms-admin-entries', WPFORMS_PLUGIN_URL . "assets/pro/js/admin/entries/entries{$min}.js", [ 'jquery', 'wpforms-flatpickr' ], WPFORMS_VERSION, true ); /** * Fires on enqueue entries list page assets. * * @since 1.0.0 * * @param string $context Current context. */ do_action( 'wpforms_entries_enqueue', 'list' ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName } /** * Watch for and run complete marking all entries as read. * * @since 1.8.6 */ public function process_read() { $form_id = $this->get_filtered_form_id(); // Check for run switch. if ( empty( $_GET['action'] ) || ! $form_id || $_GET['action'] !== 'markread' || empty( $_GET['_wpnonce'] ) ) { return; } // Security check. if ( ! wp_verify_nonce( sanitize_key( $_GET['_wpnonce'] ), 'wpforms_entry_list_markread' ) ) { return; } wpforms()->obj( 'entry' )->mark_all_read( $form_id ); $this->alerts[] = [ 'type' => 'success', 'message' => esc_html__( 'All entries marked as read.', 'wpforms' ), 'dismiss' => true, ]; } /** * Entry deletion and trigger if needed. * * @since 1.8.6 */ public function process_delete() { // Security check. if ( ! check_ajax_referer( 'wpforms-admin', 'nonce', false ) ) { wp_send_json_error( esc_html__( 'Your session expired. Please reload the builder.', 'wpforms' ) ); } $form_id = $this->get_filtered_form_id(); // Require data check. if ( ! $form_id ) { wp_send_json_error( esc_html__( 'Something went wrong while performing this action.', 'wpforms' ) ); } // Permission check. if ( ! wpforms_current_user_can( 'delete_entries_form_single', $form_id ) ) { wp_send_json_error( esc_html__( 'You do not have permission to perform this action.', 'wpforms' ) ); } // Get the screen first. $screen = isset( $_REQUEST['page'] ) ? sanitize_key( $_REQUEST['page'] ) : ''; // The delete all functionality should only be available on the trash and spam screens. // All other places the delete all button will be replaced by trash all button. if ( ! in_array( $screen, [ self::TRASH_ENTRY_STATUS, SpamEntry::ENTRY_STATUS ], true ) ) { wp_send_json_error( esc_html__( 'Something went wrong while performing this action.', 'wpforms' ) ); } // Default args to find entries. $args = [ 'form_id' => $form_id, 'select' => 'entry_ids', 'status' => $screen, 'number' => '-1', ]; // Get entries. $entries = wpforms()->obj( 'entry' )->get_entries( $args ); if ( ! $entries ) { wp_send_json_error( esc_html__( 'Something went wrong while performing this action.', 'wpforms' ) ); } $entry_ids = wp_list_pluck( $entries, 'entry_id' ); $deleted = 0; // Delete media if any. // It must be done before removing the entry itself. array_map( [ FileUploadField::class, 'delete_uploaded_files_from_entry' ], $entry_ids ); /** * Allow performing additional actions before deleting entries. * * @since 1.8.9 * * @param array $entry_ids Entry IDs. * @param int $form_id Form ID. */ do_action( 'wpforms_pro_admin_entries_page_empty_trash_before', $entry_ids, $form_id ); // Delete meta only if the related entry has been removed successfully. if ( wpforms()->obj( 'entry' )->delete_where_in( 'entry_id', $entry_ids ) ) { wpforms()->obj( 'entry_meta' )->delete_where_in( 'entry_id', $entry_ids ); wpforms()->obj( 'entry_fields' )->delete_where_in( 'entry_id', $entry_ids ); $deleted = count( $entry_ids ); } $redirect_url = ! empty( $_GET['url'] ) ? add_query_arg( 'deleted', $deleted, esc_url_raw( wp_unslash( $_GET['url'] ) ) ) : ''; DashboardWidget::clear_widget_cache(); wp_send_json_success( $redirect_url ); } /** * Entry trash and trigger if needed. * * @since 1.8.5 */ public function process_trash() { // Security check. if ( ! check_ajax_referer( 'wpforms-admin', 'nonce', false ) ) { wp_send_json_error( esc_html__( 'Your session expired. Please reload the builder.', 'wpforms' ) ); } $form_id = $this->get_filtered_form_id(); // Require data check. if ( ! $form_id ) { wp_send_json_error( esc_html__( 'Something went wrong while performing this action.', 'wpforms' ) ); } // Permission check. if ( ! wpforms_current_user_can( 'delete_entries_form_single', $form_id ) ) { wp_send_json_error( esc_html__( 'You do not have permission to perform this action.', 'wpforms' ) ); } if ( $this->is_list_filtered() ) { $this->process_filter_dates(); $this->process_filter_search(); } $entries_id = $this->process_trash_data( $form_id ); if ( empty( $entries_id ) ) { wp_send_json_error( esc_html__( 'Something went wrong while performing this action.', 'wpforms' ) ); } $trashed = $this->process_trash_with_ids( $entries_id, $form_id ); $redirect_url = ! empty( $_GET['url'] ) ? add_query_arg( 'trashed', $trashed, esc_url_raw( wp_unslash( $_GET['url'] ) ) ) : ''; DashboardWidget::clear_widget_cache(); wp_send_json_success( $redirect_url ); } /** * Process entries for trashing. * * @since 1.8.5 * * @param int $form_id Form ID. * * @return array $entries_id Entry IDs. */ private function process_trash_data( $form_id ) { // Check if entries filtered. // This also checks if there's entry ids provided. See: FilterSearch Trait. if ( ! empty( $this->filter['entry_id'] ) ) { return $this->filter['entry_id']; } // Get the screen first. // phpcs:ignore WordPress.Security.NonceVerification.Recommended $screen = isset( $_REQUEST['page'] ) ? sanitize_key( $_REQUEST['page'] ) : ''; // We can only trash all on all other screens expect trash screen. if ( $screen === self::TRASH_ENTRY_STATUS ) { return []; } // Default args to find entries. $args = [ 'form_id' => $form_id, 'select' => 'entry_ids', 'number' => '-1', ]; // Apply the date filter if set. if ( ! empty( $this->filter['date'] ) ) { $args['date'] = $this->filter['date']; } // Get entries. $all_entries = wpforms()->obj( 'entry' )->get_entries( $args ); $spam_entries = wpforms()->obj( 'entry' )->get_entries( [ 'form_id' => $form_id, 'status' => SpamEntry::ENTRY_STATUS, 'select' => 'entry_ids', ] ); return wp_list_pluck( array_merge( $all_entries, $spam_entries ), 'entry_id' ); } /** * Process trash when entry ids are given. * * @since 1.8.5 * * @param array $entry_ids Entry IDs. * @param int $form_id Form ID. * * @return int $trashed Number of trashed entries. */ private function process_trash_with_ids( $entry_ids, $form_id ) { $trashed = 0; $user_id = get_current_user_id(); foreach ( $entry_ids as $id ) { // Get the entry first. $entry = wpforms()->obj( 'entry' )->get( $id ); if ( ! $entry ) { continue; } $status = $entry->status; /** * TODO :: After the support for PHP 7 ends, * we can update the following code to use named arguments and skip the optional params. */ $success = wpforms()->obj( 'entry' )->update( $id, [ 'status' => self::TRASH_ENTRY_STATUS ], '', '', [ 'cap' => 'delete_entry_single' ] // Force the cap to trash the entry, since we cant provide edit cap here. ); // If it didn't work continue. if ( ! $success ) { continue; } if ( $status !== '' ) { wpforms()->obj( 'entry_meta' )->add( [ 'entry_id' => $id, 'form_id' => $form_id, 'user_id' => $user_id, 'type' => 'status_prev', 'data' => '', 'status' => $status, ], 'entry_meta' ); } ++$trashed; } return $trashed; } /** * Return validated information about search or FALSE. * * @since 1.8.6 * * @return bool|array */ protected function get_filter_search_parts() { // phpcs:disable WordPress.Security.NonceVerification.Recommended if ( empty( $_GET['search'] ) ) { return false; } $expected = [ 'field', 'comparison', 'term' ]; foreach ( $expected as $field ) { if ( ! isset( $_GET['search'][ $field ] ) || $_GET['search'][ $field ] === '' ) { return false; } } return array_map( 'sanitize_text_field', wp_unslash( $_GET['search'] ) ); // phpcs:enable WordPress.Security.NonceVerification.Recommended } /** * Return HTML with information about the search filter. * * @since 1.8.6 * * @return string */ protected function get_filter_search_html() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity $form_id = $this->get_filtered_form_id(); $data = $this->get_filter_search_parts(); if ( ! $data ) { return ''; } $comparisons = [ 'contains' => __( 'contains', 'wpforms' ), 'contains_not' => __( 'does not contain', 'wpforms' ), 'is' => __( 'is', 'wpforms' ), 'is_not' => __( 'is not', 'wpforms' ), ]; $comparison = isset( $comparisons[ $data['comparison'] ] ) ? $comparisons[ $data['comparison'] ] : $comparisons['contains']; $field = isset( $data['field'] ) ? $data['field'] : ''; $term = isset( $data['term'] ) ? $data['term'] : ''; // phpcs:disable WordPress.Security.NonceVerification.Recommended if ( ! empty( $_GET['search']['term'] ) && wpforms_is_empty_string( $term ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $term = htmlspecialchars( wp_unslash( $_GET['search']['term'] ) ); } // phpcs:enable WordPress.Security.NonceVerification.Recommended if ( is_numeric( $field ) && $form_id ) { $meta = wpforms()->obj( 'form' )->get_field( $form_id, $field ); if ( isset( $meta['label'] ) ) { $field = $meta['label']; } } else { $advanced_options = Helpers::get_search_fields_advanced_options(); $field = ! empty( $advanced_options[ $field ] ) ? $advanced_options[ $field ] : __( 'any form field', 'wpforms' ); } return sprintf( /* translators: %1$s - field name, %2$s - operation, %3$s term. */ __( 'where %1$s %2$s "%3$s"', 'wpforms' ), '<em>' . esc_html( $field ) . '</em>', esc_html( $comparison ), '<em>' . esc_html( $term ) . '</em>' ); } /** * Get filtered date range. * * @since 1.8.6 * * @return array * * @noinspection PhpMissingReturnTypeInspection */ private function get_filtered_dates() { /** * Filter the date range for the entry list page. * * @since 1.9.8.6 * * @param array $dates Date range in the Y-m-d format. The 1st element is the start date, the 2nd element is the end date. */ $dates = (array) apply_filters( 'wpforms_pro_admin_entries_page_get_filtered_dates', [] ); if ( ! empty( $dates ) ) { return array_map( 'sanitize_text_field', $dates ); } // phpcs:disable WordPress.Security.NonceVerification.Recommended if ( empty( $_GET['date'] ) ) { return []; } $dates = (array) explode( ' - ', sanitize_text_field( wp_unslash( $_GET['date'] ) ) ); return array_map( 'sanitize_text_field', $dates ); // phpcs:enable WordPress.Security.NonceVerification.Recommended } /** * Return an array with information (HTML and id) for each filter for this current view. * * @since 1.8.6 * * @return array */ public function get_filters_html() { $filters = [ '.search-box' => $this->get_filter_search_html(), ]; $dates = $this->get_filtered_dates(); if ( $dates ) { $dates = array_map( static function ( $date ) { return wpforms_date_format( $date ); }, $dates ); $html = ''; switch ( count( $dates ) ) { case 1: $html = sprintf( /* translators: %s: date. */ esc_html__( 'on %s', 'wpforms' ), '<em>' . $dates[0] . '</em>' ); break; case 2: $html = sprintf( /* translators: %1$s - date, %2$s - date. */ esc_html__( 'between %1$s and %2$s', 'wpforms' ), '<em>' . $dates[0] . '</em>', '<em>' . $dates[1] . '</em>' ); break; } $filters['.wpforms-filter-date'] = $html; } return array_filter( $filters ); } /** * Watch for filtering requests from a dates range selection. * * @since 1.8.6 */ public function process_filter_dates() { $form_id = $this->get_filtered_form_id(); if ( empty( $form_id ) ) { return; } $dates = $this->get_filtered_dates(); if ( empty( $dates ) ) { return; } $this->filter = array_merge( $this->filter, [ 'date' => count( $dates ) === 1 ? $dates[0] : $dates, 'is_filtered' => true, ] ); } /** * Setup entry list page data. * * This function does the error checking and variable setup. * * @since 1.8.6 */ public function setup() { if ( wpforms_current_user_can( 'view_forms' ) ) { $forms = wpforms()->obj( 'form' )->get( '', [ 'orderby' => 'ID', 'order' => 'ASC', 'post_type' => wpforms()->obj( 'entries_overview' )->overview_show_form_templates() ? wpforms()->obj( 'form' )::POST_TYPES : 'wpforms', ] ); // Fetch all forms. $this->forms = wpforms()->obj( 'access' )->filter_forms_by_current_user_capability( $forms, 'view_entries_form_single' ); } // Check that the user has created at least one form. if ( empty( $this->forms ) ) { $this->alerts[] = [ 'type' => 'info', 'message' => sprintf( wp_kses( /* translators: %s - WPForms Builder page. */ __( 'Whoops, you haven\'t created a form yet. Want to <a href="%s">give it a go</a>?', 'wpforms' ), [ 'a' => [ 'href' => [], ], ] ), admin_url( 'admin.php?page=wpforms-builder' ) ), 'abort' => true, ]; } else { $form_id = $this->get_filtered_form_id(); /** * Filters a default form id on the Entries list page. * * @since 1.1.6 * * @param int $form_id Default form id. * * @return int */ $this->form_id = $form_id ? $form_id : apply_filters( 'wpforms_entry_list_default_form_id', absint( $this->forms[0]->ID ) ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName $this->form = wpforms()->obj( 'form' )->get( $this->form_id, [ 'cap' => 'view_entries_form_single' ] ); } } /** * Whether the current list of entries is filtered somehow or not. * * @since 1.8.6 * * @return bool */ protected function is_list_filtered() { $search_parts = $this->get_filter_search_parts(); $dates = $this->get_filtered_dates(); $is_filtered = ! empty( $dates ) || ( isset( $search_parts['term'] ) && ! wpforms_is_empty_string( $search_parts['term'] ) ); /** * Allows to mark the entries list as filtered or not, based on certain conditions. * * By default, the list is considered filtered if the date range is set or * a non-empty search term is applied. * * @since 1.4.4 * * @param bool $is_filtered Is the list filtered? */ return (bool) apply_filters( 'wpforms_entries_list_is_list_filtered', $is_filtered ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName } /** * List all entries in a specific form. * * @since 1.8.6 */ public function list_all() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity if ( $this->abort ) { return; } $post_content = $this->form->post_content ?? ''; $form_data = $post_content ? wpforms_decode( $post_content ) : []; /** * Filter the list all wrap classes. * * @since 1.8.3 * * @param array $classes List all wrap classes. */ $classes = apply_filters( // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName 'wpforms_entries_list_list_all_wrap_classes', [ 'wrap', 'wpforms-admin-wrap', ] ); ?> <div id="wpforms-entries-list" class="<?php echo wpforms_sanitize_classes( $classes, true ); ?>"> <h1 class="page-title"><?php esc_html_e( 'Entries', 'wpforms' ); ?></h1> <?php $this->entries->form_id = $this->form_id; $this->entries->form_data = $form_data; $this->entries->prepare_items(); $last_entry = wpforms()->obj( 'entry' )->get_last( $this->form_id ); ?> <?php $this->entries_disabled_notice(); ?> <div class="wpforms-admin-content"> <?php // Show empty entries table after delete bulk action. $is_deleted = isset( $_REQUEST['deleted'] ) && $_REQUEST['deleted'] === '1'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $is_filtered = $this->is_list_filtered(); if ( empty( $this->entries->items ) && $this->entries->counts['spam'] === 0 && $this->entries->counts['trash'] === 0 && ! $is_deleted && // phpcs:ignore WordPress.Security.NonceVerification.Recommended ! $is_filtered && ! isset( $_GET['type'] ) && ! isset( $_GET['status'] ) ) { // Output no entries screen. // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo wpforms_render( 'admin/empty-states/no-entries', [ 'message' => ! empty( $this->entries->form_data['settings']['disable_entries'] ) ? __( 'Storing entry information has been disabled for this form.', 'wpforms' ) : __( 'It looks like you don\'t have any form entries just yet - check back soon!', 'wpforms' ), ], true ); } else { /** * Fire before entries table. * * @since 1.1.6 * * @param array $form_data Form content. * @param Page $entries_list WPForms\Pro\Admin\Entries\Page class instance. */ do_action( 'wpforms_entry_list_title', $form_data, $this ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName // Are we on the "Spam" or "Trash" tab? // phpcs:disable WordPress.Security.NonceVerification.Recommended $has_status = isset( $_GET['status'] ) && in_array( $_GET['status'], [ SpamEntry::ENTRY_STATUS, self::TRASH_ENTRY_STATUS ], true ); $status = $has_status ? sanitize_key( $_GET['status'] ) : ''; // phpcs:enable WordPress.Security.NonceVerification.Recommended ?> <form id="wpforms-entries-table" method="GET" action="<?php echo esc_url( admin_url( 'admin.php?page=wpforms-entries' ) ); ?>" <?php echo ( ! $this->is_list_filtered() && isset( $last_entry->entry_id ) ) ? 'data-last-entry-id="' . absint( $last_entry->entry_id ) . '"' : ''; ?> <?php printf( 'data-filtered-count-trash="%1d"', absint( $this->entries->counts['total'] ) ); ?>> <?php if ( $this->get_filters_html() ) : ?> <div id="wpforms-reset-filter"> <?php printf( wp_kses( /* translators: %s - number of entries found. */ _n( 'Found <strong>%s entry</strong>', 'Found <strong>%s entries</strong>', absint( count( (array) $this->entries->items ) ), 'wpforms' ), [ 'strong' => [], ] ), $has_status ? absint( $this->entries->counts[ $status ] ) : absint( $this->entries->counts['total'] ) ); ?> <?php foreach ( $this->get_filters_html() as $id => $html ) : ?> <?php echo wp_kses( $html, [ 'em' => [] ] ); ?> <i class="reset fa fa-times-circle" data-scope="<?php echo esc_attr( $id ); ?>"></i> <?php endforeach; ?> </div> <?php endif ?> <input type="hidden" name="page" value="wpforms-entries" /> <input type="hidden" name="view" value="list" /> <input type="hidden" name="form_id" value="<?php echo absint( $this->form_id ); ?>" /> <?php if ( $has_status ) : ?> <input type="hidden" name="status" value="<?php echo esc_attr( $status ); ?>" /> <?php endif; ?> <?php $this->entries->views(); ?> <?php $this->entries->search_box( esc_html__( 'Search', 'wpforms' ), 'wpforms-entries' ); ?> <?php $this->entries->display(); ?> </form> <?php } ?> </div> </div> <?php } /** * Display abort message using empty state page. * * @since 1.8.6 */ public function display_abort_message() { if ( ! $this->abort ) { return; } ?> <div id="wpforms-entries-list" class="wrap wpforms-admin-wrap"> <h1 class="page-title"> <?php esc_html_e( 'Entries', 'wpforms' ); ?> </h1> <div class="wpforms-admin-content"> <?php // Output empty state screen. // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo wpforms_render( 'admin/empty-states/no-entries', [ 'message' => $this->abort_message, ], true ); ?> </div> </div> <?php } /** * Settings for field column personalization! * * @since 1.8.6 */ public function field_column_setting() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $this->get_columns_multiselect(); } /** * Get columns multiselect menu. * * @since 1.8.6 * * @return string HTML menu markup. */ private function get_columns_multiselect(): string { $field_columns = Columns::get_field_columns( $this->form_id ); $meta_columns = Columns::get_meta_columns(); $selected_keys = Columns::get_selected_columns_keys(); $selected_keys = empty( $selected_keys ) ? Columns::get_default_columns_keys() : $selected_keys; $html = ' <div id="wpforms-list-table-ext-edit-columns-select-container" class="wpforms-hidden wpforms-list-table-ext-edit-columns-select-container wpforms-entries-list-page"> <form method="post" action="' . esc_url( admin_url( 'admin.php?page=wpforms-entries&view=list&form_id=' . (int) $this->form_id ) ) . '"> <input type="hidden" name="action" value="wpforms_admin_entries_list_save_columns_order"/> <input type="hidden" name="form_id" value="' . (int) $this->form_id . '"/> <select name="fields[]" id="wpforms-entries-table-edit-columns-select" class="wpforms-entries-table-edit-columns-select wpforms-list-table-ext-edit-columns-select" name="wpforms-entries-table-edit-columns-select" multiple="multiple"> %s %s </select> </form> </div> '; $field_options = $this->get_optgroup_html( $field_columns, $selected_keys, esc_html__( 'Form Fields', 'wpforms' ) ); $meta_options = $this->get_optgroup_html( $meta_columns, $selected_keys, esc_html__( 'Entry Meta', 'wpforms' ) ); return sprintf( $html, $field_options, $meta_options ); } /** * Get columns multiselect options. * * @since 1.8.6 * * @param Column[] $columns List of columns. * @param array $selected_keys List of selected columns keys. * @param string $label Label for the optgroup. * * @return string HTML options markup. */ private function get_optgroup_html( $columns, $selected_keys, $label ): string { if ( empty( $columns ) ) { return ''; } $html = '<optgroup label="' . esc_html( $label ) . '">'; foreach ( $columns as $column ) { $selected = in_array( $column->get_id(), $selected_keys, true ) ? 'selected' : ''; $html .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $column->get_id() ), $selected, esc_html( $column->get_label() ) ); } $html .= '</optgroup>'; return $html; } /** * Entries list form actions. * * @since 1.8.6 * * @param array $form_data Form data and settings. * * @noinspection PhpMissingParamTypeInspection, ReturnTypeCanBeDeclaredInspection */ public function list_form_actions( $form_data ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity $actions = [ 'all_entries', 'payments', 'edit_form', 'view_form', 'export_entries', 'read_entries', 'delete_entries' ]; /** * Filter the list of entries list form actions. * * @since 1.9.8.6 * * @param array $actions List of entries list form actions. * @param array $form_data Form data and settings. */ $actions = (array) apply_filters( 'wpforms_pro_admin_entries_page_actions', $actions, $form_data ); $base = add_query_arg( [ 'page' => 'wpforms-entries', 'view' => 'list', 'form_id' => absint( $this->form_id ), ], admin_url( 'admin.php' ) ); // Edit Form URL. $edit_url = add_query_arg( [ 'page' => 'wpforms-builder', 'view' => 'fields', 'form_id' => absint( $this->form_id ), ], admin_url( 'admin.php' ) ); // Payments URL. if ( wpforms()->obj( 'payment' )->get_by( 'form_id', $this->form_id ) ) { $payments_url = add_query_arg( [ 'page' => 'wpforms-payments', 'form_id' => absint( $this->form_id ), ], admin_url( 'admin.php' ) ); } // Preview Entry URL. $preview_url = esc_url( wpforms_get_form_preview_url( $this->form_id ) ); // Export Entry URL. // phpcs:disable WordPress.Security.NonceVerification.Recommended $export_url = add_query_arg( [ 'page' => 'wpforms-tools', 'view' => 'export', 'form' => absint( $this->form_id ), 'search' => ! empty( $_GET['search'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_GET['search'] ) ) : [], 'date' => ! empty( $_GET['date'] ) ? sanitize_text_field( wp_unslash( $_GET['date'] ) ) : [], ], admin_url( 'admin.php' ) ); $read_url_args = [ 'action' => 'markread' ]; if ( isset( $_GET['status'] ) && ! empty( $_GET['status'] ) ) { $read_url_args['status'] = sanitize_key( $_GET['status'] ); } // phpcs:enable WordPress.Security.NonceVerification.Recommended // Mark Read URL. $read_url = wp_nonce_url( add_query_arg( $read_url_args, $base ), 'wpforms_entry_list_markread' ); // Delete all entries. $delete_url = wp_nonce_url( $base, 'bulk-entries' ); // Form title. $form_title = isset( $form_data['settings']['form_title'] ) ? $form_data['settings']['form_title'] : ''; if ( empty( $form_title ) ) { $form = wpforms()->obj( 'form' )->get( $this->form_id ); $form_title = ! empty( $form ) ? $form->post_title : sprintf( /* translators: %d - form ID. */ esc_html__( 'Form (#%d)', 'wpforms' ), $this->form_id ); } $is_form_template = wpforms_is_form_template( $this->form_id ); $form_title_suffix = ''; if ( $is_form_template ) { $form_title_suffix = sprintf( '<span> — %s</span>', esc_html__( 'Template', 'wpforms' ) ); } ?> <div class="form-details"> <span class="form-details-sub"><?php esc_html_e( 'Select Form', 'wpforms' ); ?></span> <h3 class="form-details-title"> <?php echo esc_html( wp_strip_all_tags( $form_title ) ) . wp_kses( $form_title_suffix, [ 'span' => [] ] ); $this->form_selector_html(); ?> </h3> <div class="form-details-actions"> <?php if ( in_array( 'all_entries', $actions, true ) && $this->is_list_filtered() ) : ?> <a href="<?php echo esc_url( $base ); ?>" class="form-details-actions-entries"> <span class="dashicons dashicons-list-view"></span> <?php esc_html_e( 'All Entries', 'wpforms' ); ?> </a> <?php endif; ?> <?php if ( in_array( 'payments', $actions, true ) && isset( $payments_url ) ) : ?> <a href="<?php echo esc_url( $payments_url ); ?>" class="form-details-actions-view-payments"> <span class="fa fa-credit-card"></span> <?php esc_html_e( 'View Payments', 'wpforms' ); ?> </a> <?php endif; ?> <?php if ( in_array( 'edit_form', $actions, true ) && wpforms_current_user_can( 'edit_form_single', $this->form_id ) ) : ?> <a href="<?php echo esc_url( $edit_url ); ?>" class="form-details-actions-edit"> <span class="dashicons dashicons-edit"></span> <?php $is_form_template ? esc_html_e( 'Edit This Template', 'wpforms' ) : esc_html_e( 'Edit This Form', 'wpforms' ); ?> </a> <?php endif; ?> <?php if ( in_array( 'view_form', $actions, true ) && wpforms_current_user_can( 'view_form_single', $this->form_id ) ) : ?> <a href="<?php echo esc_url( $preview_url ); ?>" class="form-details-actions-preview" target="_blank" rel="noopener noreferrer"> <span class="dashicons dashicons-visibility"></span> <?php $is_form_template ? esc_html_e( 'Preview Template', 'wpforms' ) : esc_html_e( 'Preview Form', 'wpforms' ); ?> </a> <?php endif; ?> <?php if ( in_array( 'export_entries', $actions, true ) && ! $is_form_template ) : ?> <a href="<?php echo esc_url( $export_url ); ?>" class="form-details-actions-export"> <span class="dashicons dashicons-migrate"></span> <?php echo $this->is_list_filtered() ? esc_html__( 'Export Filtered', 'wpforms' ) : esc_html__( 'Export All', 'wpforms' ); ?> </a> <?php endif; ?> <?php if ( in_array( 'read_entries', $actions, true ) ) : ?> <a href="<?php echo esc_url( $read_url ); ?>" class="form-details-actions-read"> <span class="dashicons dashicons-marker"></span> <?php esc_html_e( 'Mark All Read', 'wpforms' ); ?> </a> <?php endif; ?> <?php if ( in_array( 'delete_entries', $actions, true ) && wpforms_current_user_can( 'delete_entries_form_single', $this->form_id ) ) : ?> <?php $status = ! empty( $_GET['status'] ) ? sanitize_key( $_GET['status'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended ?> <a href="<?php echo esc_url( $delete_url ); ?>" class="form-details-actions-removeall" data-page="<?php echo esc_attr( $status ); ?>"> <span class="dashicons dashicons-trash"></span> <?php $status === self::TRASH_ENTRY_STATUS ? esc_html_e( 'Empty Trash', 'wpforms' ) : esc_html_e( 'Trash All', 'wpforms' ); ?> </a> <?php endif; ?> </div> </div> <?php } /** * Display form selector HTML. * * @since 1.8.6 */ protected function form_selector_html() { if ( ! wpforms_current_user_can( 'view_forms' ) ) { return; } if ( empty( $this->forms ) ) { return; } ?> <div class="form-selector"> <a href="#" title="<?php esc_attr_e( 'Open form selector', 'wpforms' ); ?>" class="toggle dashicons dashicons-arrow-down-alt2"></a> <div class="form-list"> <ul> <?php foreach ( $this->forms as $key => $form ) { if ( $this->form_id === $form->ID ) { continue; } $form_url = add_query_arg( [ 'page' => 'wpforms-entries', 'view' => 'list', 'form_id' => absint( $form->ID ), ], admin_url( 'admin.php' ) ); $form_title = $form->post_type === 'wpforms-template' ? $form->post_title . ' – ' . __( 'Template', 'wpforms' ) : $form->post_title; printf( '<li><a href="%s">%s</a></li>', esc_url( $form_url ), esc_html( $form_title ) ); } ?> </ul> </div> </div> <?php } /** * Add notices and errors. * * @since 1.8.6 */ public function register_alerts() { if ( empty( $this->alerts ) ) { return; } foreach ( $this->alerts as $alert ) { $type = ! empty( $alert['type'] ) ? $alert['type'] : 'info'; Notice::add( $alert['message'], $type ); if ( ! empty( $alert['abort'] ) ) { $this->abort = true; break; } } } /** * Check for new entries using Heartbeat API. * * @since 1.8.6 * * @param array $response The Heartbeat response. * @param array $data The $_POST data sent. * @param string $screen_id The screen id. * * @return array */ public function heartbeat_new_entries_check( $response, $data, $screen_id ) { if ( $screen_id !== 'wpforms_page_wpforms-entries' ) { return $response; } $entry_id = ! empty( $data['wpforms_new_entries_entry_id'] ) ? absint( $data['wpforms_new_entries_entry_id'] ) : 0; $form_id = ! empty( $data['wpforms_new_entries_form_id'] ) ? absint( $data['wpforms_new_entries_form_id'] ) : 0; if ( empty( $form_id ) ) { return $response; } $entries_count = wpforms()->obj( 'entry' )->get_next_count( $entry_id, $form_id, '' ); if ( empty( $entries_count ) ) { return $response; } /* translators: %d - number of form entries. */ $response['wpforms_new_entries_notification'] = esc_html( sprintf( _n( 'See %d new entry', 'See %d new entries', $entries_count, 'wpforms' ), $entries_count ) ); return $response; } /** * Localize needed strings. * * @since 1.8.6 * * @param array $strings JS strings. * * @return mixed */ public function js_strings( $strings ) { $strings['lang_code'] = sanitize_key( wpforms_get_language_code() ); $strings['default_date'] = []; $dates = $this->get_filtered_dates(); if ( $dates ) { if ( count( $dates ) === 1 ) { $dates[1] = $dates[0]; } $strings['default_date'] = [ sanitize_text_field( $dates[0] ), sanitize_text_field( $dates[1] ) ]; } return $strings; } /** * Display info notice for forms that have entries and disable_entries setting. * * The entries list isn't available when register_alerts runs. * * @since 1.8.6 * * @return void */ protected function entries_disabled_notice() { if ( empty( $this->entries->form_data['settings']['disable_entries'] ) || empty( $this->entries->items ) ) { return; } ?> <div class="notice wpforms-notice notice-info" style="display: block;"> <p> <?php esc_html_e( 'Storing entry information has been disabled for this form.', 'wpforms' ); ?> </p> </div> <?php } }
| ver. 1.1 | |
.
| PHP 8.3.30 | Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñтраницы: 0 |
proxy
|
phpinfo
|
ÐаÑтройка