在管理员的用户列表中按自定义帖子类型显示用户的帖子计数?


9

我试图弄清楚如何进入/wp-admin/users.php管理页面以创建自定义列,以显示用户在WPHonors.com上自定义帖子类型所拥有的帖子数量

我为此创建了一张票,但@nacin解释了为什么代替插件做更多的工作。

我一直无法找到一种方法来操纵用户表的输出,因此我可以为每个用户的CPT帖子数添加自定义列。这可能与@nacin提出的问题有关,帖子计数数字将链接到什么。对于用户当前拥有的“帖子”帖子数,它链接到帖子管理页面,显示该用户的所有帖子(/wp-admin/edit.php?author=%author_id%)。

如果我将其链接到某处,它将是:

/wp-admin/edit.php?post_type=%post_type%&author=%author_id%

我想,如果那在某种程度上甚至可行。但我什至不一定需要将其链接到任何地方。我最想显示的是每个人的CPT帖子数,其中包含600用户和300+不同4自定义帖子类型的帖子总数。管理员只是可以提交'post'帖子的人员,因此用户页面中的该列无用。

Answers:


10

这是Mike的教程答案的扩展。我添加了到列出的类型的链接,因此您可以单击一个,然后直接转到该作者的该类型所有帖子的列表,这需要一个附加变量$counts和某些附加输出$custom_column[]

add_action('manage_users_columns','yoursite_manage_users_columns');
function yoursite_manage_users_columns($column_headers) {
    unset($column_headers['posts']);
    $column_headers['custom_posts'] = 'Assets';
    return $column_headers;
}

add_action('manage_users_custom_column','yoursite_manage_users_custom_column',10,3);
function yoursite_manage_users_custom_column($custom_column,$column_name,$user_id) {
    if ($column_name=='custom_posts') {
        $counts = _yoursite_get_author_post_type_counts();
        $custom_column = array();
        if (isset($counts[$user_id]) && is_array($counts[$user_id]))
            foreach($counts[$user_id] as $count) {
                $link = admin_url() . "edit.php?post_type=" . $count['type']. "&author=".$user_id;
                // admin_url() . "edit.php?author=" . $user->ID;
                $custom_column[] = "\t<tr><th><a href={$link}>{$count['label']}</a></th><td>{$count['count']}</td></tr>";
            }
        $custom_column = implode("\n",$custom_column);
        if (empty($custom_column))
            $custom_column = "<th>[none]</th>";
        $custom_column = "<table>\n{$custom_column}\n</table>";
    }
    return $custom_column;
}

function _yoursite_get_author_post_type_counts() {
    static $counts;
    if (!isset($counts)) {
        global $wpdb;
        global $wp_post_types;
        $sql = <<<SQL
        SELECT
        post_type,
        post_author,
        COUNT(*) AS post_count
        FROM
        {$wpdb->posts}
        WHERE 1=1
        AND post_type NOT IN ('revision','nav_menu_item')
        AND post_status IN ('publish','pending', 'draft')
        GROUP BY
        post_type,
        post_author
SQL;
        $posts = $wpdb->get_results($sql);
        foreach($posts as $post) {
            $post_type_object = $wp_post_types[$post_type = $post->post_type];
            if (!empty($post_type_object->label))
                $label = $post_type_object->label;
            else if (!empty($post_type_object->labels->name))
                $label = $post_type_object->labels->name;
            else
                $label = ucfirst(str_replace(array('-','_'),' ',$post_type));
            if (!isset($counts[$post_author = $post->post_author]))
                $counts[$post_author] = array();
            $counts[$post_author][] = array(
                'label' => $label,
                'count' => $post->post_count,
                'type' => $post->post_type,
                );
        }
    }
    return $counts;
}

10

假设我理解了这个问题,您需要做的是将两个钩子关联到与admin管理页面的列标题和列值相关的两个钩子中。他们是'manage_{$type}_columns''manage_{$type}_custom_column'凡在你的用例{$type}users

'manage_users_columns'挂钩

第一个很简单,它使您可以指定列标题以及可用列。WordPress对“ Posts”列的值进行硬编码,因此,由于您要更改它,我们只需要使用删除它,unset()然后添加具有相同标题但标识符为的新列'custom_posts'

