对插件管理接口表中的条目进行排序时出现问题

时间:2012-06-28 作者:mattbd

我正在开发一个WordPress插件,它将在页面上显示一个可公开访问的公告栏。

我被要求使用WordPress管理界面添加从公告栏中删除现有帖子的方法,我使用this tutorial 有关创建表格以保存每个条目的详细信息的指导。

它可以显示表格并在页面之间移动,但排序有一个奇怪的错误。按每个列排序的超链接仅显示orderby参数中列名的第一个字符,因此破坏了此功能。

例如,按描述排序的链接是

http://example.com/wordpress/wp-admin/options-general.php?page=Noticeboard&orderby=d&order=desc

而且应该是

http://example.com/wordpress/wp-admin/options-general.php?page=Noticeboard&orderby=description&order=desc

... 这很有效。

现在,我看了一下wp-admin/includes/class-wp-list-table.php, 在print\\u column\\u headers方法中,问题似乎出现在line 679, 内容如下:

list( $orderby, $desc_first ) = $sortable[$column_key];
如果我做了var_dump 属于$sortable[$column_key], 我得到的值正好是我期望的值,在本例中是一个值为的字符串"title", 因为这是我想展示的第一个专栏。但是$orderby$desc_first"t""i", 看来是这样list() 正在治疗$sortable[$column_key] 作为array 返回前两个元素。

我假设这不是WordPress中的一个bug,因为我在用于开发目的的WordPress版本中找不到这样的bug,所以我认为最可能的解释是我在某个地方做错了什么。看起来我定义了get_sortable_columns method, 我应该传递一个数组,其中包含两个或多个值作为$sortable 关联数组。

以下是我为管理员编写的代码:

