Wyświetlanie liczby postów użytkownika według niestandardowego typu postów na liście użytkowników administratora?

9

Próbuję wymyślić, jak podłączyć się do strony /wp-admin/users.phpzarządzania, aby utworzyć niestandardowe kolumny do wyświetlania liczby postów użytkowników dla niestandardowych typów postów na WPHonors.com .

Stworzyłem do tego bilet trac, ale @nacin wyjaśnił, dlaczego zamiast tego wtyczka powinna pracować.

Nie udało mi się znaleźć sposobu na manipulowanie danymi wyjściowymi tabeli użytkowników, więc mogę dodać niestandardowe kolumny dla liczników postów CPT dla każdego użytkownika. I może to mieć coś wspólnego z pytaniem @nacin, do którego prowadzą numery liczb postów. W przypadku bieżącej liczby postów użytkownika użytkownik prowadzi do strony zarządzania postami, pokazując wszystkie posty dla tego użytkownika ( /wp-admin/edit.php?author=%author_id%).

Gdybym miał gdzieś to linkować, byłoby to:

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

Gdyby to było w jakiś sposób możliwe. Ale niekoniecznie muszę to nigdzie łączyć. Chcę przede wszystkim wyświetlać liczby postów CPT dla każdej osoby, mając 600użytkowników i łączną liczbę 300+postów w 4niestandardowych typach postów. Tylko administratorzy mogą przesyłać 'post'posty, więc kolumna na stronie użytkownika jest bezużyteczna.

jaredwilli
źródło

Odpowiedzi:

10

Oto rozwinięcie samouczka Mike'a. Dodałem linki do wymienionych typów, abyś mógł kliknąć jeden z nich i przejść bezpośrednio do listy wszystkich postów tego typu dla tego autora, co wymagało dodatkowej zmiennej $countsi dodatkowych wyników dla$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;
}
somatyczny
źródło
10

Zakładając, że rozumiem pytanie, co musisz zrobić, to podpiąć się do dwóch zaczepów związanych z nagłówkami kolumn i wartością kolumn dla stron zarządzania administratorem. Są 'manage_{$type}_columns'i 'manage_{$type}_custom_column'gdzie korzystanie-case {$type}jest users.

'manage_users_columns'hak

Ten pierwszy jest prosty, pozwala określić nagłówki kolumn, a tym samym dostępne kolumny. WordPress koduje wartość kolumny „Posty”, więc ponieważ chcesz ją zmienić, po prostu ją usuniemy, unset()a następnie dodamy nową kolumnę o tym samym tytule, która zamiast tego ma identyfikator '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'hak

Następnie musisz użyć 'manage_users_custom_column'haka, który jest wywoływany tylko dla niestandardowych kolumn. Sprawdzamy, czy $column_name=='custom_posts'nasz kod jest niezawodny na wypadek, gdybyśmy dodawali nowe kolumny użytkowników w przyszłości, a następnie pobieramy liczby typów postów użytkownika z funkcji, którą napisałem, o _yoursite_get_author_post_type_counts()której omówię w dalszej części. Potem grałem na kilka sposobów, aby to sformatować, ale zdecydowałem, że HTML <table>jest najbardziej odpowiedni (ponieważ jest to tabela danych) . Jeśli tabela nie działa dla ciebie, zakładam, że będziesz w stanie dość łatwo wygenerować różne znaczniki:

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

Pobieranie postów liczy się według typu posta dla każdego użytkownika / autora

Wreszcie jest pobieranie liczby postów według typu postu przez autora / użytkownika. Generalnie staram się trzymać przy użyciu WP_Query()podczas uruchamiania zapytań do postów, ale to zapytanie wymagałoby użycia tak wielu innych haków, że po prostu łatwiej było być „niegrzecznym” i robić wszystko w jednym.

Pominąłem którykolwiek post $post->post_typejest 'revision'lub 'nav_menu_item'pozostało w 'attachments'. Może się okazać, że lepiej jest jawnie dołączyć typy postów, które chcesz, zamiast wykluczać kilka, które zrobiłem.

Filtrowałem też według $post->post_statustylko 'publish'i 'pending'. Jeśli chcesz także 'future', 'private'i / lub 'draft'trzeba wprowadzić zmiany w kodzie.

Przy każdym ładowaniu strony wywołuję tę _yoursite_get_author_post_type_counts()funkcję tylko raz, a następnie zapisuję w zmiennej statycznej zamiast wywoływać dla każdego użytkownika. Przechowuję w tablicy indeksowanej według identyfikatora autora / użytkownika zawierającej tablicę z nazwą typu postu w elemencie 'label'i oczywiście liczbą w elemencie o tej samej nazwie:

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

Wynikowy interfejs użytkownika

I tak to wygląda w przypadku mojej instalacji testowej WordPress 3.0.1:


(źródło: mikeschinkel.com )

Pobierz pełny kod

Możesz pobrać pełny kod z Gist :

