Hiển thị số lượng bài đăng của người dùng theo loại bài đăng tùy chỉnh trong danh sách người dùng của quản trị viên?


9

Tôi đang cố gắng tìm ra cách nối vào /wp-admin/users.phptrang quản lý để tạo các cột tùy chỉnh để hiển thị số lượng bài đăng mà người dùng có cho các loại bài đăng tùy chỉnh trên WPHonors.com .

Tôi đã tạo một vé trac cho việc này nhưng @nacin đã giải thích lý do tại sao đó là công việc nhiều hơn cho một plugin để làm thay thế.

Tôi đã không thể tìm ra cách nào để thao tác đầu ra của bảng người dùng, vì vậy tôi có thể thêm các cột tùy chỉnh cho số lượng bài đăng của CPT cho mỗi người dùng. Và điều đó có thể có liên quan đến câu hỏi @nacin đã hỏi, số lượng bài đăng sẽ liên kết đến cái gì. Đối với số bài đăng 'bài đăng hiện tại mà người dùng có, nó liên kết đến trang quản lý bài đăng, hiển thị tất cả các bài đăng cho người dùng đó ( /wp-admin/edit.php?author=%author_id%).

Nếu tôi liên kết nó ở đâu đó, nó sẽ là:

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

Nếu điều đó thậm chí có thể bằng cách nào đó, tôi đoán. Nhưng tôi thậm chí không nhất thiết phải liên kết nó với bất cứ nơi nào. Tôi hầu như chỉ muốn hiển thị số lượng bài đăng CPT cho mỗi người, có 600người dùng và tổng số 300+bài đăng kết hợp trên 4các loại bài đăng tùy chỉnh. Quản trị viên chỉ là một người có thể gửi 'post'bài đăng, do đó, cột trong trang của người dùng là vô dụng.

Câu trả lời:


10

Đây là một bản mở rộng của câu trả lời hướng dẫn của Mike. Tôi đã thêm các liên kết đến các loại được liệt kê để bạn có thể nhấp vào một và được đưa thẳng vào danh sách tất cả các bài đăng trong loại đó cho tác giả đó, yêu cầu một biến bổ sung cho $countsvà một số đầu ra bổ sung cho$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

Giả sử tôi đã hiểu câu hỏi, điều bạn cần làm là móc vào hai móc liên quan đến tiêu đề cột và giá trị cột cho các trang quản lý quản trị viên. Họ 'manage_{$type}_columns''manage_{$type}_custom_column'nơi sử dụng hợp cụ thể của bạn {$type}users.

Cái 'manage_users_columns'móc

Cái đầu tiên này rất đơn giản, nó cho phép bạn chỉ định các tiêu đề cột và do đó các cột có sẵn. WordPress mã hóa giá trị của cột "Bài viết" vì vậy vì bạn muốn thay đổi nó, chúng tôi chỉ cần xóa nó đi unset()và sau đó thêm một cột mới có cùng tiêu đề nhưng thay vào đó có định danh '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;
}

Cái 'manage_users_custom_column'móc

Tiếp theo, bạn cần sử dụng 'manage_users_custom_column'hook chỉ được gọi cho các cột không chuẩn. Chúng tôi kiểm tra $column_name=='custom_posts'để làm cho mã của chúng tôi mạnh mẽ trong trường hợp chúng tôi thêm các cột người dùng mới trong tương lai và sau đó chúng tôi lấy số lượng bài đăng của người dùng từ chức năng tôi đã viết _yoursite_get_author_post_type_counts()mà tôi sẽ thảo luận tiếp theo. Sau đó tôi đã chơi với một vài cách để định dạng này nhưng quyết định HTML <table>là phù hợp nhất (vì đó bảng dữ liệu) . Nếu một bảng không hoạt động với bạn, tôi cho rằng bạn sẽ có thể tạo các đánh dấu khác nhau khá dễ dàng:

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

Nhận số lượng bài viết theo loại bài đăng cho mỗi người dùng / tác giả

Cuối cùng là việc truy xuất số lượng bài đăng theo loại bài đăng của tác giả / người dùng. Nói chung, tôi cố gắng sử dụng WP_Query()khi chạy truy vấn trên các bài đăng nhưng truy vấn này sẽ yêu cầu sử dụng rất nhiều hook khác, nó dường như dễ "nghịch ngợm" hơn và thực hiện tất cả trong một.

Tôi đã bỏ qua bất kỳ bài đăng nào $post->post_type'revision'hoặc 'nav_menu_item'nhưng để lại 'attachments'. Bạn có thể thấy tốt hơn là bao gồm rõ ràng các loại bài đăng bạn muốn thay vì loại trừ số ít tôi đã làm.

Tôi cũng được lọc bởi $post->post_statuschỉ 'publish''pending'. Nếu bạn cũng muốn bao gồm 'future', 'private'và / hoặc 'draft'bạn sẽ cần thực hiện các thay đổi trong mã.

Đối với mỗi lần tải trang, tôi chỉ gọi _yoursite_get_author_post_type_counts()hàm này một lần và sau đó lưu vào một biến tĩnh thay vì gọi cho mỗi người dùng. Tôi lưu trữ trong một mảng được lập chỉ mục bởi ID tác giả / người dùng có chứa một mảng có tên Loại bài đăng trong thành phần 'label'và tất nhiên số lượng trong một thành phần cùng tên:

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

UI kết quả

Và đây là giao diện được áp dụng cho bản cài đặt thử nghiệm WordPress 3.0.1 của tôi:


(nguồn: mikechinkel.com )

