I see that it is possible to sort a user query by the number of posts each user has, but is it possible to exclude users with zero posts from the result? In the Wp_User_Query class there is a pre_user_query
action, but query strings are a huge weak point, so I'm not sure what sort of filter action I'd want to use here.
3 Answers
Well I have come up with 2 solutions.
Solution 1 - foreach loop and verify each user
This one is based off of @GhostToast's solution, but with updated WordPress functions
//new query with default args
$author_query = new WP_User_Query();
// Get the results
$authors = $author_query->get_results();
if( $authors ) {
foreach( $authors as $author ) {
if ( count_user_posts( $author->id ) >= 1 ) {
echo $author->display_name . '</br>';
}
}
} else {
echo "no users found";
}
Solution 2 - fancy pants pre_user_query
action
This is what I was thinking of when I posted my question once I found the pre_user_query
action in the WP_User_Query
class. If you pass in post_count
as your orderby
parameter then some fancy SQL querying that I never would've figured out on my own happens to join the proper tables together. So what I did was copy that join statement and add it on to my own. This would be better if I could check for its presence first before adding it... perhaps I will use a string match in the future. But for now since I am the one setting up the query I know it isn't there and I just won't worry about it yet. So the code turned out like so:
function authors_with_posts( $query ) {
if ( isset( $query->query_vars['query_id'] ) && 'authors_with_posts' == $query->query_vars['query_id'] ) {
$query->query_from = $query->query_from . ' LEFT OUTER JOIN (
SELECT post_author, COUNT(*) as post_count
FROM wp_posts
WHERE post_type = "post" AND (post_status = "publish" OR post_status = "private")
GROUP BY post_author
) p ON (wp_users.ID = p.post_author)';
$query->query_where = $query->query_where . ' AND post_count > 0 ';
}
}
add_action('pre_user_query','authors_with_posts');
and then to use it
$args = ( array( 'query_id' => 'authors_with_posts' ) );
$author_query = new WP_User_Query( $args );
The idea for a query_id
parameter is from An Introduction to WP_User_Class
Which is also just a very good reference on WP_User_Query
-
1This is lovely. Now all we need is a way to adjust the pagination page count to the new reworked list...– Christine Cooper ♦Commented Aug 31, 2014 at 17:37
-
-
author->id is now author->ID (small change but id is depreciated) Commented Jan 26, 2018 at 10:19
Since 4.4, you can simply use the `has_published_posts' parameter.
Example:
$authors = get_transient('mytheme_all_authors');
if (empty($authors)){
$user_args = array(
'role__in' => array('Author', 'Administrator', 'Contributor'),
'orderby' => 'post_count',
'order' => 'DESC',
'count_total' => true,
'has_published_posts' => array('post'),
);
$authors = new WP_User_Query( $user_args );
set_transient('mytheme_all_authors', $authors, 1 * HOUR_IN_SECONDS );
}
$total= $authors->get_total();
$authors = $authors->results;
foreach ( $authors as $user) {
// loop through your users....
has_published_posts
can be either true/false (or null), or an array of post types (like in this example).
Note: I'm using transients here because this specific query can get pretty heavy depending on the system so it makes sense to store it for future uses.
Submitting as answer for closure:
$all_members = get_users();
foreach($all_members as $member){
$post_count = count_user_posts($member->ID);
if(empty($post_count)) {
$bad_writers[] = $member->ID;
continue;
} else {
// do something;
}
}
-
Is that the workaround required to get users of all roles? I'm finding that leaving that argument blank is not returning all the users in multisite. Commented Dec 19, 2012 at 18:40
-
get_users_with_role()
is not a WordPress function or have I been looking at my computer too long? Commented Dec 19, 2012 at 18:42 -
1It does not exists. Searching 966 files for
"get_users_with_role": 0 matches across 0 files
. Alsoget_usernumposts
is depreciated, usecount_user_posts()
– WyckCommented Dec 19, 2012 at 18:53 -
argh! my apologies. this was a function i wrote for a members based site. you can just use get_users() and pass whatever parameters you want to it: codex.wordpress.org/Function_Reference/get_users Commented Dec 19, 2012 at 20:15
-
post_count
== 0?get_posts_by_author_sql
function that generates the SQL for theget_authors()
query. Users must have a published or private post to be included in the results. #facepalmget_authors()
result as a transient... then I can simply skip the current author without needing to do a query every time.