星期三 , 22 1 月 2025

WP LIST TABLE CLASS 带搜索和排序

<?php 
// Second class: WCF_Contacts_List_Table
if (!class_exists('WP_List_Table')) {
    require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
}
class WCF_Contacts_List_Table extends WP_List_Table {

	public function prepare_items() {
		global $wpdb;

		$columns = $this->get_columns();
		$hidden = array();
		$sortable = $this->get_sortable_columns();

		//设置header 
		$this->_column_headers = array($columns,$hidden,$sortable);

		//sorting
		$orderby = isset($_GET['orderby']) ? $_GET['orderby'] : 'id';  // Changed from $_REQUEST to $_GET
        $order = isset($_GET['order']) ? $_GET['order'] : 'DESC';      // Changed from $_REQUEST to $_GET

		//handle search 
		
		$search = isset($_REQUEST['s']) ? wp_unslash( trim($_REQUEST['s']) ) : '';

		//设置翻页
		$per_page = 3;
		$current_page = $this->get_pagenum();
		$total_items = $this->get_total_contacts($search);

		$this->set_pagination_args(array(
			'total_items'  => $total_items,
			'per_page'  => $per_page,
			'total_pages'  => ceil($total_items / $per_page)
		));

		//Get the data with sorting applied 
		$this->items = $this->get_contacts($per_page, $current_page, $search, $orderby, $order);

		//handle delete action 
		$this->process_action();


	}
	//get_columns 一定要重新覆盖, 获取所有的列
	public function get_columns()
	{

		return array(
			'id'  => __('ID'),
			'name'  => __('Name'),
			'email'  => __('Email'),
			'subject'  => __('Subject'),
			'message'  => __('Message'),
			'message_time' => __('Time'),
			'actions'  => __('Actions'),

		);
		
	}

	//设置可以排序的列
	public function get_sortable_columns()
	{
		return array(

			'id'  => array('id',true),// true means it's the default sorted column
			'message_time'  => array('message_time',false),
			'name'  => array('name',false),
			'email'  => array('email',false),
			'subject'  => array('subject',false),

		);
		
	}

	 // Add this method to enable the search box
    public function search_box($text, $input_id) {
        if (empty($_REQUEST['s']) && !$this->has_items()) {
            return;
        }
 
        $search_value = isset($_REQUEST['s']) ? esc_attr(wp_unslash($_REQUEST['s'])) : '';
        ?>
        <p class="search-box">
            <label class="screen-reader-text" for="<?php echo esc_attr($input_id); ?>"><?php echo $text; ?>:</label>
            <input type="search" id="<?php echo esc_attr($input_id); ?>" name="s" value="<?php echo $search_value; ?>" />
            <?php submit_button($text, '', '', false, array('id' => 'search-submit')); ?>
        </p>
        <?php
    }


	private function get_contacts($per_page,$page_number,$search = '',$orderby = 'id', $order = 'DESC')
	{
		global $wpdb;
		$table_name = $wpdb->prefix . 'wcf_contacts';

		$sql = "SELECT * FROM $table_name";

		//add search condition
		//如果执行了搜索 就是input里面有内容 

		   // handle search
        if (!empty($search)) {
            $wild = '%';
            $like = $wild . $wpdb->esc_like($search) . $wild;
            
            $sql .= " WHERE (
                name LIKE %s 
                OR email LIKE %s 
                OR subject LIKE %s 
                OR message LIKE %s
            )";
            
            $args = array($like, $like, $like, $like);
        }


		//handle sorting 
		

		//validate sorting parameters 
		$allowed_orderby = array('id','message_time','name','email','subject');
		$allowed_order = array('ASC','DESC');

		// Sanitize order and orderby
        $order = in_array(strtoupper($order), $allowed_order) ? strtoupper($order) : 'DESC';

		 // Sanitize and validate orderby
        if (in_array($orderby, $allowed_orderby)) {
            switch ($orderby) {
                case 'id':
                    $sql .= " ORDER BY CAST(id AS SIGNED) $order";
                    break;
                case 'message_time':
                    $sql .= " ORDER BY message_time $order";
                    break;
                default:
                    $sql .= " ORDER BY $orderby $order";
            }
        } else {
            $sql .= " ORDER BY CAST(id AS SIGNED) DESC";
        }

		

		// Add pagination
        $sql .= " LIMIT %d OFFSET %d";
        $args[] = $per_page;
        $args[] = ($page_number - 1) * $per_page;
        
        // Prepare and execute query
        if (!empty($args)) {
            return $wpdb->get_results($wpdb->prepare($sql, $args), ARRAY_A);
        }
        // For debugging
        error_log("SQL Query: " . $sql);
        
        return $wpdb->get_results($sql, ARRAY_A);
		
	}

	//获取所有的items 数量,包括搜索条件下

	private function get_total_contacts($search = '')
	{
		global $wpdb;
		$table_name = $wpdb->prefix . 'wcf_contacts';

		$sql = "SELECT count(*) FROM $table_name";
		$args = array();



		 if (!empty($search)) {
            $wild = '%';
            $like = $wild . $wpdb->esc_like($search) . $wild;
            
            $sql .= " WHERE (
                name LIKE %s 
                OR email LIKE %s 
                OR subject LIKE %s 
                OR message LIKE %s
            )";
            
            $args = array($like, $like, $like, $like);
        }

        if (!empty($args)) {
            return $wpdb->get_var($wpdb->prepare($sql, $args));
        }

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

	public function column_default($item, $column_name) {
		switch ($column_name) {
			case 'id' : 
			case 'name' : 
			case 'email' :
			case 'subject' : 
			case 'message' :
			case 'message_time' : 
				return $item[$column_name];
			case 'actions' : 

			return sprintf(
                    '<a href="%s">Edit</a> | <a href="%s" onclick="return confirm(\'Are you sure you want to delete this booking?\')">Delete</a>',
                    admin_url('admin.php?page=mbs-edit-booking&booking=' . $item['id']),
                    wp_nonce_url(admin_url('admin.php?page=mbs-bookings&action=delete&booking=' . $item['id']), 'delete_booking_' . $item['id'])
                );
			default : 
				return print_r($item, true);

		}
	}






}

用法,在admin页面的回调函数中, 首先把这个class文件在function中引入,然后

public function wcf_display_form_admin_page()
	{
		$contact_table = new WCF_Contacts_List_Table();
		//require_once WCF_PLUGIN_DIR . 'admin/views/tmpl-wcf-admin.php';
		?>

		<div class="wrap">
			<h1 class="wp-heading-inline">WCF Contacts</h1>
			<hr class="wp-header-end">
			<form method="get">
				<?php //添加这个是因为 url 地址会像这样 ?page=wcf-contacts 这个就是查询的参数 也是你提交的页面, 所以这个必须是你管理页面的slug, 也就是上面的wcf-form, 必须添加这个不然搜索的时候不知道如何返回,因为我们添加了搜索框 ?>
				<input type="hidden" name="page" value="wcf-form" />

				<?php 

				$contact_table->prepare_items();
        // Add the search box before the table
        $contact_table->search_box('Search Contacts', 'contact-search');
        $contact_table->display();


				 ?>

			</form>
		</div>

		<?php 
		
	}