Отображение количества сообщений пользователя по типу пользовательской записи в списке пользователей администратора?


9

Я пытаюсь выяснить, как подключиться к /wp-admin/users.phpстранице управления, чтобы создать настраиваемые столбцы для отображения количества сообщений, которые пользователи имеют для пользовательских типов сообщений на WPHonors.com .

Я создал для этого трейк- билет, но @nacin объяснил, почему вместо этого плагину нужно больше работать.

Мне не удалось найти способ манипулирования выводом таблицы пользователей, поэтому я могу добавить пользовательские столбцы для количества сообщений CPT для каждого пользователя. И это может иметь какое-то отношение к вопросу, заданному @nacin, на что будут ссылаться цифры количества сообщений. Для текущего подсчета сообщений, которое имеет пользователь, он ссылается на страницу управления сообщениями, показывая все сообщения для этого пользователя ( /wp-admin/edit.php?author=%author_id%).

Если бы я должен был связать это где-нибудь, это было бы к:

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

Если бы это было хоть как-то возможно, я думаю. Но мне даже не обязательно связывать это где-либо. В основном я хочу просто показать количество сообщений CPT для каждого человека, количество 600пользователей и общее количество 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

Предполагая, что я понял вопрос, вам нужно подключиться к двум хукам, связанным с заголовками столбцов и значением столбцов для страниц администрирования администратора. Они 'manage_{$type}_columns'и 'manage_{$type}_custom_column'где в вашем потребительная случае {$type}это users.

'manage_users_columns'крюк

Первый простой, он позволяет вам указать заголовки столбцов и, следовательно, доступные столбцы. WordPress жестко кодирует значение столбца «Posts», поэтому, так как вы хотите изменить его, мы просто удалим его, 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()при выполнении запросов к сообщениям, но для этого запроса потребовалось бы использовать так много других хуков, что просто было бы легче "непослушным" и делать все в одном.

Я опустил любой пост $post->post_typeIS 'revision'или'nav_menu_item' , но оставили в 'attachments'. Возможно, вам будет лучше явно включить типы сообщений, которые вы хотите, а не исключать те, которые я сделал.

Я также отфильтровал $post->post_statusтолько 'publish'и 'pending'. Если вы хотите также включить 'future','private' и / или 'draft'вам нужно будет внести изменения в код.

Для каждой загрузки страницы я вызываю эту _yoursite_get_author_post_type_counts()функцию только один раз и затем сохраняю в статическую переменную, а не вызываю для каждого пользователя. Я храню в массиве, проиндексированном по идентификатору автора / пользователя, содержащему массив с именем типа сообщения в элементе '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;
}

Результирующий интерфейс

И вот как это выглядит применительно к моей тестовой установке 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 Ответы состоит в том, чтобы предоставлять ответы людям, выходящим далеко за рамки первого запроса. Вот почему я пишу подробно, хотя вам может понадобиться только немного информации, а другие могут быть совершенно новыми для этого подхода. Пытаюсь помочь обоим. О, и спасибо за хорошие комментарии на сайте (и шанс, что я мог бы изменить эту фотографию, хотя? :)
MikeSchinkel

Да, именно поэтому я не остановил вас от того, чтобы просто рассказать мне о крючке, который мне нужно было использовать. Я знаю, что я не буду единственным, кто найдет в этом необходимость, так что все хорошо.
Джаредвилли

Извините, конечно, я буду. Я был отвлечен заказным постом, который я создаю для магазина, который я строю. Я не думаю, что вы нашли способ связать количество сообщений со страницей edit.php, показывающей сообщения для их авторов? Наверное, нужно встроить это в мой CPT.
Джаредвилли

@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()избавляет вас от необходимости писать два бита: тип записи и автор:

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

Это работает так же хорошо, и добавит столько столбцов, сколько вы хотите, но каждый из них занимает горизонтальное пространство, в то время как учебник Майка добавит один столбец для пользовательских типов записей, а затем перечислит их в виде таблицы в этой строке. Та же информация, другая визуализация. Mike's, вероятно, лучше подходит для большого количества типов, так как он создает сжатый вертикальный список (и отображает только элемент подсчета, если не пустой), в то время как метод sorich87 хорош для меньших количеств, поскольку доступно только так много горизонтальных столбцов.

Не забудьте, что вы можете добавить «post_status = publish» к запросу, чтобы возвращать только опубликованные элементы, так как в настоящее время в примере возвращаются все сообщения ...


Большой! get_posts_by_author_sql( $column, true, $user_id );должен построить оператор where.
sorich87

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

Да, я неправильно понял вопрос. Мой код будет добавлять только один столбец для одного пользовательского типа сообщения. Просто замените post_typeна название типа сообщения. Например: get_posts_by_author_sql( 'book', true, $user_id );для сообщения типа «книга». Проверено и все работает.
sorich87

PS: Также проголосовал за вас на WPHonors. Вы определенно заслуживаете этого!
sorich87

Я еще не протестировал это, но похоже, что он будет работать, но может не иметь всех функций, которые я ищу, но это легко добавить. Спасибо :)
Джаредвилли

@ sorich87 - Отлично!
MikeSchinkel
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.