In my WordPress v5.8.1, I have a list of authors who post in custom posts song
and poem
. With the below code I am getting the list of authors who posted in the both or either in one custom post.
$authors = get_users(array(
'who' => 'authors',
'has_published_posts' => array('song','poem'),
'orderby' => 'post_count',
'order' => 'DESC',
'number' => '15'
));
Below code is listing all the authors with their post counts:
foreach ($authors as $user) {
$name = $user->first_name . ' ' . $user->last_name;
$songs = count_user_posts($user->ID, $post_type = "song");
$poems = count_user_posts($user->ID, $post_type = "poem");
echo $name.' has '. $songs .' songs, and '. $poems .' poems;
}
With 'orderby' => 'post_count'
in the arguments, I expected the authors list with highest combined custom posts count displayed first, however it is showing randomly with no order, neither by post_counts
nor ID
.
How can I order the authors with most combined total posts?
Try below code.
$authors = get_users(array(
'who' => 'authors',
'has_published_posts' => array('song','poem'),
'orderby' => 'post_count',
'order' => 'DESC',
'number' => '15'
));
Create one array
and count total poem + songs
$author_posts = array();
foreach ($authors as $user) {
$name = $user->first_name . ' ' . $user->last_name;
$songs = count_user_posts($user->ID, $post_type = "song");
$poems = count_user_posts($user->ID, $post_type = "poem");
$author_posts[] = array(
'total' => $songs+$poems,
'label' => $name.' has '. $songs .' songs, and '. $poems .' poems'
);
}
now use `usort to sort an array by total.
usort($author_posts, function($a, $b) {
if($a['total']==$b['total']) return 0;
return $a['total'] < $b['total']?1:-1;
});
print the output.
foreach ( $author_posts as $key => $author_post ) {
echo $author_post['label']."</br>";
}
Complete code.
$authors = get_users(array(
'who' => 'authors',
'has_published_posts' => array('song','poem'),
'orderby' => 'post_count',
'order' => 'DESC',
'number' => '15'
));
$author_posts = array();
foreach ($authors as $user) {
$name = $user->first_name . ' ' . $user->last_name;
$songs = count_user_posts($user->ID, $post_type = "song");
$poems = count_user_posts($user->ID, $post_type = "poem");
$author_posts[] = array(
'total' => $songs+$poems,
'label' => $name.' has '. $songs .' songs, and '. $poems .' poems'
);
}
usort($author_posts, function($a, $b) {
if($a['total']==$b['total']) return 0;
return $a['total'] < $b['total']?1:-1;
});
foreach ( $author_posts as $key => $author_post ) {
echo $author_post['label']."</br>";
}
Tested and works.
First, the orderby argument of function get_users() works with post_count but counts all post types (here, it is counting poem, song and the others types like post or page).
If you want to order your results by specific custom post types, I would recommend to use the wpdb class to design your own request. This allows you to get the exact desired results with one single request and no need to use a foreach to sort your results after.
I tried this way and it worked:
$authors = $wpdb->get_results(
"SELECT
$wpdb->users.ID AS author_id,
$wpdb->users.display_name AS author_name,
COUNT($wpdb->posts.ID) AS published_songs_and_poems,
COUNT(CASE WHEN $wpdb->posts.post_type = 'song' THEN $wpdb->posts.ID ELSE NULL END) as published_songs,
COUNT(CASE WHEN $wpdb->posts.post_type = 'poem' THEN $wpdb->posts.ID ELSE NULL END) as published_poems
FROM $wpdb->users
JOIN $wpdb->posts
ON $wpdb->posts.post_author = $wpdb->users.ID
AND $wpdb->posts.post_type IN('song', 'poem') AND $wpdb->posts.post_status = 'publish'
GROUP BY author_id
ORDER BY published_songs_and_poems DESC"
);
This request return an object with results grouped by author and order by total amount of published songs and poems.
You can use this object as you already did. Something like this :
array_walk($authors, function($author) {
echo $author->author_name." has published ".$author->published_songs." song(s) and ".$author->published_poems." poem(s).<br/>";
});
I edited this answer because the first version focused on how to return the results order by total post_count. This was clarified when commented by @theKing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With