Jump to content

How do I get a list of online users?


Vineet Sawant
 Share

Recommended Posts

Hello all,

I'm making a dashboard kind of a thing for online ticket booking website.

For that I need a list of all the users who are online and if possible, I need to see which page they are on.

I don't know how can I do it. I tried a simple code like this:

$users_list = $users->find();
foreach ($users_list as $u) {
	if ($u->isLoggedin()) {
		echo $u->name." is Logged in.<br/>";
	}
}

Which outputs list of all the users and shows all them online, which is obviously impossible as I'm running this on localhost.

So how do I do it? :)

p.s.: The logic in code is very wrong, now when I think about it, I know this is not the code I need. :P

Link to comment
Share on other sites

  • 1 month later...

Install db session module and you'll have a setup page with users. (not installed in core)

 I couldn't find anything like db session module but I figured, that's SessionHandlerDB.

HI! could someone please clarify: what module?

(I would like to see a list of logged in users when logged in as superuser.)

Thanks!

Link to comment
Share on other sites

The module soma is talking about is included in the core, but not installed, so go to the modules page and install "Session Handler Database" which will also install the required "Sessions" module.

Let us know if you are still having problems finding this.

  • Like 4
Link to comment
Share on other sites

  • 3 years later...

I have a nearly identical use scenario where isLoggedin is always returning true, except I'm running PW 3.0.61 and am looking to return two lists. Here's the code:

	$members = $users->find("roles=superuser||agent");
	$active = new PageArray();
	$inactive = new PageArray();
	
	foreach ($members as $account){
		if ($account->isLoggedin()) {
			$active->add($account);
		} else {
			$inactive->add($account);
		}
	}

After dozens of searches I found this thread and enabled the Session Handler Database module as suggested, but that had no effect on every user showing up as logged in on my local machine. From what I can tell, that only seems to add a page to the back-end (where I don't need it). Any ideas?

Link to comment
Share on other sites

@Arcturus, isLoggedIn() only works for the current user.

There is a related thread here which suggests adapting some code from the SessionHandlerDB module to get active users from the database. I updated/modified it a bit below:

// Find IDs of users that have been active in the last $mins number of minutes
function onlineUserIDs($mins, $limit = 500) {
    $table = SessionHandlerDB::dbTableName;
    $seconds = $mins * 60;
    $sql =  "SELECT user_id " .
        "FROM `$table` " .
        "WHERE ts > DATE_SUB(NOW(), INTERVAL $seconds SECOND) " .
        "AND user_id!=40 " . // exclude guest
        "ORDER BY ts DESC LIMIT $limit";
    $query = wire('database')->prepare($sql);
    $query->execute();
    $results = $query->fetchAll(\PDO::FETCH_COLUMN);
    return $results;
}

$online_user_ids = onlineUserIDs(60); // User IDs active in the last hour

// Online users
$online_users = $pages->find([
    'id' => $online_user_ids
]);

// Offline users
$offline_users = $pages->find([
    'id!=' => $online_user_ids,
    'template' => 'user',
    'roles!=' => 'guest'
]);

 

  • Like 5
Link to comment
Share on other sites

Thanks, Robin!

I have a slight variant for offline users and am curious as to why an OR operator doesn't seem to work there.

// Offline users
$offline_users = $pages->find([
    'id!=' => $online_user_ids,
    'template' => 'user',
    'name!=' => 'guest', // this is fine for my specific use case
    'roles=' => 'agent' // returns expected listing
    // 'roles=' => 'agent|superuser' returns nothing when used
]);
	

I can get around this by assigning the agent role to each superuser (changes nothing really), but I'm not sure that what I was attempting was technically wrong.

Link to comment
Share on other sites

  • 2 years later...
On 5/18/2017 at 6:17 AM, Robin S said:

@Arcturus, isLoggedIn() only works for the current user.

There is a related thread here which suggests adapting some code from the SessionHandlerDB module to get active users from the database. I updated/modified it a bit below:


// Find IDs of users that have been active in the last $mins number of minutes
function onlineUserIDs($mins, $limit = 500) {
    $table = SessionHandlerDB::dbTableName;
    $seconds = $mins * 60;
    $sql =  "SELECT user_id " .
        "FROM `$table` " .
        "WHERE ts > DATE_SUB(NOW(), INTERVAL $seconds SECOND) " .
        "AND user_id!=40 " . // exclude guest
        "ORDER BY ts DESC LIMIT $limit";
    $query = wire('database')->prepare($sql);
    $query->execute();
    $results = $query->fetchAll(\PDO::FETCH_COLUMN);
    return $results;
}

$online_user_ids = onlineUserIDs(60); // User IDs active in the last hour

// Online users
$online_users = $pages->find([
    'id' => $online_user_ids
]);

// Offline users
$offline_users = $pages->find([
    'id!=' => $online_user_ids,
    'template' => 'user',
    'roles!=' => 'guest'
]);

 

This option works great, but there is one problem I cannot solve. How can and allow to display this kind of data for user role editor. The data is available only for superuser role. I was trying to add permission to the SessionHandlerDB and ProcessSessionDB modules but it dose't work.

Any suggestions? 

Link to comment
Share on other sites

1 hour ago, theqbap said:

Any suggestions? 

Here's some updated code to try:

// Find IDs of users that have been active in the last $mins number of minutes
function onlineUserIDs($mins, $limit = 500) {
	$table = SessionHandlerDB::dbTableName;
	$seconds = $mins * 60;
	$sql =  "SELECT user_id " .
		"FROM `$table` " .
		"WHERE ts > DATE_SUB(NOW(), INTERVAL $seconds SECOND) " .
		"AND user_id!=40 " . // exclude guest
		"ORDER BY ts DESC LIMIT $limit";
	$query = wire('database')->prepare($sql);
	$query->execute();
	$results = $query->fetchAll(\PDO::FETCH_COLUMN);
	return $results;
}

// User IDs active in the last hour
$online_user_ids = onlineUserIDs(60);

// Convert to string for use in selector
$online_user_ids = implode('|', $online_user_ids);

// Online users
$online_users = $users->find("id=$online_user_ids");

// Offline users excluding guest user
$offline_users = $users->find("id!=$online_user_ids, roles.count>1");

 

  • Like 3
  • Thanks 2
Link to comment
Share on other sites

  • 11 months later...

or simply ...

$s = $modules->get('SessionHandlerDB')->getSessions(); // seconds = 300, limit = 100
$online_user_ids = array_filter(array_column($s,'user_id'), function($id) {return $id != 40;});

// with all arguments
$seconds = 86400; // one day
$limit = 200;
$s = $modules->get('SessionHandlerDB')->getSessions($seconds, $limit);
$online_user_ids = array_filter(array_column($s,'user_id'), function($id) {return $id != 40;});

Unfortunately this doesn't work if ProcessWire is bootstrapped
https://github.com/processwire/processwire-issues/issues/1294#issuecomment-748057420

I have to correct myself. It works also if ProcessWire instance is bootstrapped

$otherPwInstance = new ProcessWire($config->paths->root . 'site/');
$s = $otherPwInstance->modules->getModule('SessionHandlerDB', array('noPermissionCheck' => true))->getSessions();
$online_user_ids = array_filter(array_column($s,'user_id'), function($id) {return $id != 40;});

 

Edited by kixe
Correction
  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...