问题描述

我试图找出如何挂钩到/wp-admin/users.php 管理页面来创建自定义列,以显示用户在 WPHonors.com 上的自定义帖子类型的帖子数。

我为此创建了一个 trac ticket,但是 @nacin 解释了为什么这是一个更适合插件的工作。

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

如果我把它链接到某个地方,那就是:

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

如果这样甚至有可能,我猜。但是我甚至不需要将它链接到任何地方。我主要想要显示每个人的 CPT 帖子数,拥有 600 用户和 300+4 自定义帖子类型的总和。管理员只能提交'post'的帖子,因此用户页面中的列是无用的。

最佳解决方案

这是 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;
}

次佳解决方案

假设我明白了这个问题,你需要做的是将两个挂钩相关联的列标题和列值作为管理员管理页面。它们是'manage_{$type}_columns''manage_{$type}_custom_column',其中您的 use-case {$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'

接下来,您需要使用仅用于 non-standard 列的'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()在帖子上运行查询时坚持使用,但是这个查询将需要使用这么多其他钩子,它似乎更容易被”naughty” 所有。

我省略了 $post->post_type 的任何帖子是'revision''nav_menu_item',但留在'attachments'中。您可能会更好地明确地包含您想要的帖子类型,而不是排除我所做的几个。

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

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

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;
}

结果 UI

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

下载完整的代码

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

  • wp-post-counts-for-user-by-post-type.php

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

希望这可以帮助!

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。