0

I'm looking to display a weekly list of 'Popular Posts' on a site. Currently the list shows a 'Popular Posts' column but these are posts from no particular timeframe. It's displaying the most popular posts from the beginning of the website.

Here's my code...

// Track post view count for popular posts
function track_post_view( $post_id ) {
$count_key  = 'post_views_count';
$count      = get_post_meta( $post_id, $count_key, true );

if( ! $count ) {
    $count = 0;
}

return update_post_meta( $post_id, $count_key, ++$count );
}

// Get popular posts
function get_popular_posts( $limit = 3 ) {
// WP_Query arguments
$args = array (
    'post_type'             => 'post',
    'post_status'           => 'publish',
    'posts_per_page'        => $limit,
    'order'                 => 'DESC',
    'orderby'               => 'meta_value',
    'meta_key'              => 'post_views_count',
    'meta_type'             => 'NUMERIC',
);

// The Query
$popular = new WP_Query( $args );

// Restore original Post Data
wp_reset_postdata();

return $popular;
}

So, is this doable? If so, anyone able to suggest a method? I've had a look through various similar questions, but haven't found a concrete answer.

Thanks in advance.

  • By "weekly" do you mean posted in the past week or viewed in the past week? – cameronjonesweb Jul 6 '15 at 3:12
  • @user1672694 Viewed in the last week. – Kelvin Farrell Jul 6 '15 at 7:49
0

The best way to do this would be to set up a custom table. For each view you would add a new row which would contain (at least) a uid, the post id and the date/time. The beauty of this method is you can store as much data per view as you like, such as IP or the current user if they're logged in. I can't really give any more advise than that as I've never attempted to use custom tables however there are plenty of plugins out there that can do it. The codex article can be found here.

Another way to do it would be using post meta similar to how you've been doing it. What you do is store an array of view times. This way, you wouldn't have to store the view count although I'm sure you'd want to keep the old data for the purpose of records. However this would end up with a really bloated function trying to sort your posts.

I've done up some code below that should work in theory but I haven't had a chance to test it.

//Track page view
function track_post_view( $post_id ) {
    $views_key  = 'post_views_times';
    $views = get_post_meta( $post_id, $views_key, true );
    $count = count( $views );

    if( $count === 0 ) {
        $views = array();
    }

    //Adds another entry to the views with the current UNIX timestamp
    $views[] = time();

    return update_post_meta( $post_id, $views_key, $views );
}

//Get all posts

function get_popular_posts( $limit = 3 ) {

    $all_posts = new WP_Query( 'post_type' => 'post', 'post_status' => 'publish' );

    //Store these posts
    while($all_posts->get_posts()){
        $all_posts->the_post();
        $post_views = get_post_meta( get_the_ID(), 'post_views_times' );
        $week_ago_time = time() - 7 * 24 * 60 * 60; //This is the timestamp of 1 week ago
        for( $i = 0; $i < count( $post_views ); $i++ ){
            if( $post_views[$i] < $week_ago_time ){ 
                unset($post_views[$i]); //If the timestamp is less than 1 week ago get remove it from the variable
            }
        }
        $posts_list[] = array( 'views' => count( $post_views ), 'post_id' => get_the_ID() );
    }

    //Get the column to sort the $posts_list by
    foreach ($posts_list as $key => $row) {
        $views[$key]  = $row['volume'];
    }

    array_multisort( $views, SORT_DESC, $posts_list ); //This sorts descending by views.

    //Get the top 3 viewed posts and store that it yet another array
    for( $i = 0; $i < $limit; $i++ ){
        $most_viewed_ids[] = $posts_list[$i]['post_id'];
    }

    $popular = new WP_Query( 'p' => $most_viewed_ids ); //Run a query getting our 3 top posts

    wp_reset_postdata();

    return $popular;

}

I hope this answer helps in some way or another

  • Thanks. Unfortunately that didn't work. It causes an error and the functions.php file needs to be reset to previous version. – Kelvin Farrell Jul 18 '15 at 0:15
  • @KelvinFarrell what is the error? – cameronjonesweb Jul 18 '15 at 3:50
  • I'm not sure. After I save the changes, it just fails to load any page on the website and shows only a blank white screen. – Kelvin Farrell Aug 6 '15 at 11:50
  • @KelvinFarrell ok that means that's it's giving a fatal error but your debug is turned off, so the error message is hidden. Here's how you can turn on WP_DEBUG: premium.wpmudev.org/blog/… – cameronjonesweb Aug 6 '15 at 12:49

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.