Tải xuống toàn bộ mã

Bạn có thể tải xuống mã đầy đủ từ Gist :

Bạn có thể sao chép mã này vào functions.phptệp hoặc cửa hàng của chủ đề bao gồm tệp trong plugin, tùy theo bạn chọn.

Hi vọng điêu nay co ich!


Vâng, đó là dễ dàng. Tất cả những gì bạn phải làm là nói rằng nó sử dụng 'Manage _ {$ type} _columns' và 'Manage _ {$ type} _custom_column' trong đó $ type = users và tôi có thể tìm ra phần còn lại từ đó. Tôi có cảm giác như vậy, nhưng tôi đã kiểm tra và không thấy người dùng. Phần còn lại là đủ dễ dàng. Tôi đánh giá cao nỗ lực sâu rộng mà bạn đã bỏ ra và chắc chắn tôi sẽ bỏ phiếu cho bạn trên WPHonors (vì tôi đã có) goo.gl/CrSi Cảm ơn rất nhiều: D
jaredwilli

1
@jaredwilli - Vâng tất nhiên. Nhưng mục tiêu trả lời của WordPress là cung cấp câu trả lời cho những người vượt xa người đầu tiên hỏi. Đó là lý do tại sao tôi viết sâu, mặc dù bạn có thể chỉ cần một chút thông tin mà người khác có thể hoàn toàn mới đối với phương pháp này. Cố gắng giúp cả hai. Ồ, và cảm ơn vì những bình luận tốt đẹp trên trang web (và cơ hội tôi có thể thay đổi bức ảnh đó chứ? :)
MikeSchinkel

Vâng, đó là lý do tại sao tôi không ngăn bạn chỉ nói với tôi cái móc tôi cần sử dụng. Tôi biết tôi sẽ không phải là người duy nhất tìm thấy nhu cầu này vì vậy mọi thứ đều tốt.
jaredwilli

Oh xin lỗi, tất nhiên tôi sẽ. Tôi đã bị phân tâm bởi một loại bài đăng tùy chỉnh Im làm cho một trang web cửa hàng Im xây dựng. Tôi không cho rằng bạn đã tìm ra một cách để liên kết số lượng bài đăng với trang edit.php hiển thị một bài đăng cho các tác giả của chúng? Có lẽ cần phải xây dựng nó vào CPT Im đoán của tôi.
jaredwilli

@jaredwilli - À, vâng, nhưng có vẻ như @somatic đã làm điều đó cho bạn, phải không?
MikeSchinkel

2

Sau đây là một biến thể về câu trả lời của sorich87, vì tôi không thể khiến anh ấy làm việc và tôi muốn tự động hỗ trợ nhiều loại:

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

Tôi đã đọc get_posts_by_author_sql()và làm thế nào để xây dựng một câu lệnh WHERE cho bạn, nhưng kết quả tôi nhận được luôn là "1 = 0". Vì vậy, tôi chỉ viết phần còn lại của câu lệnh SQL, vì get_posts_by_author_sql()chỉ tiết kiệm cho bạn khi phải viết hai bit: loại bài đăng và tác giả:

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

Điều này cũng hoạt động tốt và sẽ thêm nhiều cột như bạn muốn, nhưng mỗi cột sử dụng không gian ngang, trong khi hướng dẫn của Mike sẽ thêm một cột cho các loại bài tùy chỉnh, sau đó liệt kê chúng thành một bảng trong hàng đó. Cùng một thông tin, hình dung khác nhau. Mike có lẽ tốt hơn cho số lượng lớn các loại, vì nó xây dựng một danh sách dọc cô đọng (và chỉ hiển thị một mục đếm nếu không trống), trong khi phương pháp của sorich87 là tốt cho số lượng nhỏ hơn, vì chỉ có rất nhiều phòng cột ngang.

Đừng quên bạn có thể thêm "post_status = xuất bản" vào truy vấn để chỉ trả về các mục đã xuất bản, vì ví dụ hiện trả về tất cả các bài đăng ...


Tuyệt quá! get_posts_by_author_sql( $column, true, $user_id );nên xây dựng câu lệnh where.
sorich87

1

Sau đây sẽ thêm nó:

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()hả? Đó là một cái mới đối với tôi; cảm ơn! Nhưng tôi chỉ kiểm tra mã của bạn và tôi không nghĩ nó làm được điều anh ấy mong đợi. Cuộc get_posts_by_author_sql()gọi của bạn luôn trả về '1=0'và anh ấy muốn nhận danh sách đếm theo loại bài đăng cho người dùng; trừ khi tôi hiểu nhầm mã này không làm điều đó. Có lẽ bạn có thể sửa nó?
MikeSchinkel

Vâng, tôi đã hiểu nhầm câu hỏi. Mã của tôi sẽ chỉ thêm một cột cho một loại bài đăng tùy chỉnh. Chỉ cần thay thế post_typebằng tên loại bài. Ví dụ: get_posts_by_author_sql( 'book', true, $user_id );đối với loại bài đăng có tên là 'cuốn sách'. Đã thử nghiệm và nó hoạt động.
sorich87

PS: Cũng đã bình chọn cho bạn trên WPHonors. Bạn chắc chắn xứng đáng với nó!
sorich87

Tôi vẫn chưa thử nghiệm điều này, nhưng có vẻ như nó sẽ hoạt động, có thể không có tất cả các chức năng tôi đang tìm kiếm, nhưng điều đó thật dễ dàng để thêm vào. Cảm ơn :)
jaredwilli

@ sorich87 - Tuyệt vời!
MikeSchinkel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.