WordPress – Getting Posts by User Role, combining two queries into one

I am building a website where certain users will be “premium” and certain users will be non premium. Both roles will be able to make posts, but in our post queries, we would like all posts made by “premium” users to be returned first, with a css class of “premium”, and then all non-premium posts returned after.

I need to do so in a way that preserves pagination.

Read More

I have the following query which I can use to return posts by user role:

<?php $premiums = get_users( array( 'role' => 's2member_level1, administrator' ) );
$premium_ids = array();
foreach( $premiums as $premium )
$premium_ids[] = $premium->ID;
$posts = new WP_Query( array( 'author' => implode( ',', $premium_ids ), 'post_type' => 'classifieds', 'paged' => get_query_var('paged') ) );
if ( $posts->have_posts() ) : while ( $posts->have_posts() ) : $posts->the_post(); 

// The post title, content, etc, encase in a PREMIUM css class

endwhile; 
endif; 
wp_reset_postdata(); ?>

The two roles specified above are our “premium” roles so all their posts should be returned first. The non premium roles use the “subscriber” role provided in WordPress.

For the non-premium posts, I was going to do a second query swapping out the role as needed, but I realized this would break pagination, or at least stop pagination from working in the traditional way.

Therefore, it seems to be clear that I need to have everything in a single query.

From reading posts such as the following, I know its possible to merge two queries into one, but I am not sure if this would be the best way to go.

https://wordpress.org/support/topic/multiple-queries-compiling-into-one-loop

Therefore, I am posting the question here to see if anyone might know of a way to query our premium users, return their posts, then query the non premium users and return their posts, all in one single query with a “premium” class on premium posts and a “non-premium” class on the non premium ones.

This is more of a PHP issue than a WordPress one I feel, so I have tagged this question as PHP first and WordPress second.

Hope someone can help.

Thanks

Related posts

1 comment

  1. As nobody seems to have any solution for this, I had to solve it with jQuery which was/is not ideal.

    My solution was to query the user role in each returned post and then use this as a var to assign a unique class to all “premium” posts. Then I use jQuery to move all premium posts to the top, into an empty div.

    The empty div goes before the loop:

    <div class="all-premium-posts"></div>
    

    Then in the loop:

            if(have_posts()): while(have_posts()):the_post();
            
            $user_id = $author_id;
            $user = new WP_User( $user_id );
            if ( !empty( $user->roles ) && is_array( $user->roles ) ) {
                foreach ( $user->roles as $role )
                    if($role == 's2member_level1') { 
                        $premium_post = 'premium-post';
                    }
            }
    

    And then on each post in the loop:

    <div class="post <?php echo $premium_post;?>">
    

    And then the jQuery:

    jQuery('.premium-post').prependTo('.all-premium-posts');
    

    The severe disadvantage of this is that I have to return all posts on one page.

    If there are hundreds of posts returned, it would cause a huge DB query and page load time.

    It works for us though as we auto-prune posts every 30 days, so posts per category / posts per page should never exceed 20-30 at most for us, thus making this a workable/usable solution in this scenario.

Comments are closed.