<?php
// Retrieve any recaptcha keys sent via POST
if($_POST[\'recaptcha_public_key\'])
{
    update_option(\'recaptcha_public_key\', $_POST[\'recaptcha_public_key\']);
}

if($_POST[\'recaptcha_private_key\'])
{
    update_option(\'recaptcha_private_key\', $_POST[\'recaptcha_private_key\']);
}

// Create a class for the post list table
class Post_List_Table extends WP_List_Table {
    /*
     * Constructor
     */
    function __construct() {
        parent::__construct( array(
            \'singular\'=> \'wp_list_post\',
            \'plural\' => \'wp_list_posts\',
            \'ajax\' => false
        ) );
    }

    function get_columns() {
        return $columns = array(
            \'title\'=>__(\'Title\'),
            \'description\'=>__(\'Description\'),
            \'submissionDate\'=>__(\'Date submitted\'),
            \'name\'=>__(\'Author name\'),
            \'email\'=>__(\'Author email\'),
            \'post_title\'=>__(\'Page this has been posted on\')
        );
    }

    public function get_sortable_columns() {
        return $sortable = array(
            \'title\'=>\'title\',
            \'description\'=>\'description\',
            \'submissionDate\'=>\'submissionDate\',
            \'name\'=>\'name\',
            \'email\'=>\'email\',
            \'post_title\'=>\'post_title\'
        );
    }

    function prepare_items() {
        global $wpdb, $_wp_column_headers;
        $screen = get_current_screen();

        // Prepare query
        $query = "SELECT ".$wpdb->prefix."noticeboard_posts.title, ".$wpdb->prefix."noticeboard_posts.description, ".$wpdb->prefix."noticeboard_posts.submissionDate, ".$wpdb->prefix."noticeboard_author.name, ".$wpdb->prefix."noticeboard_author.email, ".$wpdb->prefix."posts.post_title FROM ".$wpdb->prefix."noticeboard_posts INNER JOIN ".$wpdb->prefix."noticeboard_author ON ".$wpdb->prefix."noticeboard_posts.authorId = ".$wpdb->prefix."noticeboard_author.authorId INNER JOIN ".$wpdb->prefix."posts ON ".$wpdb->prefix."noticeboard_posts.pageID = ".$wpdb->prefix."posts.ID";

        // Parameters that are going to be used to order the result
        $orderby = !empty($_GET["orderby"]) ? mysql_real_escape_string($_GET["orderby"]) : \'ASC\';
        $order = !empty($_GET["order"]) ? mysql_real_escape_string($_GET["order"]) : \'\';
        if(!empty($orderby) & !empty($order)){ $query.=\' ORDER BY \'.$orderby.\' \'.$order; }

        // Parameters for pagination
        $totalitems = $wpdb->query($query);

        // How many to display per page?
        $perpage = 5;

        // Which page is this?
        $paged = !empty($_GET["paged"]) ? mysql_real_escape_string($_GET["paged"]) : \'\';

        // Page number
        if(empty($paged) || !is_numeric($paged) || $paged<=0 ){ $paged=1; }

        // How many pages do we have in total?
        $totalpages = ceil($totalitems/$perpage);

        //adjust the query to take pagination into account
        if(!empty($paged) && !empty($perpage)){
            $paged = (int)$paged;
            $offset = ($paged - 1) * $perpage;
            $query .=\' LIMIT \'.(int)$offset.\', \'.(int)$perpage;
        }

        // Register the pagination
        $this->set_pagination_args( array(
            "total_items" => $totalitems,
            "total_pages" => $totalpages,
            "per_page" => $perpage,
        ) );

        // The pagination links are automatically built according to those parameters

        // Register the columns
        $columns = $this->get_columns();
        $hidden = array();
        $sortable = $this->get_sortable_columns();
        $this->_column_headers = array($columns, $hidden, $sortable);

        // Fetch the items
        $this->items = $wpdb->get_results($query);
    }

    function display_rows() {

        // Get the records registered in the prepare_items method
        $records = $this->items;

        // Get the columns registered in the get_columns and get_sortable_columns methods
        list ( $columns, $hidden ) = $this->get_column_info();

        // Loop for each record
        if(!empty($records)){foreach($records as $rec){

            // Open the line
            echo \'<tr id="record_\'.$rec->postId.\'">\';
            foreach ( $columns as $column_name => $column_display_name ) {

                // Style attributes for each column
                $class = "class=\'$column_name column-$column_name\'";
                $style = "";
                if ( in_array( $column_name, $hidden ) ) $style = \' style="display:none;"\';
                $attributes = $class . $style;

                //Display the cell
                switch ( $column_name ) {
                case "title": echo \'<td \'.$attributes.\'><strong>\'.stripslashes($rec->title).\'</strong></td>\';  break;
                case "description": echo \'<td \'.$attributes.\'>\'.stripslashes($rec->description).\'</td>\'; break;
                case "submissionDate": echo \'<td \'.$attributes.\'>\'.stripslashes(date("j F Y", strtotime($rec->submissionDate))).\'</td>\'; break;
                case "name": echo \'<td \'.$attributes.\'>\'.$rec->name.\'</td>\'; break;
                case "email": echo \'<td \'.$attributes.\'>\'.$rec->email.\'</td>\'; break;
                case "post_title": echo \'<td \'.$attributes.\'>\'.$rec->post_title.\'</td>\'; break;
            }
        }

        //Close the line
        echo \'</tr>\';
    }}
    }
}
?>
<div class="wrap">
    <h2>Noticeboard administration</h2>
    <form name="notification_admin_form" method="post" action="<?php echo str_replace( \'%7E\', \'~\', $_SERVER[\'REQUEST_URI\']); ?>">
        <p><label>reCAPTCHA public key <input type="text" name="recaptcha_public_key" size="60" value="<?php echo get_option(\'recaptcha_public_key\', \'\');?>" /></label></p>
        <p><label>reCAPTCHA private key <input type="text" name="recaptcha_private_key" size="60" value="<?php echo get_option(\'recaptcha_private_key\', \'\');?>" /></label></p>
        <input type="submit" name="Submit" value="Update reCAPTCHA key details" />
    </form>
<h2>Edit posts</h2>

<?php
//Our class extends the WP_List_Table class, so we need to make sure that it\'s there
if(!class_exists(\'WP_List_Table\')){
    require_once( ABSPATH . \'wp-admin/includes/class-wp-list-table.php\' );
}

//Prepare Table of elements
$wp_post_table = new Post_List_Table();
$wp_post_table->prepare_items();

//Table of elements
$wp_post_table->display();
?>
</div>
你知道我哪里出了问题吗?

1 个回复
最合适的回答,由SO网友:mattbd 整理而成

在凯撒告诉我抄本上的适当条目,特别是http://codex.wordpress.org/Class_Reference/WP_List_Table#Notice:_Sortable_Columns 但我还是错过了。问题在于get\\u sortable\\u columns方法,它应该如下所示:

    public function get_sortable_columns() {
    return $sortable = array(
        \'title\'=>array(\'title\',true),
        \'description\'=>array(\'description\',true),
        \'submissionDate\'=>array(\'submissionDate\',true),
        \'name\'=>array(\'name\',true),
        \'email\'=>array(\'email\',true),
        \'post_title\'=>array(\'post_title\',true)
    );
}
我猜我使用的教程一定是不正确的。

结束

相关推荐