skip to Main Content

I wrote a custom plugin and trying to extend WP_List_Table. Its worked fine in older WordPress versions, But when i upgraded to wordpress 6.0 am getting following erro.

My_Cutsom_Table::prepare_items($additions) must be compatible with WP_List_Table::prepare_items()

Following is my code

class My_Cutsom_Table extends WP_List_Table {

    function get_columns()
     {
        $columns = array(
            'display_name' => 'User',
            'user_email' => 'Email',
            'company' => 'Company',
        );
        return $columns;
    }

    public function prepare_items() {
        $columns = $this->get_columns();
        $hidden = array();
        $sortable = $this->get_sortable_columns();
        $this->_column_headers = array($columns, $hidden, $sortable);
        $this->items = $registrations;
    }

    function get_sortable_columns() {
        $sortable_columns = array(
            'display_name' => array('display_name', false),
            'user_email' => array('user_email', false),
            'company' => array('school', false),
            'created_at' => array('created_at', false)
        );
        return $sortable_columns;
    }

    function column_default($item, $column_name) {

        if ($column_name == 'edit_delete') {
            return '<a href="/wp-admin/?page=bsog_events_registrations_delete&event_registration_id=' . $item['id'] . '&event_id=' . $_GET['event_id'] . '">Delete</a> | <a href="/wp-admin/?page=bsog_events_registrations_update&event_registration_id=' . $item['id'] . '&event_id=' . $_GET['event_id'] . '">Edit</a>';
        } else {
            return $item[$column_name];
        }
    }

}

And outside the class there is function and calling prepare_method. COde is as follows

function additions() {

    global $wpdb;
    $order_by = "";
    $order = "";
    $event_id = $_GET['event_id'];
    //$msg = $_GET['msg'];
    if (isset($_GET['orderby'])) {
        $order_by = "ORDER BY " . $_GET['orderby'];
    }
    if (isset($_GET['order'])) {
        $order = $_GET['order'];
    }

    $event = get_post($event_id);
    $table_name_reg = $wpdb->prefix . 'events_registrations';
    $table_name_user = $wpdb->prefix . 'users';
    $query = "SELECT * FROM `$table_name_reg` AS reg JOIN `$table_name_user` AS u ON `reg`.`user_id` = u.`ID` WHERE `reg`.`event_id`=%d $order_by $order";
    $query = $wpdb->prepare($query, [$event_id]);
    $additions = $wpdb->get_results($query, 'ARRAY_A');
    $myListTable = new My_List_Table();
    $myListTable->prepare_items($additions);




    if ($wpdb->num_rows > 0) {
        $i = 1;
        include 'views/additions.php';
    } else {
        echo '<div class="wrap"><p>No followers</p></div>';
    }


    die(0);
}

What is the cause of this error and how can I resolve it?

2

