将搜索值添加到wp_list_table分页

时间:2018-06-05 作者:keithp

我有一个使用wp\\u list\\u table的自定义WordPress表,其中有一个搜索字段:搜索效果很好,但我发现当有多页结果时,搜索值不会添加到分页链接中。以下是我的完整代码:

if ( ! class_exists( \'WP_List_Table\' ) ) {
    require_once( ABSPATH . \'wp-admin/includes/class-wp-list-table.php\' );
}

class Customers_List extends WP_List_Table {

    /** Class constructor */
    public function __construct() {

        parent::__construct( [
            \'singular\' => __( \'Order\', \'sp\' ), //singular name of the listed records
            \'plural\'   => __( \'Orders\', \'sp\' ), //plural name of the listed records
            \'ajax\'     => false //does this table support ajax?
        ] );

    }


    /**
     * Retrieve customers data from the database
     *
     * @param int $per_page
     * @param int $page_number
     *
     * @return mixed
     */
    public static function get_customers( $per_page = 5, $page_number = 1 ) {

        global $wpdb;

        $sql = "SELECT * FROM old_order";

        if( ! empty( $_REQUEST[\'s\'] ) ){
                        $search = esc_sql( $_REQUEST[\'s\'] );
            $sql .= " WHERE firstname LIKE \'%{$search}%\'";
            $sql .= " OR lastname LIKE \'%{$search}%\'";
            $sql .= " OR order_id = \'{$search}\'";
        }

        if ( ! empty( $_REQUEST[\'orderby\'] ) ) {
            $sql .= \' ORDER BY \' . esc_sql( $_REQUEST[\'orderby\'] );
            $sql .= ! empty( $_REQUEST[\'order\'] ) ? \' \' . esc_sql( $_REQUEST[\'order\'] ) : \' ASC\';
        }

        $sql .= " LIMIT $per_page";
        $sql .= \' OFFSET \' . ( $page_number - 1 ) * $per_page;

        // echo $sql;

        $result = $wpdb->get_results( $sql, \'ARRAY_A\' );

        return $result;
    }


    /**
     * Delete a customer record.
     *
     * @param int $id customer ID
     */
    public static function delete_customer( $id ) {
        global $wpdb;

        $wpdb->delete(
            "old_order",
            [ \'ID\' => $id ],
            [ \'%d\' ]
        );
    }


    /**
     * Returns the count of records in the database.
     *
     * @return null|string
     */
    public static function record_count() {
        global $wpdb;

        $sql = "SELECT COUNT(*) FROM old_order";

        if( ! empty( $_REQUEST[\'s\'] ) ){
            $search = esc_sql( $_REQUEST[\'s\'] );
            $sql .= " WHERE firstname LIKE \'%{$search}%\'";
            $sql .= " OR lastname LIKE \'%{$search}%\'";
            $sql .= " OR order_id LIKE \'%{$search}%\'";
        }

        return $wpdb->get_var( $sql );
    }


    /** Text displayed when no customer data is available */
    public function no_items() {
        _e( \'No orders available..\', \'sp\' );
    }


    /**
     * Render a column when no column specific method exist.
     *
     * @param array $item
     * @param string $column_name
     *
     * @return mixed
     */
    public function column_default( $item, $column_name ) {
        switch ( $column_name ) {
            case \'order_id\':
                return $item[ $column_name ];
            case \'firstname\':
                return $item[ $column_name ];
            case \'lastname\':
                return $item[ $column_name ];
            case \'total\':
                return "$" . number_format( $item[ $column_name ] );
            case \'date_added\':
                return date(\'m/d/Y g:i:s A\', strtotime( $item[ $column_name ] ) );
            default:
                return print_r( $item, true ); //Show the whole array for troubleshooting purposes
        }
    }

    /**
     * Render the bulk edit checkbox
     *
     * @param array $item
     *
     * @return string
     */
    function column_cb( $item ) {
        return sprintf(
            \'<input type="checkbox" name="bulk-delete[]" value="%s" />\', $item[\'ID\']
        );
    }


    /**
     * Method for name column
     *
     * @param array $item an array of DB data
     *
     * @return string
     */
    function column_name( $item ) {

        $delete_nonce = wp_create_nonce( \'sp_delete_customer\' );

        $title = \'<strong>\' . $item[\'name\'] . \'</strong>\';

        $actions = [
            \'delete\' => sprintf( \'<a href="?page=%s&action=%s&customer=%s&_wpnonce=%s">Delete</a>\', esc_attr( $_REQUEST[\'page\'] ), \'delete\', absint( $item[\'ID\'] ), $delete_nonce )
        ];

        return $title . $this->row_actions( $actions );
    }


    /**
     *  Associative array of columns
     *
     * @return array
     */
    function get_columns() {
        $columns = [
            \'cb\'      => \'<input type="checkbox" />\',
            \'order_id\'    => __( \'Order ID\', \'sp\' ),
            \'firstname\' => __( \'First Name\', \'sp\' ),
            \'lastname\'    => __( \'Last Name\', \'sp\' ),
            \'total\'    => __( \'Total\', \'sp\' ),
            \'date_added\'    => __( \'Date Added\', \'sp\' )
        ];

        return $columns;
    }


    /**
     * Columns to make sortable.
     *
     * @return array
     */
    public function get_sortable_columns() {
        $sortable_columns = array(
            \'order_id\' => array( \'order_id\', true ),
            \'firstname\' => array( \'firstname\', true ),
            \'lastname\' => array( \'lastname\', true )
        );

        return $sortable_columns;
    }

    /**
     * Returns an associative array containing the bulk action
     *
     * @return array
     */
    public function get_bulk_actions() {
        $actions = [
            \'bulk-delete\' => \'Delete\'
        ];

        return $actions;
    }


    /**
     * Handles data query and filter, sorting, and pagination.
     */
    public function prepare_items( ) {

        $this->_column_headers = $this->get_column_info();

        /** Process bulk action */
        $this->process_bulk_action();

        $per_page     = $this->get_items_per_page( \'customers_per_page\', 20 );
        $current_page = $this->get_pagenum();
        $total_items  = self::record_count();

        $this->set_pagination_args( [
            \'total_items\' => $total_items, //WE have to calculate the total number of items
            \'per_page\'    => $per_page //WE have to determine how many items to show on a page
        ] );

        $this->items = self::get_customers( $per_page, $current_page );
    }

    public function process_bulk_action() {

        //Detect when a bulk action is being triggered...
        if ( \'delete\' === $this->current_action() ) {

            // In our file that handles the request, verify the nonce.
            $nonce = esc_attr( $_REQUEST[\'_wpnonce\'] );

            if ( ! wp_verify_nonce( $nonce, \'sp_delete_customer\' ) ) {
                die( \'Go get a life script kiddies\' );
            }
            else {
                self::delete_customer( absint( $_GET[\'customer\'] ) );

                        // esc_url_raw() is used to prevent converting ampersand in url to "#038;"
                        // add_query_arg() return the current url
                        wp_redirect( esc_url_raw(add_query_arg()) );
                exit;
            }

        }

        // If the delete bulk action is triggered
        if ( ( isset( $_POST[\'action\'] ) && $_POST[\'action\'] == \'bulk-delete\' )
             || ( isset( $_POST[\'action2\'] ) && $_POST[\'action2\'] == \'bulk-delete\' )
        ) {

            $delete_ids = esc_sql( $_POST[\'bulk-delete\'] );

            // loop over the array of record IDs and delete them
            foreach ( $delete_ids as $id ) {
                self::delete_customer( $id );

            }

            // esc_url_raw() is used to prevent converting ampersand in url to "#038;"
                // add_query_arg() return the current url
                wp_redirect( esc_url_raw(add_query_arg()) );
            exit;
        }
    }

}


class SP_Plugin {

    // class instance
    static $instance;

    // customer WP_List_Table object
    public $customers_obj;

    // class constructor
    public function __construct() {
        add_filter( \'set-screen-option\', [ __CLASS__, \'set_screen\' ], 10, 3 );
        add_action( \'admin_menu\', [ $this, \'plugin_menu\' ] );
    }


    public static function set_screen( $status, $option, $value ) {
        return $value;
    }

    public function plugin_menu() {

        $hook = add_menu_page(
            \'Order Lookup\',
            \'Order Lookup\',
            \'manage_options\',
            \'wp_list_table_class\',
            [ $this, \'plugin_settings_page\' ]
        );

        add_action( "load-$hook", [ $this, \'screen_option\' ] );

    }


    /**
     * Plugin settings page
     */
    public function plugin_settings_page() {
        ?>
        <div class="wrap">
            <h2>Previous Order System Lookup</h2>

            <div id="poststuff">
                <div id="post-body" class="metabox-holder columns-2">
                    <div id="post-body-content">
                        <div class="meta-box-sortables ui-sortable">
                            <form method="get">
                                <?php
                                $this->customers_obj->prepare_items();
                                $this->customers_obj->search_box(\'Search\', \'search\');
                                $this->customers_obj->display(); ?>
                            </form>
                        </div>
                    </div>
                </div>
                <br class="clear">
            </div>
        </div>
    <?php
    }

    /**
     * Screen options
     */
    public function screen_option() {

        $option = \'per_page\';
        $args   = [
            \'label\'   => \'Customers\',
            \'default\' => 20,
            \'option\'  => \'customers_per_page\'
        ];

        add_screen_option( $option, $args );

        $this->customers_obj = new Customers_List();
    }


    /** Singleton instance */
    public static function get_instance() {
        if ( ! isset( self::$instance ) ) {
            self::$instance = new self();
        }

        return self::$instance;
    }

}


add_action( \'plugins_loaded\', function () {
    SP_Plugin::get_instance();
} );
除了在有多个页面时向分页链接添加搜索值外,所有操作都按预期进行。因此,当您单击“下一步”时,它会删除搜索值并返回所有结果(在下一页)。我将此要点作为参考:https://gist.github.com/paulund/7659452

2 个回复
SO网友:keithp

通过将page变量作为隐藏字段传递,我解决了我的问题:

<form method="get">
    <input type="hidden" name="page" value="<?php echo $_REQUEST[\'page\'] ?>" />
    <?php
    $this->customers_obj->prepare_items();
    $this->customers_obj->search_box(\'Search\', \'search\');
    $this->customers_obj->display(); ?>
</form>

SO网友:Rohit Sharma

我通过克隆WP列表的分页函数并在url中添加搜索变量来实现这一点。以下是相同的代码。

受保护的函数分页($which){if(empty($this->;\\u pagination\\u args)){return;}

    $total_items     = $this->_pagination_args[\'total_items\'];
    $total_pages     = $this->_pagination_args[\'total_pages\'];
    $infinite_scroll = false;

    if ( isset( $this->_pagination_args[\'infinite_scroll\'] ) ) {
        $infinite_scroll = $this->_pagination_args[\'infinite_scroll\'];
    }

    if ( \'top\' === $which && $total_pages > 1 ) {
        $this->screen->render_screen_reader_content( \'heading_pagination\' );
    }

    $output = \'<span class="displaying-num">\' . sprintf( _n( \'%s item\', \'%s items\', $total_items ), number_format_i18n( $total_items ) ) . \'</span>\';

    $current              = $this->get_pagenum();
    $removable_query_args = wp_removable_query_args();

    $current_url = set_url_scheme( \'http://\' . $_SERVER[\'HTTP_HOST\'] . $_SERVER[\'REQUEST_URI\'] );

    $current_url = remove_query_arg( $removable_query_args, $current_url );

    if( isset($_REQUEST[\'s\'] ) ){
        $current_url = add_query_arg( \'s\', $_REQUEST[\'s\'], $current_url );
    }

    $page_links = array();

    $total_pages_before = \'<span class="paging-input">\';
    $total_pages_after  = \'</span></span>\';

    $disable_first = $disable_last = $disable_prev = $disable_next = false;

    if ( $current == 1 ) {
        $disable_first = true;
        $disable_prev  = true;
    }
    if ( $current == 2 ) {
        $disable_first = true;
    }
    if ( $current == $total_pages ) {
        $disable_last = true;
        $disable_next = true;
    }
    if ( $current == $total_pages - 1 ) {
        $disable_last = true;
    }

    if ( $disable_first ) {
        $page_links[] = \'<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&laquo;</span>\';
    } else {
        $page_links[] = sprintf(
            "<a class=\'first-page button\' href=\'%s\'><span class=\'screen-reader-text\'>%s</span><span aria-hidden=\'true\'>%s</span></a>",
            esc_url( remove_query_arg( \'paged\', $current_url ) ),
            __( \'First page\' ),
            \'&laquo;\'
        );
    }

    if ( $disable_prev ) {
        $page_links[] = \'<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&lsaquo;</span>\';
    } else {
        $page_links[] = sprintf(
            "<a class=\'prev-page button\' href=\'%s\'><span class=\'screen-reader-text\'>%s</span><span aria-hidden=\'true\'>%s</span></a>",
            esc_url( add_query_arg( \'paged\', max( 1, $current - 1 ), $current_url ) ),
            __( \'Previous page\' ),
            \'&lsaquo;\'
        );
    }

    if ( \'bottom\' === $which ) {
        $html_current_page  = $current;
        $total_pages_before = \'<span class="screen-reader-text">\' . __( \'Current Page\' ) . \'</span><span id="table-paging" class="paging-input"><span class="tablenav-paging-text">\';
    } else {
        $html_current_page = sprintf(
            "%s<input class=\'current-page\' id=\'current-page-selector\' type=\'text\' name=\'paged\' value=\'%s\' size=\'%d\' aria-describedby=\'table-paging\' /><span class=\'tablenav-paging-text\'>",
            \'<label for="current-page-selector" class="screen-reader-text">\' . __( \'Current Page\' ) . \'</label>\',
            $current,
            strlen( $total_pages )
        );
    }
    $html_total_pages = sprintf( "<span class=\'total-pages\'>%s</span>", number_format_i18n( $total_pages ) );
    $page_links[]     = $total_pages_before . sprintf( _x( \'%1$s of %2$s\', \'paging\' ), $html_current_page, $html_total_pages ) . $total_pages_after;

    if ( $disable_next ) {
        $page_links[] = \'<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&rsaquo;</span>\';
    } else {
        $page_links[] = sprintf(
            "<a class=\'next-page button\' href=\'%s\'><span class=\'screen-reader-text\'>%s</span><span aria-hidden=\'true\'>%s</span></a>",
            esc_url( add_query_arg( \'paged\', min( $total_pages, $current + 1 ), $current_url ) ),
            __( \'Next page\' ),
            \'&rsaquo;\'
        );
    }

    if ( $disable_last ) {
        $page_links[] = \'<span class="tablenav-pages-navspan button disabled" aria-hidden="true">&raquo;</span>\';
    } else {
        $page_links[] = sprintf(
            "<a class=\'last-page button\' href=\'%s\'><span class=\'screen-reader-text\'>%s</span><span aria-hidden=\'true\'>%s</span></a>",
            esc_url( add_query_arg( \'paged\', $total_pages, $current_url ) ),
            __( \'Last page\' ),
            \'&raquo;\'
        );
    }

    $pagination_links_class = \'pagination-links\';
    if ( ! empty( $infinite_scroll ) ) {
        $pagination_links_class .= \' hide-if-js\';
    }
    $output .= "\\n<span class=\'$pagination_links_class\'>" . join( "\\n", $page_links ) . \'</span>\';

    if ( $total_pages ) {
        $page_class = $total_pages < 2 ? \' one-page\' : \'\';
    } else {
        $page_class = \' no-pages\';
    }

    $this->_pagination = "<div class=\'tablenav-pages{$page_class}\'>$output</div>";
    echo $this->_pagination;
}

结束