Możesz skopiować ten kod do functions.phppliku motywu lub zapisać plik we wtyczce, cokolwiek wybierzesz.

Mam nadzieję że to pomoże!

MikeSchinkel
źródło
Cóż, to łatwe. Wystarczyło powiedzieć, że używa „zarządzaj _ {$ typ} _kolumny” i „zarządzaj _ {$ typ} _ niestandardowa_kolumna”, gdzie $ typ = użytkownicy, a ja mógłbym dowiedzieć się o tym resztę. Miałem wrażenie, że tak, ale sprawdziłem to i nie widziałem użytkowników. Reszta jest dość łatwa. Doceniam wysiłek włożony w to i na pewno będę głosować na ciebie w WPHonors (ponieważ już mam) goo.gl/CrSi Dziękuję bardzo: D
jaredwilli
1
@jaredwilli - Tak, oczywiście. Ale celem WordPress Answers jest udzielenie odpowiedzi osobom znacznie wykraczającym poza pierwszą osobę, która o to poprosi. Właśnie dlatego piszę dogłębnie, chociaż możesz potrzebować tylko fragmentów informacji, które inni mogą być zupełnie nowi w tym podejściu. Próbuję pomóc obu. Aha, i dziękuję za miłe komentarze na stronie (i czy mógłbym zmienić to zdjęcie? :)
MikeSchinkel
Tak, dlatego nie powstrzymałem cię od powiedzenia mi haka, którego potrzebowałem. Wiem, że nie będę jedyną potrzebą, więc wszystko jest w porządku.
jaredwilli
Och przepraszam, oczywiście że tak. Byłem rozproszony przez niestandardowy typ postu, który robię dla witryny sklepu, którą buduję. Nie sądzę, że wymyśliłeś sposób, aby połączyć liczbę postów ze stroną edit.php pokazującą posty dla ich autorów? Prawdopodobnie muszę to wbudować w moje zgadywanie CPT.
jaredwilli 24.10.10
@jaredwilli - Ach, tak, ale wygląda na to, że @somatic to dla ciebie zrobił, prawda?
MikeSchinkel
2

Oto odmiana odpowiedzi sorich87, ponieważ nie mogłem zmusić go do pracy i chciałem automatycznie obsługiwać wiele typów:

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

Czytam dalej get_posts_by_author_sql()i jak to ma dla ciebie skonstruować instrukcję WHERE, ale wyniki, które otrzymywałem były zawsze „1 = 0”. Właśnie napisałem resztę instrukcji SQL, co get_posts_by_author_sql()oszczędza tylko pisania dwóch bitów: typu postu i autora:

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

Działa to równie dobrze i doda tyle kolumn, ile chcesz, ale każda z nich zajmuje przestrzeń poziomą, podczas gdy samouczek Mike'a doda jedną kolumnę dla niestandardowych typów postów, a następnie wyświetli listę jako tabelę w tym rzędzie. Te same informacje, inna wizualizacja. Metoda Mike'a jest prawdopodobnie lepsza w przypadku dużych ilości typów, ponieważ tworzy skondensowaną listę pionową (i wyświetla tylko element liczenia, jeśli nie jest pusty), podczas gdy metoda sorich87 jest dobra dla mniejszych ilości, ponieważ jest tylko tyle dostępnego miejsca w poziomej kolumnie.

Nie zapomnij, że możesz dodać do zapytania „post_status = opublikować”, aby zwrócić tylko opublikowane elementy, ponieważ przykład obecnie zwraca wszystkie posty ...

somatyczny
źródło
Świetny! get_posts_by_author_sql( $column, true, $user_id );powinien skonstruować instrukcję where.
sorich87
1

Dodają to:

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
źródło
@ sorich87 - get_posts_by_author_sql()co? Ten jest dla mnie nowy; dzięki! Ale właśnie sprawdziłem twój kod i nie sądzę, że robi to, czego się spodziewał. Twoje get_posts_by_author_sql()połączenie zawsze powraca '1=0”, a on chciał uzyskać listę zliczeń według typu posta dla użytkownika; chyba że źle zrozumiem ten kod tego nie robi. Może możesz to naprawić?
MikeSchinkel
Tak, źle zrozumiałem pytanie. Mój kod doda tylko jedną kolumnę dla jednego niestandardowego typu postu. Wystarczy zastąpić post_typenazwą typu posta. Np .: get_posts_by_author_sql( 'book', true, $user_id );dla typu posta o nazwie „książka”. Przetestowane i działa.
sorich87 24.10.10
PS: Głosowałem również na ciebie w WPHonors. Zdecydowanie na to zasłużyłeś!
sorich87 24.10.10
Muszę to jeszcze przetestować, ale wygląda na to, że zadziałałoby, po prostu może nie mieć całej funkcjonalności, której szukam, ale nadal łatwo ją dodać. Dzięki :)
jaredwilli 24.10.10
@ sorich87 - Awesome!
MikeSchinkel