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 ♦Aug 31, 2014 at 17:37
-
-
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. 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? 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()
– WyckDec 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 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.