Wordpress Plugin Boilerplate - 如何正确使用 WP_List_Table 类?

Posted

技术标签:

【中文标题】Wordpress Plugin Boilerplate - 如何正确使用 WP_List_Table 类?【英文标题】:Wordpress Plugin Boilerplate - How to use WP_List_Table class correctly? 【发布时间】:2021-06-08 23:23:38 【问题描述】:

我使用Wordpress Plugin Boilerplate 作为我自己插件的基础。在管理区域中,我打算使用 Wordpress 的 WP_List_Table 类来显示数据。我知道我必须创建自己的子类才能访问它。这样做不是问题,但是我收到以下错误:

致命错误:未捕获的错误:调用成员函数 render_screen_reader_content() on

在研究过程中,我发现了一些具有相同问题的案例(1、2),但没有一个解决方案适用于我的案例。

使用样板的结构,我在包含文件夹内的文件中创建了子类:

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

if ( !class_exists( 'Hedwig_tables' ) ) 
    class Hedwig_tables extends WP_List_Table 
        private array $hd_columns;
        private array $hd_data;
        private array $hd_hidden;
        private array $hd_sortable;
        private array $hd_column_names;

        public function __construct() 
            //parent::__construct();
        

        public function set_column_names(array $column_names) 
            $this->hd_column_names = $column_names;
        

        public function set_columns(array $columns) 
            $this->hd_columns = $columns;
        

        public function set_data(array $data) 
            $this->hd_data = $data;
        

        public function set_hidden(array $hidden) 
            $this->hd_hidden = $hidden;
        

        public function set_sortable(array $sortable) 
            $this->hd_sortable = $sortable;
        

        public function prepare_items() 
            $this->_column_headers = array($this->hd_columns, $this->hd_hidden, $this->hd_sortable);
            $this->items = $this->hd_data;
        

        public function column_default( $item, $column_name ): mixed 
            if (in_array($column_name, $this->hd_column_names)) 
                return $item[ $column_name ];
            
            return print_r($item, true);
        
    

然后将该文件加载到样板文件的 load_dependencies() 函数中,该函数位于包含文件夹内的 class-plugin-name.php 中。

在样板文件的 class-plugin-name-admin.php(在 admin 文件夹内)中,我创建了一个生成管理菜单条目的函数。

    public function add_hedwig_page() 

        $this->plugin_screen_hook_suffix = add_menu_page(
            __( 'Hedwig Settings', 'Hedwig' ),
            __( 'Hedwig Settings', 'Hedwig' ),
            'manage_options',
            $this->plugin_name,
            array( $this, 'hedwig_admin_display_page' ),
            'dashicons-buddicons-activity'
        );

        $this->plugin_screen_hook_suffix = add_submenu_page(
            $this->plugin_name,
            __( 'Hedwig Settings', 'Hedwig' ),
            __( 'Hedwig Settings', 'Hedwig' ),
                'manage_options',
            $this->plugin_name,
            array( $this, 'hedwig_admin_display_page' )
        );

    public function hedwig_admin_display_page() 
        include_once 'partials/hedwig-admin-display.php';
    

在 display.php 中调用了我在 class-plugin-name-admin.php 中创建的函数,该函数为 WP_List_Table 的子类创建对象。

    public function get_data() 
        $hedwig_list_table = new Hedwig_tables();
        $sql = "SELECT id, value FROM y";
        $results = $this->wpdb->get_results($sql, ARRAY_A);
        
        if (count($results)<=0) 
            ?>
            <div class="hedwig-msg-error"><?php _e('No data found.','Hedwig');?></div>
            <?php
            return false;
        
        
        $hedwig_list_table->set_columns(
            array(
                'id' => __('ID','Hedwig'),
                'value' => __('Art','Hedwig')
            )
        );
        $hedwig_list_table->set_column_names(
            array(
                'id',
                'value'
            )
        );
        $hedwig_list_table->set_data($results);
        $hedwig_list_table->set_hidden(array());
        $hedwig_list_table->set_sortable(array());
        $hedwig_list_table->prepare_items();
        $hedwig_list_table->display();
        
        return true;
    

根据我前面提到的研究,问题一定是在创建子类的对象时(see this answer)。我尝试在不同的地方使用add_actions()(在管理类的__construct 上,在plugin-name.php 的run() 函数内尝试在生成菜单项后加载它或将类加载为$GLOBALS . 我想出的一切都失败了。我曾经创建一些没有样板的较小插件,但在这个项目中,我实际上想切换到这个 OOP 并以这种方式启动新插件。

更新 #1

仍然没有解决方案,但我偶然发现了看起来很有希望的another solution。但是,在创建用于初始化子类的菜单项时使用函数也不起作用。

public function add_hedwig_page() 

    $this->plugin_screen_hook_suffix = add_menu_page(
        __( 'Hedwig Settings', 'Hedwig' ),
        __( 'Hedwig Settings', 'Hedwig' ),
        'manage_options',
        $this->plugin_name,
        function()  
                    $this->hedwig_list_table = new Hedwig_tables();
                    $this->hedwig_admin_display_page();
        ,
        'dashicons-buddicons-activity'
    );

    $this->plugin_screen_hook_suffix = add_submenu_page(
        $this->plugin_name,
        __( 'Hedwig Settings', 'Hedwig' ),
        __( 'Hedwig Settings', 'Hedwig' ),
            'manage_options',
        $this->plugin_name,
        function()  
                    $this->hedwig_list_table = new Hedwig_tables();
                    $this->hedwig_admin_display_page();
        
    );

public function hedwig_admin_display_page() 
    include_once 'partials/hedwig-admin-display.php';

【问题讨论】:

【参考方案1】:

您不应该像自定义类一样加载此类,因为这是核心类的扩展,并且它有更多依赖项可以依赖。不要使用add_action$GLOBALS 来初始化这个类。

如果你在includes文件夹内class-plugin-name.php的样板文件的load_dependencies()函数中加载它,它将被过早实例化,并且无法正常运行。

相反,仅在需要时调用它,在您将用于输出该页面标记的 partials/hedwig-admin-display.php 中。

这样的东西应该在你的例子中起作用:

<?php $table = new Hedwig_tables(); ?>

<h1>Hedwig_tables</h1>
    <div class="wrap">
        <div id="poststuff">
            <div id="post-body" class="metabox-holder">
                <div id="post-body-content">
                    <div class="meta-box-sortables ui-sortable">
                        <?php $table->prepare_items();?>
                        <form method="get">
                            <?php $table->display(); ?>
                        </form>
                    </div>
                </div>
            </div>
            <br class="clear">
        </div>
    </div>

【讨论】:

以上是关于Wordpress Plugin Boilerplate - 如何正确使用 WP_List_Table 类?的主要内容,如果未能解决你的问题,请参考以下文章

WordPress plugin 代码注入漏洞(CVE-2022-24663)

WordPress plugin 代码注入漏洞(CVE-2022-24663)

php 在wordpress函数中选中Use cache Plugin

markdown 链接,片段,提醒,收集点作为重新访问WordPress插件开发期间的笔记#WordPress #Plugin #PHP #Refere

php 添加对与Woocommerce Plugin一起使用的Wordpress主题的支持

PHP [PLUGIN]第一次访问的Wordpress特定模板(并写一个cookie)