I am implementing a section in my website to get the top 5 authors using this code.

function ranked_authors(){

$usrs = get_users('role=contributor');

  $countarr = array();

  foreach ($usrs as $usr) {

    $post_views = total_no_of_post_views($usr->ID); 
    $countarr[$usr->ID] = $post_views;


  foreach($countarr as $id => $pcount){
    $div_media = '<div class="media clearfix">
    <div class="media-left">';
        $author_link = get_author_posts_url($id);
        $author_name = get_the_author_meta('display_name',$id);
        $avatar = get_avatar_url( $id, 'size=50' );
        $div_media .= '<a href="'.$author_link.'">'.get_avatar($id, 'size=50').'
            <span class="rank">'.$i.'</span>

    <div class="media-body">';
        $div_media .= '<h4 class="media-heading"><a href="'.$author_link.'">'.$author_name.'</a></h4>'.$pcount.' Total Views</div>
        echo $div_media;


I am having more than 4000 post on my blog so this query is taking so much time to execute and it almost taking 10 second to process and return the data from the server. Then i thought of Doing it in ajax way. But there is a problem in my code that it doesn't return me any data in ajax request when i am returning(return) the result but if i echo this function then it returns me the data through ajax request. I don't know but is wrong i am doing.

I want to sort the authors according to the total no of post views.this is the function i am using to count total no of post views.

function total_no_of_post_views($author_id){

    $sumViews = 0;
    $args = array(
        'author'    => $author_id,
        'post_type' => array('communityposts','post','video'),
        'posts_per_page'=> -1
    $author_query = new WP_Query( $args );

    if( $author_query->have_posts() ) : while( $author_query->have_posts() ) : $author_query->the_post();
        $sumViews += get_post_meta( get_the_ID(), 'cv_post_views_count', true );
    endwhile; endif;
    return $sumViews;

My final requirements is to calculate top 5 authors sorted according to the total no. of post views value of their published posts.

3 Answers 3


You need a custom query - this will join the posts, postmeta and usermeta table together and then count all communityposts, post and video views, grouped by author:

function wpse_190303_get_popular_users( $number = 5 ) {
    if ( ! $number = absint( $number ) )

    global $wpdb;

    $query = "
    SUM( $wpdb->postmeta.meta_value+0 ) AS `post_views`,
    $wpdb->usermeta.user_id AS `user_id`
    $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id
    $wpdb->usermeta ON $wpdb->posts.post_author = $wpdb->usermeta.user_id
    $wpdb->posts.post_type IN( 'communityposts', 'post', 'video' ) AND
    $wpdb->posts.post_status = 'publish' AND
    $wpdb->postmeta.meta_key = 'cv_post_views_count' AND
    $wpdb->usermeta.meta_key = '{$wpdb->prefix}capabilities' AND
    $wpdb->usermeta.meta_value LIKE '%\\\"contributor\\\"%'
    post_views DESC

    if ( $result = $wpdb->get_results( $query ) )
        cache_users( wp_list_pluck( $result, 'user_id' ) );

    return $result;

To use:

if ( $data = wpse_190303_get_popular_users() ) {
    foreach ( $data as $item ) {
        $user_id = $item->user_id;
        $views   = $item->post_views;

        // Your code to output the popular authors
  • Thanks @TheDeadMedic . It works like a charm . Thank you so much Jun 29, 2015 at 17:21

I am not sure what approach you are using to send ajax request, but if you are using WordPress standard code for Ajax requests. Source: https://codex.wordpress.org/AJAX_in_Plugins

There are two issues with your current code.

1) You are echoing inside the loop, don't do it, concat all the author html inside loop, and once loop ends only than echo it.

2) Use die(); at the end of this function, it's necessary for Ajax request to be successfully completed.

and you can't return the content, you will have to echo it.

  • Thanks Syed for your answer, I am following the wordpress Standard code for Ajax Request. I will try to tweak my code as you mentioned the two issues in my code. Jun 3, 2015 at 10:10

What you're doing is extremely inefficient - I'm guessing total_no_of_post_views runs a count query on the posts table for just one user?

Instead, use the arguments available for get_users to get the top 5 authors during the query (instead of looping over all of them and counting each user's posts):

        'role'        => 'contributor',
        'number'      => 5, // Number of users to retrieve
        'count_total' => false, // Don't SQL_CALC_FOUND_ROWS
        'meta_key'    => 'cv_post_views_count',
        'orderby'     => 'meta_value_num',
        'order'       => 'DESC',
  • 1
    Hi Edited the Question for your reference where i added the code for my function which i am using to count the total no. of post views and i want to sort the user according to this value Jun 3, 2015 at 12:33
  • I see you count by post type - will need a rethink. You can still greatly improve your speed by using MySQL to get the top 5 contributors (as opposed to looping over all of them and using PHP to calculate the numbers). Jun 3, 2015 at 13:34
  • i am a newbie with mysql , I don't know how can i do that . Jun 3, 2015 at 14:04
  • I took another look at your code - we can avoid the custom query since you're using a custom user meta "views" attribute (I originally thought we were talking about post published count) - see my revised answer. Jun 3, 2015 at 14:16
  • Scrap that, sorry, I'm not thinking straight. This answer is invalid and I will delete once you've got this comment. Jun 3, 2015 at 14:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.