add_action('manage_users_columns','yoursite_manage_users_columns');
function yoursite_manage_users_columns($column_headers) {
  unset($column_headers['posts']);
  $column_headers['custom_posts'] = 'Posts';
  return $column_headers;
}

'manage_users_custom_column'挂钩

接下来,您需要使用'manage_users_custom_column'仅对非标准列调用的钩子。我们进行测试$column_name=='custom_posts'以使我们的代码更健壮,以防将来我们添加新的用户列,然后从我编写的函数中获取用户发布类型计数,_yoursite_get_author_post_type_counts()这将在接下来的内容中进行讨论。然后,我尝试了几种格式化该格式的方法,但认为HTML <table>最合适(因为它数据表)。如果表格对您不起作用,我认为您将能够轻松地生成不同的标记:

add_action('manage_users_custom_column','yoursite_manage_users_custom_column',10,3);
function yoursite_manage_users_custom_column($custom_column,$column_name,$user_id) {
  if ($column_name=='custom_posts') {
    $counts = _yoursite_get_author_post_type_counts();
    $custom_column = array();
    if (isset($counts[$user_id]) && is_array($counts[$user_id]))
      foreach($counts[$user_id] as $count)
        $custom_column[] = "\t<tr><th>{$count['label']}</th>" .
                                 "<td>{$count['count']}</td></tr>";
    $custom_column = implode("\n",$custom_column);
  }
  if (empty($custom_column)) 
    $custom_column = "No Posts!";
  else 
    $custom_column = "<table>\n{$custom_column}\n</table>";
  return $custom_column;
}

按帖子类型获取每个用户/作者的帖子数

最后,作者/用户按帖子类型检索帖子计数。通常,WP_Query()在帖子上运行查询时,我会尽量坚持使用,但是此查询将需要使用许多其他挂钩,因此看起来“顽皮”并一并完成似乎更容易。

我省略了任何$post->post_typeis 'revision''nav_menu_item'但留在中的帖子'attachments'。您可能会发现更好地是显式地包含所需的帖子类型,而不是排除我所做的少数几种。

我也$post->post_status只过滤了'publish''pending'。如果您还想包含'future''private'和/或'draft'需要在代码中进行更改。

对于每次页面加载,我只调用_yoursite_get_author_post_type_counts()一次此函数,然后将其存储到静态变量中,而不是为每个用户调用。我存储在一个由作者/用户ID索引的数组中,该数组包含元素中具有Post Type名称的数组'label',当然还有同名元素中的计数:

function _yoursite_get_author_post_type_counts() {
  static $counts;
  if (!isset($counts)) {
    global $wpdb;
    global $wp_post_types;
    $sql = <<<SQL
SELECT
  post_type,
  post_author,
  COUNT(*) AS post_count
FROM
  {$wpdb->posts}
WHERE 1=1
  AND post_type NOT IN ('revision','nav_menu_item')
  AND post_status IN ('publish','pending')
GROUP BY
  post_type,
  post_author
SQL;
    $posts = $wpdb->get_results($sql);
    foreach($posts as $post) {
      $post_type_object = $wp_post_types[$post_type = $post->post_type];
      if (!empty($post_type_object->label))
        $label = $post_type_object->label;
      else if (!empty($post_type_object->labels->name))
        $label = $post_type_object->labels->name;
      else
        $label = ucfirst(str_replace(array('-','_'),' ',$post_type));
      if (!isset($counts[$post_author = $post->post_author]))
        $counts[$post_author] = array();
      $counts[$post_author][] = array(
        'label' => $label,
        'count' => $post->post_count,
        );
    }
  }
  return $counts;
}

结果界面

这就是应用于我的WordPress 3.0.1测试安装的样子:


