Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call to undefined function convert_to_screen()

Tags:

php

wordpress

I am developing a plugin where i did have to extend the class WP_List_Table. I have extended the class within my plugin-file (I don't know if this is the right way to do this?) and included WP_List_Table like this:

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

Then comes the code for extending the class and then I do create an instance of my table class like this:

<?php

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


 Class Wp_Ban_User extends WP_List_Table
 {

    public function __construct()
    {
             add_action('admin_menu',array($this,'WBU_adminMenu'));
             parent::__construct( array(
                  'singular'=> 'wp_list_text_link', //Singular label
                  'plural' => 'wp_list_test_links', //plural label, also this well be one of the table css class
                  'ajax'   => false //We won't support Ajax for this table
                  ) );      
            $this->prepare_items();
            $this->display();           

    }
     function get_columns() {
        $columns = array(
            'id'    => 'ID',
            'user_login'     => 'User Name',
            'user_email'   => 'User Email'            
        );
        return $columns;
    }


    function column_default( $item, $column_name ) {
        switch( $column_name ) {
            case 'id':
            case 'user_login':
            case 'user_email':

                return $item[ $column_name ];
            default:
                return print_r( $item, true ) ;
        }
    }
    function prepare_items() {

        $example_data = array(
                array(
                        'id'        => 1,
                        'user_login'     => 'vasim',
                        'user_email'    => '[email protected]'                        
                ),
                array(
                        'id'        => 2,
                        'user_login'     => 'Asma',
                        'user_email'    => '[email protected]'                        
                ),
                array(
                        'id'        => 3,
                        'user_login'     => 'Nehal',
                        'user_email'    => '[email protected]'                        
                ),
            );

        $columns = $this->get_columns();
        $hidden = array();
        $sortable = $this->get_sortable_columns();
        $this->_column_headers = array($columns, $hidden, $sortable);
        $this->items = $example_data;
    }

    public function WBU_adminMenu()
    {
            add_menu_page( 'Currently Logged In User', 'Banned User', 'manage_options', 'ban_admin_init', array($this,'ban_admin_init'));
    }
function ban_admin_init(){
        global $wpdb;

        $sql="SELECT * from {$wpdb->prefix}users";
        $sql_result=$wpdb->get_results($sql,'ARRAY_A');
        print_r($sql_result);
        //$this->items=$sql_result;     
    }

}

 global $Obj_Wp_Ban_User;

 $Obj_Wp_Ban_User=new Wp_Ban_User();

But when i do this, i do get this error:

Fatal error: Call to undefined function convert_to_screen() in D:\xampp\htdocs\developplugin\wp-admin\includes\class-wp-list-table.php on line 143

I did some research but did not understand how to fix it.

Does anybody knows how to fix this?

Thanks for your help!

Best regards.

like image 719
Vasim Shaikh Avatar asked Nov 29 '16 13:11

Vasim Shaikh


Video Answer


2 Answers

Sorry for my bad english, im french.

I have found the problem. Your class corrected (see at the bottom of code):

<?php
/*
Plugin Name: My List Table Example
*/
 if ( ! class_exists( 'WP_List_Table' ) ) {
    require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
}


Class Wp_Ban_User extends WP_List_Table
{

    public function __construct()
    {
             parent::__construct( array(
                  'singular'=> 'wp_list_text_link', //Singular label
                  'plural' => 'wp_list_test_links', //plural label, also this well be one of the table css class
                  'ajax'   => false //We won't support Ajax for this table
                  ) );      
            $this->prepare_items();
            $this->display();           

    }

    function get_columns() {
        $columns = array(
            'id'    => 'ID',
            'user_login'     => 'User Name',
            'user_email'   => 'User Email'            
        );
        return $columns;
    }

    function column_default( $item, $column_name ) {
        switch( $column_name ) {
            case 'id':
            case 'user_login':
            case 'user_email':

                return $item[ $column_name ];
            default:
                return print_r( $item, true ) ;
        }
    }

    function prepare_items() {

        $example_data = array(
                array(
                        'id'        => 1,
                        'user_login'     => 'vasim',
                        'user_email'    => '[email protected]'                        
                ),
                array(
                        'id'        => 2,
                        'user_login'     => 'Asma',
                        'user_email'    => '[email protected]'                        
                ),
                array(
                        'id'        => 3,
                        'user_login'     => 'Nehal',
                        'user_email'    => '[email protected]'                        
                ),
            );

        $columns = $this->get_columns();
        $hidden = array();
        $sortable = $this->get_sortable_columns();
        $this->_column_headers = array($columns, $hidden, $sortable);
        $this->items = $example_data;
    }

}


// Render your admin menu outside the class
function WBU_adminMenu()
{
    add_menu_page( 'Currently Logged In User', 'Banned User', 'manage_options', 'render_admin_page', 'render_admin_page');
}

// Create your menu outside the class
add_action('admin_menu','WBU_adminMenu');

// Render your page outside the class
function render_admin_page(){
    global $wpdb;

    $Obj_Wp_Ban_User=new Wp_Ban_User();
    $Obj_Wp_Ban_User->prepare_items();

    $sql="SELECT * from {$wpdb->prefix}users";
    $sql_result=$wpdb->get_results($sql,'ARRAY_A');
    print_r($sql_result);    
}

This simple : For resolve the error Call to undefined function convert_to_screen() you need to :

  • Add the menu outside the class
  • Add the admin_menu action outside the class
  • Render your admin page outside the class

After 3 days, it's work for me !

like image 113
Thomas Philibert Avatar answered Oct 21 '22 04:10

Thomas Philibert


I had a working prototype of a class very similar to yours. I decided to conform to the WordPress best practices structure for my plugin, so I downloaded one of the suggested boilerplates and began adapting my code to the boilerplate class based structure. When I did, I ran into the same problem as you. Since I had a working example that created the admin page extended from WP_List_Table inside a class, I knew the issue wasn't adding the menu page inside the class. The issue is that the constructor

Class Wp_Ban_User extends WP_List_Table {

public function __construct()
{
         add_action('admin_menu',array($this,'WBU_adminMenu'));
         parent::__construct( array(...

is being called be before WordPress has finished initializing. I did some digging to find out what the initialization sequence is and came across this WordPress action_hook sequence list. I tried creating my equivalent to your Wp_Ban_User class using the wp_loaded action hook {This hook is fired once WP, all plugins, and the theme are fully loaded and instantiated.}, but it still crashed. A little further in the sequence is the wp action hook {Fires once the WordPress environment has been set up} and I thought it worked because my plugin didn't crash. But wp isn't a real action hook, so that meant my classes weren't being initialized.

So, my simple code change

function run_admin_page_init() {
    $myAdminPage = new Wp_Ban_User();
}
add_action( 'wp', 'run_admin_page_init' );

rather than having to hack up my class looked promising, but was a red herring.

Still confident that the problem is a sequencing issue during initialization, I finally tracked it down to the following fix (which actually worked). In the class that added my admin menu entry I had:

function __construct() {
    $this->pageTable = new WBU_adminMenu();
    add_action( 'admin_menu', [ $this, 'addAdminMenu' ] );
}
/**
 * Adds the Manage Mailing List label to the WordPress Admin Sidebar Menu
 */
public function addAdminMenu() {
    $hook = add_menu_page(
        'Page Title',
        'Menu Name',
        'manage_options',
        'menu_slug',
        [ $this, 'adminLayout' ] );

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

but I changed it to:

function __construct() {
    add_action( 'admin_menu', [ $this, 'addAdminMenu' ] );
}

/**
 * Adds the Manage Mailing List label to the WordPress Admin Sidebar Menu
 */
public function addAdminMenu() {
    $this->pageTable = new WBU_adminMenu();
    $hook = add_menu_page(
        'Page Title',
    ...

which deferred creating the child class of WP_LIST_TABLE until after the basic admin panel menu structure is in place.

I'm sure you've moved on to bigger and better projects and the hair you pulled out in frustration trying to track this down mystery has grown back in the two years that have elapsed since you cast your question into the community, but I posted my solution just in case someone else runs into the problem.

like image 1
One In a Million Apps Avatar answered Oct 21 '22 04:10

One In a Million Apps