Affichage du nombre de publications de l'utilisateur par type de publication personnalisé dans la liste des utilisateurs de l'administrateur?

9

J'essaie de comprendre comment se connecter à la /wp-admin/users.phppage de gestion pour créer des colonnes personnalisées pour afficher le nombre de messages que les utilisateurs ont pour les types de messages personnalisés sur WPHonors.com .

J'ai créé un ticket Trac pour cela, mais @nacin a expliqué pourquoi c'est plutôt un travail à faire pour un plugin.

Je n'ai pas réussi à trouver un moyen de manipuler la sortie de la table des utilisateurs, je peux donc ajouter des colonnes personnalisées pour le nombre de publications CPT pour chaque utilisateur. Et cela peut avoir quelque chose à voir avec la question posée par @nacin, à quoi les numéros de comptage des messages sont-ils liés. Pour le nombre de publications «post» en cours qu'un utilisateur possède, il renvoie à la page de gestion des publications, affichant toutes les publications de cet utilisateur ( /wp-admin/edit.php?author=%author_id%).

Si je devais le lier quelque part, ce serait pour:

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

Si c'était encore possible, je suppose. Mais je n'ai même pas nécessairement besoin de le lier à n'importe où. Je veux surtout montrer le nombre de messages CPT pour chaque personne, avoir des 600utilisateurs et un total combiné de 300+messages sur différents 4types de messages personnalisés. Les administrateurs ne sont que ceux qui peuvent soumettre des 'post'messages, de sorte que la colonne de la page de l'utilisateur est inutile.

jaredwilli
la source

Réponses:

10

Voici une extension de la réponse du didacticiel de Mike. J'ai ajouté des liens vers les types répertoriés afin que vous puissiez cliquer sur l'un d'eux et être redirigé directement vers une liste de tous les messages de ce type pour cet auteur, ce qui nécessitait une variable supplémentaire $countset une sortie supplémentaire pour$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;
}
somatique
la source
10

En supposant que j'ai compris la question, ce que vous devez faire est de vous connecter aux deux crochets liés aux en-têtes de colonne et à la valeur des colonnes pour les pages de gestion d'administration. Ils sont 'manage_{$type}_columns'et 'manage_{$type}_custom_column'où dans votre cas d' utilisation {$type}est users.

Le 'manage_users_columns'crochet

Cette première est simple, elle vous permet de spécifier les en-têtes de colonne et donc les colonnes disponibles. WordPress code en dur la valeur de la colonne "Posts" , donc comme vous voulez la changer, nous allons simplement la supprimer avec unset()puis ajouter une nouvelle colonne avec le même titre mais qui a à la place l'identifiant de '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;
}

Le 'manage_users_custom_column'crochet

Ensuite, vous devez utiliser le 'manage_users_custom_column'hook qui n'est appelé que pour les colonnes non standard. Nous testons pour $column_name=='custom_posts'rendre notre code robuste au cas où nous ajouterions de nouvelles colonnes utilisateur à l'avenir, puis nous récupérons le nombre de types de messages utilisateur à partir de la fonction que j'ai écrite, _yoursite_get_author_post_type_counts()dont je parlerai dans la suite. J'ai ensuite joué avec quelques façons de formater cela, mais j'ai décidé qu'un HTML <table>était le plus approprié (car il s'agit d' un tableau de données) . Si une table ne fonctionne pas pour vous, je suppose que vous serez en mesure de générer assez facilement des balises différentes:

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

Obtenir le nombre de publications par type de publication pour chaque utilisateur / auteur

Enfin, il y a la récupération du nombre de publications par type de publication par auteur / utilisateur. En général, j'essaie de m'en tenir à l'utilisation WP_Query()lors de l'exécution de requêtes sur des publications, mais cette requête aurait nécessité l'utilisation de nombreux autres crochets, il semblait simplement plus facile d'être "méchant" et de faire tout en un.

J'ai omis tout poste de $post->post_typeis 'revision'or 'nav_menu_item'but but in 'attachments'. Vous pourriez trouver préférable d'inclure explicitement les types de messages que vous souhaitez au lieu d'exclure les quelques-uns que j'ai faits.

J'ai également filtré $post->post_statuspour seulement 'publish'et 'pending'. Si vous souhaitez également inclure 'future', 'private'et / ou 'draft'vous devrez apporter les modifications dans le code.

Pour chaque chargement de page, j'appelle cette _yoursite_get_author_post_type_counts()fonction une seule fois, puis je stocke dans une variable statique plutôt que d'appeler pour chaque utilisateur. Je stocke dans un tableau indexé par les ID auteur / utilisateur contenant un tableau avec le nom du type de message dans l'élément 'label'et bien sûr le nombre dans un élément du même nom:

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

L'interface utilisateur résultante

