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


9

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ユーザーのCPT投稿数を表示し、ユーザーとカスタム投稿タイプ全体の300+投稿の合計を表示し4ます。管理者は'post'投稿を送信できる唯一のユーザーであるため、ユーザーのページの列は役に立ちません。

回答:


10

これはマイクのチュートリアルの回答の拡張です。あなたがいずれかをクリックすることができますし、ために追加の変数を必要と作者のためにそのタイプのすべての記事の一覧に右取られるので、私は、リストされているタイプへのリンクを追加$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管理ページの列ヘッダーと列値に関連する2つのフックにフックすることです。彼らはある'manage_{$type}_columns''manage_{$type}_custom_column'どこユースケースです。{$type}users

'manage_users_columns'フック

最初の1つは単純で、列ヘッダーを指定できるため、使用可能な列を指定できます。WordPressは「投稿」列の値をハードコーディングしているので、変更したいので、それを削除して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()は投稿に対してクエリを実行するときに使用することに固執しようとしますが、このクエリは他の多くのフックを使用する必要があり、「いたずら」になり、すべてを1つに行う方が簡単に思えました。

$post->post_typeis 'revision'またはorの投稿を省略し'nav_menu_item'ました'attachments'。私が行った少数の投稿を除外するよりも、希望する投稿の種類を明示的に含めるほうが良いかもしれません。

私も$post->post_statusfor 'publish'とでフィルタリングしました'pending'。も含めたい場合'future''private'および/または'draft'コードに変更を加える必要があります。

ページの読み込みごとに、この_yoursite_get_author_post_type_counts()関数を1回だけ呼び出してから、ユーザーごとに呼び出すのではなく、静的変数に格納します。要素に投稿タイプ名の配列を含む作成者/ユーザーIDでインデックス付けされた配列に保存します。'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;
}

結果のUI

そして、これはWordPress 3.0.1の私のテストインストールに適用されたように見えます:


(ソース:mikeschinkel.com

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

Gistから完全なコードをダウンロードできます

このコードをテーマのfunctions.phpファイルにコピーするか、ファイルをプラグインに格納して、どちらを選択してもかまいません。

お役に立てれば!


まあ、それは簡単です。あなたがしなければならないのは、それが 'manage _ {$ type} _columns'と 'manage _ {$ type} _custom_column'を使用していて$ type = usersであると言うことだけであり、私はそこから残りを理解することができました。感じはしましたが、チェックしてみましたがユーザーは見えませんでした。残りは簡単です。私はあなたがそれに費やした多大な努力に感謝します、そして(私はすでに持っているので)確かにWPHonorsであなたのために投票しますgoo.gl/CrSi おかげでたくさん:D
jaredwilli

1
@jaredwilli-はい、もちろんです。しかし、WordPress Answersの目標は、最初に質問した人をはるかに超えた人に回答を提供することです。他の人がこのアプローチにまったく新しいかもしれない情報を少しだけ必要とするかもしれないにもかかわらず、私が詳細に書くのはそのためです。両方を助けようとしています。ああ、そしてサイトの素敵なコメントに感謝します(そしてその写真を変更できる可能性はありますか?:)
MikeSchinkel

だからこそ、私が使う必要のあるフックを教えてくれるのを止めなかったのです。これが必要なのは私だけではないので、それで十分です。
jaredwilli 2010年

申し訳ありませんが、もちろんします。ショップサイトのイムビルディング用に作成したカスタムポストタイプのイムに気を取られました。投稿数をそれらの作者の投稿を表示しているedit.phpページにリンクする方法を理解したと思いませんか?おそらくそれを私のCPT Im推測に組み込む必要があります。
jaredwilli

@jaredwilli-ああ、そうですが、@ somaticがあなたのためにやったように見えますよね?
MikeSchinkel、

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()を書きました。ポストタイプと作成者の2ビットを書くだけで済みます。

"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 2010年

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

はい、質問を誤解しました。私のコードは、1つのカスタム投稿タイプに対して1つの列のみを追加します。post_type投稿タイプ名に置き換えるだけです。例:get_posts_by_author_sql( 'book', true, $user_id );「本」という投稿タイプの場合。テスト済みで動作します。
sorich87

PS:WPHonorsにも投票しました。あなたは間違いなくそれに値する!
sorich87 2010年

私はまだこれをテストしていませんが、うまくいくように見えますが、Imが探しているすべての機能を備えているわけではありませんが、それでも簡単に追加できます。ありがとう:)
jaredwilli

@ sorich87-すごい!
MikeSchinkel、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.