Mostrando contagens de postagem do usuário por tipo de postagem personalizado na lista de usuários do administrador?


9

Estou tentando descobrir como conectar-se à /wp-admin/users.phppágina de gerenciamento para criar colunas personalizadas para mostrar o número de postagens que os usuários têm para os tipos de post personalizados no WPHonors.com .

Criei um ticket trac para isso, mas o @nacin explicou por que é mais um trabalho que um plugin deve fazer.

Não consegui encontrar uma maneira de manipular a saída da tabela de usuários, para poder adicionar colunas personalizadas para contagens de postagem de CPTs para cada usuário. E isso pode ter algo a ver com a pergunta @nacin, com o que os números da contagem de postagens vinculariam. Para a contagem atual de postagens, o usuário vincula a página de gerenciamento de postagens, mostrando todas as postagens desse usuário ( /wp-admin/edit.php?author=%author_id%).

Se eu o vinculasse em algum lugar, seria:

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

Se isso fosse de alguma forma possível, eu acho. Mas nem preciso necessariamente vinculá-lo a qualquer lugar. Quero principalmente mostrar apenas a contagem de postagens de CPT para cada pessoa, com 600usuários e um total combinado de 300+postagens nos 4tipos de postagem personalizados. Os administradores são apenas quem pode enviar 'post'postagens, para que a coluna na página do usuário seja inútil.

Respostas:


10

Aqui está uma expansão da resposta do tutorial de Mike. Adicionei links para os tipos listados, para que você possa clicar em um e ser direcionado para uma lista de todas as postagens desse tipo para esse autor, o que exigia uma variável adicional $countse uma saída extra 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;
}

10

Supondo que eu entendi a pergunta, o que você precisa fazer é conectar os dois ganchos relacionados aos cabeçalhos das colunas e ao valor das colunas das páginas de gerenciamento do administrador. Eles são 'manage_{$type}_columns'e 'manage_{$type}_custom_column'em que na sua de casos de uso {$type}é users.

O 'manage_users_columns'gancho

Este primeiro é simples, permite especificar os cabeçalhos das colunas e, portanto, as colunas disponíveis. O WordPress codifica o valor da coluna "Postagens". Assim, como você deseja alterá-lo, simplesmente o removemos unset()e adicionamos uma nova coluna com o mesmo título, mas que possui o 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;
}

O 'manage_users_custom_column'gancho

Em seguida, você precisa usar o 'manage_users_custom_column'gancho, que só é chamado para colunas não padrão. Testamos para $column_name=='custom_posts'tornar nosso código robusto, caso adicionemos novas colunas de usuário no futuro e, em seguida, obtemos as contagens de tipo de postagem do usuário na função que escrevi, _yoursite_get_author_post_type_counts()que discutirei a seguir. Eu então joguei com algumas maneiras de formatar isso, mas decidi que um HTML <table>era o mais apropriado (já que é uma tabela de dados) . Se uma tabela não funcionar para você, presumo que você poderá gerar marcações diferentes com bastante facilidade:

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

Obter contagens de postagens por tipo de post para cada usuário / autor

Por fim, há a recuperação de contagens de mensagens por tipo de postagem por autor / usuário. Geralmente, tento manter o uso WP_Query()ao executar consultas em postagens, mas essa consulta exigiria o uso de tantos outros ganchos que parecia mais fácil ser "malcriado" e fazer tudo em um.

Omiti qualquer postagem de $post->post_typeis 'revision'or 'nav_menu_item'but left 'attachments'. Talvez seja melhor incluir explicitamente os tipos de postagem desejados, em vez de excluir os poucos que fiz.

Eu também filtrada por $post->post_statusapenas 'publish'e 'pending'. Se você quiser incluir também 'future', 'private'e / ou 'draft'você vai precisar para fazer as mudanças no código.

Para cada carregamento de página, eu chamo essa _yoursite_get_author_post_type_counts()função apenas uma vez e, em seguida, armazeno em uma variável estática em vez de chamar para cada usuário. Eu armazeno em uma matriz indexada por IDs de autor / usuário que contêm uma matriz com o nome Post Type no elemento 'label'e, claro, a contagem em um elemento com o mesmo nome:

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

A interface do usuário resultante

E é isso que parece aplicado à minha instalação de teste do WordPress 3.0.1:


