¿Se muestran los recuentos de publicaciones del usuario por tipo de publicación personalizada en la lista de usuarios del administrador?

9

Estoy tratando de descubrir cómo conectarme a la /wp-admin/users.phppágina de administración para crear columnas personalizadas que muestren la cantidad de publicaciones que los usuarios tienen para los tipos de publicaciones personalizadas en WPHonors.com .

Creé un ticket de trac para esto, pero @nacin explicó por qué es un trabajo más para un complemento.

No he podido encontrar una manera de manipular el resultado de la tabla de usuarios, por lo que puedo agregar columnas personalizadas para los recuentos de publicaciones de CPT para cada usuario. Y eso puede tener algo que ver con la pregunta que hizo @nacin, a qué se vincularían los números de conteo posterior. Para el recuento de publicaciones actual de 'publicaciones' que tiene un usuario, se vincula a la página de administración de publicaciones, mostrando todas las publicaciones para ese usuario ( /wp-admin/edit.php?author=%author_id%).

Si tuviera que vincularlo en alguna parte, sería para:

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

Si eso fuera posible de alguna manera, supongo. Pero ni siquiera necesito vincularlo necesariamente a ningún lado. Principalmente, solo quiero mostrar el recuento de publicaciones de CPT para cada persona, con 600usuarios y un total combinado de 300+publicaciones en diferentes 4tipos de publicaciones personalizadas. Los administradores son los únicos que pueden enviar 'post'publicaciones, por lo que esa columna en la página del usuario es inútil.

jaredwilli
fuente

Respuestas:

10

Aquí hay una expansión de la respuesta tutorial de Mike. Agregué enlaces a los tipos enumerados para que pueda hacer clic en uno y acceder directamente a una lista de todas las publicaciones en ese tipo para ese autor, que requiere una variable adicional para $countsy una salida adicional para$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;
}
somático
fuente
10

Suponiendo que entendí la pregunta, lo que debe hacer es conectar los dos ganchos relacionados con los encabezados de columna y el valor de las columnas para las páginas de administración del administrador. Ellos son 'manage_{$type}_columns'y 'manage_{$type}_custom_column'dónde en su caso de uso {$type}es users.

El 'manage_users_columns'gancho

Este primero es simple, le permite especificar los encabezados de columna y, por lo tanto, las columnas disponibles. WordPress codifica el valor de la columna "Publicaciones" , por lo que, dado que desea cambiarlo, simplemente lo eliminaremos unset()y luego agregaremos una nueva columna con el mismo título, pero que en su lugar tiene el identificador 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;
}

El 'manage_users_custom_column'gancho

A continuación, debe usar el 'manage_users_custom_column'gancho que solo se llama para columnas no estándar. Probamos para $column_name=='custom_posts'hacer que nuestro código sea robusto en caso de que agreguemos nuevas columnas de usuario en el futuro y luego tomamos los recuentos de tipo de publicación de usuario de la función que escribí, _yoursite_get_author_post_type_counts()que analizaré a continuación. Luego jugué con algunas formas de formatear esto, pero decidí que un HTML <table>era el más apropiado (ya que es una tabla de datos) . Si una tabla no funciona para usted, supongo que podrá generar un marcado diferente con bastante facilidad:

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

Obtener publicaciones cuenta por tipo de publicación para cada usuario / autor

Por último, existe la recuperación de los recuentos de publicaciones por tipo de publicación por autor / usuario. En general, trato de seguir usando WP_Query()cuando ejecuto consultas en publicaciones, pero esta consulta habría requerido el uso de tantos otros ganchos que parecía más fácil ser "travieso" y hacerlo todo en uno.

Omití cualquier publicación de $post->post_typeis 'revision'o 'nav_menu_item'but left 'attachments'. Puede que le resulte mejor incluir explícitamente los tipos de publicación que desea en lugar de excluir los pocos que hice.

También filtré por $post->post_statussolo 'publish'y 'pending'. Si desea incluir también 'future', 'private'y / o 'draft'deberá realizar los cambios en el código.

Para cada carga de página, solo llamo a esta _yoursite_get_author_post_type_counts()función una vez y luego la guardo en una variable estática en lugar de llamar a cada usuario. Almaceno en una matriz indexada por ID de autor / usuario que contiene una matriz con el nombre del tipo de publicación en el elemento 'label'y, por supuesto, la cuenta en un elemento con el mismo nombre:

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

La interfaz de usuario resultante

Y esto es lo que parece aplicado a mi instalación de prueba de WordPress 3.0.1:


(fuente: mikeschinkel.com )

Descargar el código completo

Puede descargar el código completo de Gist :

Puede copiar este código en el functions.phparchivo o la tienda de su tema e incluir el archivo en un complemento, lo que elija.

¡Espero que esto ayude!

MikeSchinkel
fuente
Bueno, eso es fácil. Todo lo que tenía que hacer era decir que usaba 'manage _ {$ type} _columns' y 'manage _ {$ type} _custom_column' donde $ type = users, y podría haber descubierto el resto desde allí. Tenía la sensación de que sí, pero lo comprobé y no vi usuarios. El resto es bastante fácil. Le agradezco el gran esfuerzo que puso en ello, y seguro que votaré por usted en WPHonors (ya lo tengo) goo.gl/CrSi Muchas gracias: D
jaredwilli
1
@jaredwilli - Sí, por supuesto. Pero el objetivo de WordPress Answers es proporcionar respuestas para las personas mucho más allá de la primera persona que pregunta. Es por eso que escribo en profundidad a pesar de que es posible que solo necesite fragmentos de información que otros puedan ser completamente nuevos en el enfoque. Tratando de ayudar a ambos. Ah, y gracias por los buenos comentarios en el sitio (¿y la posibilidad de que pueda cambiar esa foto? :)
MikeSchinkel
Sí, es por eso que no te detuve de decirme el gancho que necesitaba usar. Sé que no seré el único en encontrar una necesidad para esto, así que todo está bien.
jaredwilli
Oh lo siento, por supuesto que lo haré. Me distrajo un tipo de publicación personalizada que estoy haciendo para un sitio de tienda que estoy construyendo. ¿Supongo que no encontraste una manera de vincular los recuentos de publicaciones a una página edit.php que muestre publicaciones para sus autores? Probablemente necesito construir eso en mi CPT. Supongo.
jaredwilli
@jaredwilli - Ah, sí, pero parece que @somatic lo hizo por ti, ¿verdad?
MikeSchinkel
2

La siguiente es una variación de la respuesta de sorich87, ya que no pude hacer que funcione, y quería admitir varios tipos automáticamente:

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

Leí get_posts_by_author_sql()y cómo se supone que debe construir una declaración WHERE para usted, pero los resultados que obtuve siempre fueron "1 = 0". Así que acabo de escribir el resto de la declaración SQL, ya get_posts_by_author_sql()que solo te ahorra tener que escribir dos bits: el tipo de publicación y el autor:

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

Esto funciona igual de bien y agregará tantas columnas como desee, pero cada una usa espacio horizontal, mientras que el tutorial de Mike agregará una sola columna para los tipos de publicaciones personalizadas y luego las enumerará como una tabla dentro de esa fila. La misma información, diferente visualización. Mike's probablemente sea mejor para grandes cantidades de tipos, ya que crea una lista vertical condensada (y solo muestra un elemento de conteo si no está vacío), mientras que el método sorich87 es bueno para cantidades más pequeñas, ya que solo hay una gran cantidad de espacio de columna horizontal disponible.

No olvide que puede agregar "post_status = publicar" a la consulta para devolver solo los elementos publicados, como el ejemplo actualmente devuelve todas las publicaciones ...

somático
fuente
¡Excelente! get_posts_by_author_sql( $column, true, $user_id );debe construir la instrucción where.
sorich87
1

Lo siguiente lo agregará:

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
fuente
@ sorich87 - get_posts_by_author_sql()¿eh? Ese es nuevo para mí; ¡Gracias! Pero acabo de comprobar su código y no creo que haga lo que él espera. Su get_posts_by_author_sql()llamada siempre regresa '1=0", y él quería obtener una lista de conteos por tipo de publicación para un usuario; a menos que malinterprete este código no hace eso. ¿Quizás puedas arreglarlo?
MikeSchinkel
Sí, entendí mal la pregunta. Mi código solo agregará una columna para un tipo de publicación personalizada. Simplemente reemplácelo post_typepor el nombre del tipo de publicación. Por ejemplo: get_posts_by_author_sql( 'book', true, $user_id );para un tipo de publicación llamado 'libro'. Probado y funciona.
sorich87
PD: También voté por ti en WPHonors. ¡Definitivamente te lo mereces!
sorich87
Todavía tengo que probar esto, pero parece que funcionaría, es posible que no tenga toda la funcionalidad que estoy buscando, pero eso es fácil de agregar aún. Gracias :)
jaredwilli
@ sorich87 - ¡Impresionante!
MikeSchinkel