Answers


  1. You get the error because of the line of $myListTable->prepare_items($additions);. You pass $additions While your function is not supporting a parameter:

        public function prepare_items() {
            $columns = $this->get_columns();
            $hidden = array();
            $sortable = $this->get_sortable_columns();
            $this->_column_headers = array($columns, $hidden, $sortable);
            $this->items = $registrations;
        }
    

    and the base function does not support a parameter either:

        public function prepare_items() {
            die( 'function WP_List_Table::prepare_items() must be overridden in a subclass.' );
        }
    

    See https://github.com/WordPress/WordPress/blob/master/wp-admin/includes/class-wp-list-table.php

    EDIT

    I was asked in the comment section about a possible way to be able to use $additions inside prepare_items. Basically one can do something like this:

    class My_Cutsom_Table extends WP_List_Table {
        //...
        //This will store the additions you initially wanted to pass
        protected $additions;
        //Setter for additions
        public function setAdditions($additions) {
            $this->additions = $additions; return $this;
        }
        //Getter for additions
        public function getAdditions() {
            return $this->additions;
        }
        //...
        public function prepare_items() {
            //Your code here, you can get the additions via $this->getAdditions()
        }
    }
    

    Usage:

        $myListTable = new My_List_Table();
        $myListTable->setAdditions($additions);
        $myListTable->prepare_items();
    
    Login or Signup to reply.
  2. I have an example code from the plugin i have written for customer report..(hope it helps)

    Here, $udata is table heading names…

         $udata = ['Name', 'ID', 'Role',
                 'Orders Received',
                 'Orders Completed',
                 'Total Revenue ($)'];
    
           $createTbObj = new Create_WP_Custom_Table_List_Customer($udata);
           $createTbObj->prepare_items();
           $createTbObj->display();
    
    
    
    require_once( plugin_dir_path( __FILE__ ) . 'includes/class/class-main-wp-list-table.php' );
    
    class Create_WP_Custom_Table_List_Customer extends WP_List_Table_copy {
    
        function __construct($udata){
            global $status, $page;
            parent::__construct(array(
                'singular'  => 'report_cs_order_info',
                'plural'    => 'report_cs_order_infos',
                'name' => $udata[0],
                'cid' => $udata[1],
                'role' => $udata[2],
                'order_pr' => $udata[3],
                'order_cc' => $udata[4],
                'total_sr' => $udata[5],
                'ajax'      => false
            ) );
          }
    
        function column_default($item, $column_name){
            switch($column_name){
                case 'cs_name':
                case 'cs_id':
                case 'cs_role':
                case 'orders_placed':
                case 'orders_completed':
                case 'total_orders_cost':
                    return $item[$column_name];
                default:
                    return print_r($item,true);
            }
        }
    
        function column_cb($item){
            return sprintf(
                '<input type="checkbox" name="%1$s[]" value="%2$s" />',
                $this->_args['singular'],
                $item['ID']
            );
        }
    
        function get_columns(){
            $columns = array(
                'cb'        => '<input type="checkbox" />',
                'cs_name' => $this->_args['name'],
                'cs_id' =>  $this->_args['cid'],
                'cs_role' =>  $this->_args['role'],
                'orders_placed' => $this->_args['order_pr'],
                'orders_completed' => $this->_args['order_cc'],
                'total_orders_cost' => $this->_args['total_sr']
            );
            return $columns;
        }
    
        function get_sortable_columns() {
            $sortable_columns = array(
                'cs_name' => array('cs_name',false),
                'cs_id' => array('cs_id',false),
                'cs_role' => array('cs_role',false),
                'orders_placed' => array('orders_placed',false),
                'orders_completed' => array('orders_completed',false),
                'total_orders_cost' => array('total_orders_cost',false)
            );
            return $sortable_columns;
        }
    
        function prepare_items() {
            global $wpdb, $objcus;
    
            $per_page = 15; // no of items displayed in table (each page)...
            $columns = $this->get_columns();
            $hidden = array();
            $sortable = $this->get_sortable_columns();
            $this->_column_headers = array($columns, $hidden, $sortable);
    
            // data for table...
              $data = get_data_for_prepare_items();
    
            function usort_reorder($a,$b){
                    $filterx = $_REQUEST['orderby'];
    
                    $orderby = 'total_orders_cost';
                    $order = 'desc';
                    $result = strnatcmp($a[$orderby], $b[$orderby]);
    
                    if ( !empty($filterx) ) {
                    if ($filterx == 'cs_name'):
                     $orderby = (!empty($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : $filterx;
                     $order = (!empty($_REQUEST['order'])) ? $_REQUEST['order'] : 'asc';
                     $result = strnatcmp($a[$orderby], $b[$orderby]);
                    elseif ($filterx == 'cs_id'):
                      $orderby = (!empty($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : $filterx;
                      $order = (!empty($_REQUEST['order'])) ? $_REQUEST['order'] : 'asc';
                      $result = strnatcmp($a[$orderby], $b[$orderby]);
                    elseif ($filterx == 'cs_role'):
                        $orderby = (!empty($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : $filterx;
                        $order = (!empty($_REQUEST['order'])) ? $_REQUEST['order'] : 'asc';
                        $result = strnatcmp($a[$orderby], $b[$orderby]);
                    elseif ($filterx == 'orders_placed'):
                            $orderby = (!empty($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : $filterx;
                            $order = (!empty($_REQUEST['order'])) ? $_REQUEST['order'] : 'asc';
                            $result = strnatcmp($a[$orderby], $b[$orderby]);
                    elseif ($filterx == 'orders_completed'):
                                $orderby = (!empty($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : $filterx;
                                $order = (!empty($_REQUEST['order'])) ? $_REQUEST['order'] : 'asc';
                                $result = strnatcmp($a[$orderby], $b[$orderby]);
                    elseif ($filterx == 'total_orders_cost'):
                            $orderby = (!empty($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : $filterx;
                            $order = (!empty($_REQUEST['order'])) ? $_REQUEST['order'] : 'asc';
                             $result = strnatcmp($a[$orderby], $b[$orderby]);
                   endif;
                 }
    
                    return ($order==='asc') ? $result : -$result;
            }
            usort($data, 'usort_reorder');
    
            $current_page = $this->get_pagenum();
            $total_items = count($data);
            $data = array_slice($data,(($current_page-1)*$per_page),$per_page);
            $this->items = $data;
    
            $this->set_pagination_args( array(
                'total_items' => $total_items,
                'per_page'    => $per_page,
                'total_pages' => ceil($total_items/$per_page)
            ) );
        }
    }
    

    Note from(wordpress codex):

    This class’s access is marked as private. That means it is not intended for use by plugin and theme developers as it is subject to change without warning in any future WordPress release.

    https://developer.wordpress.org/reference/classes/wp_list_table/

    So, always, make a local copy of wp table class.

    then change class name(something like below)

    class WP_List_Table {
    
    class WP_List_Table_copy {
    

    EDIT: i have added the sample data for prepare_items() below:

    just write a function and return the data for table as an array

    Note: Your keys should be same as on the inside.

    function get_data_for_prepare_items() {
    
      $data_for_table = Array();
    
      // run a loop...
    
      foreach($get_all_users as $user) {
    
        //...... some code.....
    
      $array_data_single = array(
         'ID' => $ix_inc,
         'cs_name' => $cname,
         'cs_id' => $id,
         'cs_role' => $crole,
         'orders_placed' => $total_orders,
         'orders_completed' => $ord_completed,
         'total_orders_cost' => $total_paid
      );
      array_push($data_for_table, $array_data_single);
    
    }
    
      return $data_for_table;
    }
    

    then in prepare_items()
    change the funtion name:

    // data for table...
    $data = get_data_for_prepare_items();
    

    Edit2:

    or you can do something like this:

    suppose your file name is my_class.php
    then in my_class.php

    /*** filename my_class.php ***/
    
    require_once( plugin_dir_path( __FILE__ ) . 'includes/class/class-main-wp-list-table.php' );
    
    class SomeData {
    
    public function data_prepare_items() {
    
      $data_for_table = Array();
    
      // run a loop...
    
     foreach($get_all_users as $user):
    
        //...... some code.....
    
      $array_data_single = array(
         'ID' => $ix_inc,
         'cs_name' => $cname,
         'cs_id' => $id,
         'cs_role' => $crole,
         'orders_placed' => $total_orders,
         'orders_completed' => $ord_completed,
         'total_orders_cost' => $total_paid
      );
      array_push($data_for_table, $array_data_single);
    
    endforeach;
    
      return $data_for_table;
    }
    
    }
    
    
    // create object.....
    $get_data = new SomeData();
    
    
    class Create_WP_Custom_Table_List_Customer extends WP_List_Table_copy {
    //.....
    
     // data for table...
     $data = $get_data->data_prepare_items();
    
    //.....
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search