Et voici à quoi cela ressemble appliqué à mon installation de test de WordPress 3.0.1:


(source: mikeschinkel.com )

Téléchargez le code complet

Vous pouvez télécharger le code complet depuis Gist :

Vous pouvez copier ce code dans le functions.phpfichier de votre thème ou stocker le fichier dans un plugin, selon votre choix.

J'espère que cela t'aides!

MikeSchinkel
la source
Eh bien, c'est facile. Tout ce que vous aviez à faire était de dire qu'il utilise les colonnes 'manage _ {$ type} _columns' et 'manage _ {$ type} _custom_column' où $ type = users, et j'aurais pu comprendre le reste à partir de là. J'avais l'impression que c'était le cas, mais je l'ai vérifié et je n'ai pas vu d'utilisateurs. Le reste est assez facile. J'apprécie l'effort considérable que vous y avez investi, et je voterai pour vous sur WPHonors à coup sûr (puisque j'ai déjà) goo.gl/CrSi Merci beaucoup: D
jaredwilli
1
@jaredwilli - Oui bien sûr. Mais l'objectif de WordPress Answers est de fournir des réponses aux personnes bien au-delà de la première personne qui demande. C'est pourquoi j'écris en profondeur même si vous n'avez besoin que de quelques informations, d'autres pourraient être complètement nouveaux dans l'approche. Essayer d'aider les deux. Oh, et merci pour les gentils commentaires sur le site (et par chance je pourrais changer cette photo? :)
MikeSchinkel
Oui, c'est pourquoi je ne vous ai pas empêché de me dire le crochet que je devais utiliser. Je sais que je ne serai pas le seul à en trouver un besoin donc tout va bien.
jaredwilli
Oh désolé, bien sûr que je le ferai. J'ai été distrait par un type de message personnalisé que je fais pour un site de magasin. Je ne suppose pas que vous ayez trouvé un moyen de lier le nombre de messages à une page edit.php montrant des messages pour leurs auteurs? J'ai probablement besoin d'intégrer cela dans mes suppositions CPT Im.
jaredwilli
@jaredwilli - Ah, oui, mais on dirait que @somatic l'a fait pour vous, non?
MikeSchinkel
2

Ce qui suit est une variation de la réponse de sorich87, car je n'ai pas pu faire fonctionner la sienne et je voulais prendre en charge plusieurs types automatiquement:

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

J'ai lu get_posts_by_author_sql()et comment il est censé construire une instruction WHERE pour vous, mais les résultats que j'ai obtenus étaient toujours "1 = 0". Je viens donc d'écrire le reste de l'instruction SQL, comme cela get_posts_by_author_sql()ne vous évite d'avoir à écrire deux bits: le type de message et l'auteur:

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

Cela fonctionne aussi bien et ajoutera autant de colonnes que vous le souhaitez, mais chacune utilise de l'espace horizontal, tandis que le didacticiel de Mike ajoutera une seule colonne pour les types de publication personnalisés, puis les répertoriera en tant que tableau dans cette ligne. Même info, visualisation différente. Mike est probablement meilleur pour de grandes quantités de types, car il crée une liste verticale condensée (et affiche uniquement un élément de comptage s'il n'est pas vide), tandis que la méthode de sorich87 est bonne pour de plus petites quantités, car il n'y a que peu de place de colonne horizontale disponible.

N'oubliez pas que vous pouvez ajouter "post_status = publish" à la requête pour renvoyer uniquement les éléments publiés, car l'exemple renvoie actuellement tous les messages ...

somatique
la source
Génial! get_posts_by_author_sql( $column, true, $user_id );devrait construire l'instruction where.
sorich87
1

Ce qui suit l'ajoutera:

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
la source
@ sorich87 - get_posts_by_author_sql()hein? Celui-là est nouveau pour moi; Merci! Mais je viens de vérifier votre code et je ne pense pas qu'il fasse ce qu'il attend. Votre get_posts_by_author_sql()appel revient toujours '1=0», et il voulait obtenir une liste de comptes par type de message pour un utilisateur; à moins que je ne comprenne mal ce code ne fait pas cela. Peut-être que vous pouvez le réparer?
MikeSchinkel
Oui, j'ai mal compris la question. Mon code n'ajoutera qu'une colonne pour un type de publication personnalisé. Remplacez simplement post_typepar le nom du type de message. Par exemple: get_posts_by_author_sql( 'book', true, $user_id );pour un type de poste appelé «livre». Testé et ça marche.
sorich87
PS: a également voté pour vous sur WPHonors. Vous le méritez certainement!
sorich87
Je n'ai pas encore testé cela, mais il semblerait que cela fonctionnerait, pourrait ne pas avoir toutes les fonctionnalités que je recherche, mais c'est facile à ajouter. Merci :)
jaredwilli
@ sorich87 - Génial!
MikeSchinkel