(来源:mikeschinkel.com

下载完整代码

您可以从Gist 下载完整代码:

您可以选择将此代码复制到主题functions.php文件中,或将该文件存储在插件中。

希望这可以帮助!


好吧,那很容易。您所要做的就是说它使用了'manage _ {$ type} _columns'和'manage _ {$ type} _custom_column',其中$ type = users,我可以从那里找出其余的内容。我感觉确实如此,但是我检查了一下却没有看到用户。其余的很容易。感谢您为此付出的巨大努力,我肯定会对WPHonors投票(因为我已经拥有了)goo.gl/CrSi 非常感谢:D
jaredwilli 2010年

1
@jaredwilli-当然可以。但是WordPress Answers的目标是提供远远超出第一个提出要求的人的答案。这就是为什么即使您只需要一些信息,我也要写得很深入,而其他人可能对这种方法来说是全新的。试图帮助两者。哦,谢谢您在网站上发表的评论(有机会我可以改变这张照片吗?:)
MikeSchinkel 2010年

是的,这就是为什么我没有阻止您仅仅告诉我我需要使用的钩子的原因。我知道我不会是唯一一个对此有需求的人,所以一切都很好。
jaredwilli

哦,对不起,我当然会的。我因为商店站点Im建筑定制的自定义帖子类型而分心。我不认为您找到了一种方法,可以将帖子计数链接到显示针对其作者的帖子的edit.php页面?可能需要将其内置到我的CPT中。
jaredwilli

@jaredwilli-啊,是的,但是看起来像@somatic帮了您,对吗?
MikeSchinkel 2010年

2

以下是sorich87答案的一个变体,因为我无法让他工作,并且我想自动支持多种类型:

function my_manage_users_custom_column($output = '', $column, $user_id) {
    global $wpdb;
    $result = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = '$column' AND post_author = $user_id");
    return '<a href="' . admin_url("edit.php?post_type=$column&author=$user_id") . '">' . $result . '</a>';
}
add_filter('manage_users_custom_column', 'my_manage_users_custom_column', 10, 3);

function my_manage_users_columns($columns) {
    // create columns for each type, make sure to use the post_type slug
    $columns['animals'] = 'Animals Count';
    $columns['plants'] = 'Plants Count';
    $columns['insects'] = 'Insect Count';
    return $columns;
}
add_filter('manage_users_columns', 'my_manage_users_columns');

我继续阅读,get_posts_by_author_sql()以及如何为您构造WHERE语句,但是我得到的结果始终是“ 1 = 0”。因此,我只写出了其余的SQL语句,这get_posts_by_author_sql()只是节省了您编写两个位的麻烦:帖子类型和作者:

"SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = 'your_custom_type' AND post_author = $user_id"

这种方法效果也很好,并且会根据需要添加任意多的列,但是每个列都会占用水平空间,而Mike的教程将为自定义帖子类型添加一列,然后将其列为该行中的表格。相同的信息,不同的可视化。迈克(Mike)的方法可能更适合大量类型,因为它建立了一个精简的垂直列表(并且如果不为空,则仅显示计数项目),而sorich87的方法则适用于较小的数量,因为水平列空间有限。

别忘了您可以在查询中添加“ post_status = publish”以仅返回已发布的项目,因为该示例当前返回所有帖子...


大!get_posts_by_author_sql( $column, true, $user_id );应该构造where语句。
sorich87

1

以下将添加它:

function my_manage_users_custom_column($output = '', $column_name, $user_id) {
    global $wpdb;

    if( $column_name !== 'post_type_count' )
        return;

    $where = get_posts_by_author_sql( 'post_type', true, $user_id );
    $result = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts $where" );

    return '<a href="' . admin_url("edit.php?post_type=post_type&author=$user_id") . '" title="Post Type Count">' . $result . '</a>';
}
add_filter('manage_users_custom_column', 'my_manage_users_custom_column', 10, 3);

function my_manage_users_columns($columns) {
    $columns['post_type_count'] = __( 'Post Type', 'textdomain' );

    return $columns;
}
add_filter('manage_users_columns', 'my_manage_users_columns');

@ sorich87 - get_posts_by_author_sql()诶?那是我的新事物。谢谢!但是我只是检查了您的代码,但我认为它并没有达到他的期望。您的get_posts_by_author_sql()呼叫始终返回'1=0',他想按用户的帖子类型获取计数列表;除非我误解了这段代码,否则不会这么做。也许你可以解决?
MikeSchinkel 2010年

是的,我误解了这个问题。我的代码只会为一种自定义帖子类型添加一列。只需替换post_type为帖子类型名称。例如:get_posts_by_author_sql( 'book', true, $user_id );对于名为“ book”的帖子类型。经过测试,可以正常工作。
sorich87

PS:还在WPHonors上为您投票。你绝对值得!
sorich87

我尚未对此进行测试,但是它似乎可以正常运行,只是可能没有Im寻找的所有功能,但这仍然很容易添加。谢谢:)
jaredwilli 2010年

@ sorich87-太棒了!
MikeSchinkel 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.