Display online Users on WordPress
Earlier today I ran into a problem where I needed a simple way to display which registered users are online right now on the site.
I’ve done a Video explaining what was my solution and how to apply it to a theme, but I myself hate when I see a video without any code that I can easily take a look at, so below the video you will find a explanation of the code step by step, and in the end the plugin I created for this purpose.
Please note that I will comment further the code on the video, but there are some comments on each one of the snippets here
—
Variables used
We will use only two variables on this plugin:
– static protected $_instance = null;
— Holds the static instance of our class after the plugin is initialized
– static protected $prefix = 'OnlineNow';
— Prefix we will use on the Database Options
Class Instance handling
When dealing with plugins in WordPress a good practice is to save a static variable of the main class on a private/protected variable and create a static method to instantiate the class whenever you call this method the first time:
static public function instance(){
null === self::$_instance and self::$_instance = new self;
return self::$_instance;
}
Plugin Initialization
Here is where our plugin will hook into WordPress and do the required actions to allot this plugin to work as we expect.
static public function init(){
// Lock this class to be initialized only once
if ( null !== self::$_instance ){
return false;
}
add_action( 'wp_login', array( self::instance(), 'login' ), 10, 2 );
add_action( 'clear_auth_cookie', array( self::instance(), 'logout' ), 10 );
// Register Shortcodes
add_shortcode( 'online:list', array( self::instance(), 'shortcode_list' ) );
add_shortcode( 'online:qty', array( self::instance(), 'shortcode_qty' ) );
add_filter( 'widget_text', 'do_shortcode' );
return true;
}
Register when a User logs in
We need to register when a user do the login so that we can save it in the database to grab this value and display for the users.
public function login( $user_login, $user ) {
$users = get_option( self::$prefix . '-users', array() );
if ( in_array( $user->ID, $users ) ){
return;
}
$users[] = $user->ID;
update_option( self::$prefix . '-users', $users );
}
Register when a User logs out
Just like when we register the action of login and add the user ID to the database option, now we will remove that ID when the user logs out.
public function logout() {
$users = get_option( self::$prefix . '-users', array() );
$user_id = get_current_user_id();
if ( ! in_array( $user_id, $users ) ){
return;
}
update_option( self::$prefix . '-users', array_diff( $users , array( $user_id ) ) );
}
Grab the users logged in
We need a method that will allow us to get the users from the database option, I’ve also allowed the developer to exclude or include a user to the list.
public function get_users( $include = array(), $exclude = array() ){
// Retrieve the users from Database
$users = get_option( self::$prefix . '-users', array() );
// Parse Shortcode atts to exclude
if ( is_string( $exclude ) ){
$exclude = array_map( 'trim', explode( ',', $exclude ) );
}
// Exclude users based on shortcode attribute
$users = array_diff( (array) $users, (array) $exclude );
// Parse Shortcode atts to include
if ( is_string( $include ) ){
$include = array_map( 'trim', explode( ',', $include ) );
}
// Include users based on shortcode attribute
$users = array_merge( (array) $users, (array) $include );
// Garantee that the array is safe for usage
$users = array_unique( array_filter( (array) $users ) );
// Remove all non existent users
$users = array_map( array( $this, 'user_exists' ), $users );
// Garantee that the array is safe for usage
$users = array_filter( (array) $users );
return $users;
}
Then I used a method inside of the `get_users` to check if the user exists before return the list of `WP_User` objects – *[on video](http://www.youtube.com/watch?v=k8W5O0Cpfog&t=19m47s)*.
public function user_exists( $user_id ){
$user = new WP_User( $user_id );
// Check if the users exists
if ( ! $user->exists() ){
return false;
}
return $user;
}
List Online Users Shortcode
After we did all the hard work of storing the data about user on the database, now we will use that information to print an HTML with the list of users that are currently online.
public function shortcode_list( $atts ) {
$atts = (object) shortcode_atts( array(
'avatar' => false,
'name' => true,
'link' => false,
'exclude' => '',
'include' => '',
'zero_text' => esc_attr__( 'There are no users online right now', 'online-now' ),
), $atts );
$html = '';
$users = $this->get_users( $atts->include, $atts->exclude );
$objects = array();
// Builds the objects
foreach ( $users as $id => $time ) {
$objects[] = new WP_User( $id );
}
if ( ! empty( $users ) ) {
$html .= '<ul class="users-online">';
foreach ( (array) $objects as $user ) {
// Always reset the Profile Link
$profile_link = null;
$html .= '<li>';
// Only start the link if we have the atts for it
if ( $atts->link ) {
// If the user can edit posts then show the author URL
if ( current_user_can( 'edit_posts' ) ) {
$profile_link = get_author_posts_url( $user->ID );
}
// Replace Author URL with BBPress profile link if available
if ( function_exists( 'bbp_get_user_profile_url' ) ) {
$profile_link = esc_url( bbp_get_user_profile_url( $user->ID ) );
}
// Only Show the link if we have something
if ( ! empty( $profile_link ) ) {
$html .= sprintf( '<a href="%s" title="%s">', $profile_link, $user->display_name );
}
}
// Allow the user to control the avatar size and if he wants to show
if ( ! empty( $atts->avatar ) && is_numeric( $atts->avatar ) ) {
$html .= get_avatar( $user->ID, $atts->avatar );
}
// Allow control ver displaying the name
if ( $atts->name ) {
$html .= '<span>' . $user->display_name . '</span>';
}
// Only close link if we have the Link atts and a URL
if ( $atts->link && ! empty( $profile_link ) ) {
$html .= '</a>';
}
$html .= '</li>';
}
$html .= '</ul>';
} else {
$html .= '<p>' . $atts->zero_text . '</p>';
}
return $html;
}
Display the quantity of Users Online
The user might also want to display the quantity of users that are online with a shortcode, so we will deal with that too.
public function shortcode_qty( $atts ) {
$atts = (object) shortcode_atts( [
'plural' => __( '%s users online', 'online-now' ),
'singular' => __( 'One user online', 'online-now' ),
'zero' => __( 'Zero users online', 'online-now' ),
'numeric' => false,
'exclude' => '',
'include' => '',
], $atts );
$users = $this->get_users( $atts->include, $atts->exclude );
if ( $atts->numeric ){
return count( $users );
}
if ( count( $users ) === 0 ) {
$text = $atts->zero;
} elseif ( count( $users ) === 1 ) {
$text = $atts->singular;
} else {
$text = $atts->plural;
}
return sprintf( $text, count( $users ) );
}
Repository and Download
You can always checkout the official repository for this plugin and/or download the latest version of the code to install it in your WordPress.