web-dev-qa-db-ja.com

管理者のユーザーリストにカスタム投稿タイプ別のユーザーの投稿数を表示する

WPHonors.com で、カスタム投稿タイプに対する投稿数を表示するためのカスタム列を作成するために/wp-admin/users.php管理ページにフックする方法を見つけようとしています。

tracチケットを作成しました これには @nacin がプラグインの代わりにやるべきことがなぜかという理由を説明しました。

Usersテーブルの出力を操作する方法を見つけることができなかったので、CPT用のカスタム列を追加して各ユーザーのカウントを投稿することができます。そしてそれは@nacinが尋ねた質問と関係があるかもしれません。ユーザーの現在の「投稿」投稿数については、投稿管理ページにリンクし、そのユーザーのすべての投稿を表示します(/wp-admin/edit.php?author=%author_id%)。

どこかにリンクするとしたら、次のようになります。

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

それがどうしても可能だったとしたら、私は思います。しかし、私は必ずしもそれをどこにでもリンクする必要すらない。私はたいてい600のユーザーと300+のカスタム投稿タイプの合計4の投稿を持って、それぞれの人のCPT投稿数を表示したいだけです。管理者は'post'投稿を送信できる人だけなので、ユーザーのページの列は役に立ちません。

9
jaredwilli

マイクのチュートリアル回答の拡張版です。リストされたタイプへのリンクを追加したため、クリックすると、その著者のそのタイプのすべての投稿のリストが表示されます。$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
somatic

仮定私は質問を理解しました。あなたがする必要があるのは、管理ページの管理のための列ヘッダーと列値に関連する2つのフックにフックすることです。それらは'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>が最も適切であると判断しましたisテーブルであるためof data)。テーブルが機能しない場合、異なるマークアップを簡単に生成できると思います。

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()関数を1回だけ呼び出し、ユーザーごとに呼び出すのではなく、静的変数に格納します。要素'label'の投稿タイプ名と、もちろん同じ名前の要素のカウントを持つ配列を含む著者/ユーザーIDでインデックス付けされた配列に格納します。

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のテストインストールに適用されるように見えます:


(ソース: mikeschinkel.com

完全なコードをダウンロードする

download からの完全なコード Gist

このコードをテーマのfunctions.phpファイルにコピーするか、選択したファイルをプラグインにインクルードして保存できます。

お役に立てれば!

10
MikeSchinkel

私は彼を働かせることができなかったので、以下は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"でした。 get_posts_by_author_sql()は2ビットを書く必要があるだけなので、残りのSQL文は書き出しただけです。投稿タイプと作者:

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

これも同様に機能し、必要なだけの列を追加しますが、各列は水平方向のスペースを使いますが、Mikeのチュートリアルではカスタム投稿タイプ用に1列を追加し、それらをその行内の表としてリストします。同じ情報、異なる視覚化Mikeはおそらく垂直型の要約リストを作成するので(そして空でない場合にのみカウント項目を表示するため)大量の型に向いていますが、sorich87の方法は利用できる水平方向の列の余地があまりに少ないので少量に対しては有効です。

例として、現在すべての投稿を返すように、 "post_status = publish"をクエリに追加して、公開されたアイテムのみを返すことができることを忘れないでください...

2
somatic

以下はそれを追加します:

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');
1
sorich87