Display a list of users who have viewed the post you are viewing

Here you go Pete, hope this is the “happy ending” you had in mind… LOL!

First thing we want to do is A) record the IDs of logged in users as post metadata and B) generate a template tag that we can use to display that data somewhere.

Second, we want to drop that template tag into either your single.php or a template-part that displays singular post content.

I’ve commented throughly throughout the code so you can see what I did and so that I don’t have to break it up into chunks here. Just easier for you if you can see the whole block in one place.

The code below was written for inclusion in a theme’s/child theme’s functions.php file, but if you wanted to you could easily convert it to a plugin.

<?php
// First we run a function in the wp_head or wp_footer where we capture the ID of logged in users and save them to an array in postmeta.
function track_Petes_viewers() {
    //If the viewer isn't logged in, the rest is pointless, so we check this first.
    if( is_user_logged_in() ) :
        global $post;
        //Lets set a nonce.
        $viewers_nonce  = wp_create_nonce( 'viewers_nonce_' . $post->ID );
        //Get the current user's ID.
        $userID         = get_current_user_id();
        //Lets check if this post already has a list of viewers so we can add to it.
        $viewers        = get_post_meta( $post->ID, 'petes_viewers', true );  
        //If this post doesn't already have this meta, lets set up an empty array.
        if( empty( $viewers ) ) :
            $viewers = array();
        endif;
        //Now we add the current user's ID to the array.
        $viewers[]      = $userID;
        //We don't want users being recorded twice, we just need to know if they viewed it, not how may times
        //So we're going to run array_unique() to make sure each ID is only in there once.
        $viewers_list   = array_unique( $viewers );
        //We verify the nonce and if it works, we update_post_meta(), if not, we kill the process.
        if( !wp_verify_nonce( $viewers_nonce, 'viewers_nonce_' . $post->ID ) ) :
            die();
        else :
            //If the postmeta doesn't exist, update_post_meta will create it, so we don't need to also use add_post_meta
            update_post_meta( $post->ID, 'petes_viewers', $viewers_list );
        endif;
    endif;
}
//We're going to drop it in the wp_head, but you can change this to a different hook
add_action( 'wp_head', 'track_Petes_viewers' );

//Now we generate a template tag that we can drop into our single view of posts, wherever you like, to display a list of viewers
function display_Petes_viewers() {
    global $post;
    //Not sure what you're using this for, but let's ONLY show this on posts
    if( get_post_type( $post->ID ) == 'post' ) :
        //We get the post meta for viewers
        $viewers_list   = get_post_meta( $post->ID, 'petes_viewers', true );
        //If there is a record in the DB for this particular post, we'll cycle through the IDs and spit out names
        if( !empty( $viewers_list ) ) :
            //Let's wrap the whole thing in a <ul>
            echo '<ul id="petes_viewers">';
            foreach( $viewers_list as $viewer ) :
                //We user the ID numbers to get the User object
                $viewer_info    = get_userdata( (int)$viewer );
                //ADDED: Let's check if the user still exists.
                if( $viewer_info != false ) :
                    //We pull the display_name from the User object
                    //You can pull additional info using this pattern, like the email, the link to their profile, their first/lastname, etc.
                    $viewer_name    = $viewer_info->display_name;
                    //and now we echo out whatever data we pulled from the user object, format this however you like
                    echo '<li>' . $viewer_name . '</li>';
                endif; 
            endforeach;
            echo '</ul><!--#petes_viewers-->';
        endif;
    endif;
}
?>

You now have a function that is recording the IDs of logged in users as they view posts. You then also have a second function that checks to see if this metadata exists and if it does, it generates a bullet list of display names of the users that HAVE viewed that particular post.

To use this second function you simply drop the following code into whichever theme template you want, ie. single.php.

<?php display_Petes_viewers(); ?>

Now, there’s a number of things that could be improved upon… …like, are we displaying the list of people that viewed the post to the general public? Or are we only displaying it to other logged in users? Or are we only displaying it to administrators or editors?

Second, when I’m logged in and viewing a post for the first time, my display name won’t show up (not the first time), do we want to get all fancy and add the current user to the list if they’re not already on it?

But those are relatively simple modifications you could make.

Hope this helps and if it does please remember to accept the answer. 🙂