(fonte: mikeschinkel.com )

Faça o download do código completo

Você pode baixar o código completo do Gist :

Você pode copiar esse código no functions.phparquivo do seu tema ou armazenar o arquivo em um plug-in, conforme sua escolha.

Espero que isto ajude!


Bem, isso é fácil. Tudo o que você precisava fazer era dizer que ele usa o 'manage _ {$ type} _columns' e 'manage _ {$ type} _custom_column', onde $ type = users, e eu poderia descobrir o resto a partir daí. Tive a sensação de que sim, mas verifiquei e não vi usuários. O resto é fácil o suficiente. Agradeço o grande esforço que você colocou nele, e vou votar em você no WPHonors com certeza (já que já tenho) goo.gl/CrSi Muito obrigado: D
jaredwilli

11
@jaredwilli - Sim, é claro. Mas o objetivo do WordPress Answers é fornecer respostas para pessoas que vão muito além da primeira pessoa que pergunta. É por isso que escrevo detalhadamente, mesmo que você precise apenas de informações sobre outras pessoas que sejam completamente novas na abordagem. Tentando ajudar os dois. Ah, e obrigado pelos comentários agradáveis no site (e chance que eu poderia mudar a foto embora :)?
MikeSchinkel

Sim, é por isso que eu não o impedi de me dizer o gancho que eu precisava usar. Eu sei que não serei o único a encontrar uma necessidade disso, então está tudo bem.
jaredwilli

Oh desculpe, é claro que vou. Fiquei distraído com um tipo de post personalizado que estou criando para um site de loja que estou construindo. Suponho que você não tenha descoberto uma maneira de vincular a contagem de postagens a uma página edit.php mostrando as postagens para os autores delas. Provavelmente preciso incorporar isso no meu CPT.
jaredwilli

@jaredwilli - Ah, sim, mas parece que @somatic fez isso por você, certo?
MikeSchinkel #

2

A seguir, há uma variação na resposta de sorich87, já que eu não conseguia fazê-lo funcionar e queria oferecer suporte a vários tipos automaticamente:

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

Eu li get_posts_by_author_sql()e como ela deve construir uma declaração WHERE para você, mas os resultados que obtive foram sempre "1 = 0". Então, acabei de escrever o restante da instrução SQL, pois get_posts_by_author_sql()poupa apenas a necessidade de escrever dois bits: o tipo de postagem e o autor:

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

Isso funciona tão bem e adiciona quantas colunas você desejar, mas cada uma delas ocupa espaço horizontal, enquanto o tutorial de Mike adiciona uma única coluna para tipos de postagem personalizados e as lista como uma tabela nessa linha. Mesma informação, visualização diferente. O de Mike provavelmente é melhor para grandes quantidades de tipos, pois cria uma lista vertical condensada (e exibe apenas um item de contagem se não estiver vazio), enquanto o método de sorich87 é bom para quantidades menores, pois há muito espaço para colunas horizontais disponível.

Não esqueça que você pode adicionar "post_status = publish" à consulta para retornar apenas itens publicados, pois o exemplo atualmente retorna todas as postagens ...


Ótimo! get_posts_by_author_sql( $column, true, $user_id );deve construir a instrução where.
sorich87

1

O seguinte irá adicioná-lo:

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()eh? Aquele é novo para mim; obrigado! Mas acabei de verificar seu código e acho que não faz o que ele está esperando. Sua get_posts_by_author_sql()ligação sempre retorna '1=0', e ele queria obter uma lista de contagens por tipo de postagem para um usuário; a menos que eu entenda mal esse código não faça isso. Talvez você possa consertar isso?
MikeSchinkel #

Sim, eu não entendi a pergunta. Meu código adicionará apenas uma coluna para um tipo de postagem personalizado. Basta substituir post_typepelo nome do tipo de postagem. Por exemplo: get_posts_by_author_sql( 'book', true, $user_id );para um tipo de postagem chamado 'livro'. Testado e funciona.
sorich87

PS: Também votou em você no WPHonors. Você definitivamente merece!
sorich87

Ainda estou para testar isso, mas parece que funcionaria, talvez não tenha toda a funcionalidade que estou procurando, mas é fácil adicionar ainda. Obrigado :)
jaredwilli

@ sorich87 - Incrível!
MikeSchinkel #
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.