I want to take away "Online users" so only this are showing
"Who's online
There is currently 1 user and 1 guest online."

Now it's like this:

Who's online
There is currently 1 user and 1 guest online.

Online users

* name
* name
* name

I think I have to do something her in "user.module", but what?
Thank you for a good sulotion.

case 3:
if (user_access('access content')) {
// Count users with activity in the past defined period.
$interval = time() - variable_get('user_block_seconds_online', 900);

// Perform database queries to gather online user lists. We use s.timestamp
// rather than u.access because it is much faster is much faster..
$anonymous_count = sess_count($interval);
$authenticated_users = db_query('SELECT u.uid, u.name FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.timestamp >= %d AND s.uid > 0 ORDER BY s.timestamp DESC', $interval);
$authenticated_count = db_num_rows($authenticated_users);

// Format the output with proper grammar.
if ($anonymous_count == 1 && $authenticated_count == 1) {
$output = t('There is currently %members and %visitors online.', array('%members' => format_plural($authenticated_count, '1 user', '@count users'), '%visitors' => format_plural($anonymous_count, '1 guest', '@count guests')));
}
else {
$output = t('There are currently %members and %visitors online.', array('%members' => format_plural($authenticated_count, '1 user', '@count users'), '%visitors' => format_plural($anonymous_count, '1 guest', '@count guests')));
}

// Display a list of currently online users.
$max_users = variable_get('user_block_max_list_count', 10);
if ($authenticated_count && $max_users) {
$items = array();

while ($max_users-- && $account = db_fetch_object($authenticated_users)) {
$items[] = $account;
}

$output .= theme('user_list', $items, t('Online users'));
}

$block['subject'] = t('Who\'s online');
$block['content'] = $output;
}
return $block;
}

Comments

dan33’s picture

Don't edit the module file directly. Instead, create a new block, name it Who's Online, change input format to PHP, and paste this into the body:

<?php
// Count users with activity in the past defined period.
$interval = time() - 900;

// Perform database queries to gather online user lists.  We use s.timestamp
// rather than u.access because it is much faster is much faster..
$anonymous_count = sess_count($interval);
$authenticated_users = db_query('SELECT u.uid, u.name FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.timestamp >= %d AND s.uid > 0 ORDER BY s.timestamp DESC', $interval);
$authenticated_count = db_num_rows($authenticated_users);

// Format the output with proper grammar.
if ($anonymous_count == 1 && $authenticated_count == 1) {
  $output = t('There is currently %members and %visitors online.', array('%members' => format_plural($authenticated_count, '1 user', '@count users'), '%visitors' => format_plural($anonymous_count, '1 guest', '@count guests')));
}
else {
  $output = t('There are currently %members and %visitors online.', array('%members' => format_plural($authenticated_count, '1 user', '@count users'), '%visitors' => format_plural($anonymous_count, '1 guest', '@count guests')));
}

echo $output;
?>
eileen’s picture

I'd like to leave the list of users in the block, but, it takes up five lines, which is too clunky in my opinion. Right now it looks like this:

Who's online

There are currently 1 user and 0
guests online.

Online users

* Eileen

But I'd like it to look like this:

Who's online
1 user, 5 guests
* Eileen

I've been trying to modify it myself, but it's not working. Any help would be great.

Eileen

marcvangend’s picture

In this case, CSS is a much easier way to achieve the same goal.
Find the ID of the 'Who's online' block (on my site it's "block-user-3") and add a rule to your css file like this:

#block-user-3 h3 {
    display: none;
}

Done!

drupalluver’s picture

Thank you for posting how to modify the online visitors block. I tried it and it works great. I was wondering, though, if there is a way to have it say instead of

Who's online
There is currently 1 user and 1 guest online.

I would rather have it say

Who's online
There are currently 2 people online.

I would like to lump the guest and the users together. Thank you so much for the help that can be found in the forum.

NeoID’s picture

Is there a way of outputting the online users as (with the comma between them except the last):
"user1, user2, user3, user5"

instead of a list..
user1
user2
user3
user5

Sree’s picture

yea uneed to do a bit of formatting ....

-- Sree --
IRC Nick: sreeveturi

marcvangend’s picture

You would have to override the theme_user_list function (http://api.drupal.org/api/function/theme_user_list/5) by copying the code into your templete.php file and then edit it.

You might end up with something like this (I did't test it, no guarantees!)

function theme_user_list($users, $title = NULL) {
  $output = '<div class="online_users">';
  if (isset($title)) {
    $output .= '<h3>'. $title .'</h3>';
  }
  if (!empty($users)) {
    for ($i = 0; $i < count($user) ; $i++) {  //create a loop, once for every user
      $output .= $user;  //output the name of the user
      if ($i < count($user) -1) {  //if the current user is not the last one
        $output .= ", ";  //add a comma and a space
      }
    }
  }
  $output .= '</div>';  //close div
  return $output;
}
NeoID’s picture

When adding this the user list disappeared...

marcvangend’s picture

Sorry, I see the mistake I made, I turned a foreach loop into a for loop but I didn't adjust all code within the {} correctly. Second try, still not tested:

function theme_user_list($users, $title = NULL) {
  $output = '<div class="online_users">';
  if (isset($title)) {
    $output .= '<h3>'. $title .'</h3>';
  }
  if (!empty($users)) {
    for ($i = 0; $i < count($users) ; $i++) {  //create a loop, once for every user
      $output .= $users[i];  //output the name of the user
      if ($i < count($users) -1) {  //if the current user is not the last one
        $output .= ", ";  //add a comma and a space
      }
    }
  }
  $output .= '</div>';  //close div
  return $output;
}
NeoID’s picture

Thanks, I replaced the code, but it didn't do anything and the user-list is still gone...

marcvangend’s picture

I should be more careful and precise when I try to help others. It's not much help for you like this. But now I present you: tested, working code. Cheers!

function theme_user_list($users, $title = NULL) {
  $output = '<div class="online_users">';
  if (isset($title)) {
    $output .= '<h3>'. $title .'</h3>';
  }
  if (!empty($users)) {
    for ($i = 0; $i < count($users) ; $i++) {  //create a loop, once for every user
      $output .= $users[$i]->name;  //output the name of the user
      if ($i < count($users) -1) {  //if the current user is not the last one
        $output .= ", ";  //add a comma and a space
      }
    }
  }
  $output .= '</div>';  //close div
  return $output;
}

By the way, for the sake of completeness, I should mention that the function name in the first line should be changed, according to your needs, into "[yourtemplateengine]_user_list" or "[yourtemplatename]_user_list". See http://drupal.org/node/55126 for more info.

NeoID’s picture

I still can't see any users online....
I'm using the code from http://drupal.org/node/66638 in a block, do I have to change it in order to work with this?

Thanks ;)

marcvangend’s picture

I don't know the code in the post you mentioned. The code I gave you is based on the standard Drupal 5 "Who's Online" block. As said, it is added to the template.php file in the folder of my default theme.

ahjota’s picture

Thank you from almost two years later. ;) My only quibble with the above code is that it removes the links to the user profiles, so I've added them back in. See below:

function theme_user_list($users, $title = NULL) {
  $output = '<div class="online_users">';
  if (isset($title)) {
    $output .= '<h3>'. $title .'</h3>';
  }
  if (!empty($users)) {
    for ($i = 0; $i < count($users) ; $i++) {  //create a loop, once for every user
      $output .= '<a href="/user/'.$users[$i]->uid.'" alt="View user profile.">';  //output a user profile link
      $output .= $users[$i]->name;  //output the name of the user
      $output .= '</a>';  //output the closing tag for the profile link
      if ($i < count($users) -1) {  //if the current user is not the last one
        $output .= ", ";  //add a comma and a space
      }
    }
  }
  $output .= '</div>';  //close div
  return $output;
}
BradM’s picture

Here's an example that is almost correct. Maybe someone with coding experience can take a look and figure out why it isn't working.

It does combine all visitors into one value. However, when listing the members, it repeats one member for however many members are actually online. This will vary based on which member most recently accessed the site. So for example, it may list "Brad, Brad, Brad," for the three members that are online.


$interval = time() - variable_get('user_block_seconds_online', 900);

// Perform database queries to gather online user lists.  We use s.timestamp
// rather than u.access because it is much faster is much faster..
$anonymous_count = sess_count($interval);
$authenticated_users = db_query('SELECT u.uid, u.name FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.timestamp >= %d AND s.uid > 0 ORDER BY s.timestamp DESC', $interval);
$authenticated_count = db_num_rows($authenticated_users);


// Format the output with proper grammar.
$total_count = $authenticated_count+$anonymous_count;
$output = t('There are currently %all online', array('%all' => format_plural($total_count, '1 visitor', '@count visitors')));

// Display a list of currently online users.

if ($authenticated_count) {

$max_users = variable_get('user_block_max_list_count', 10);
$output .= ", including ";

if ($authenticated_count && $max_users) {
  $items = array();

  while ($max_users-- && $account = db_fetch_object($authenticated_users)) {
    $items[] = $account;
  }
  
  foreach ($items as $item) {
    $output .= theme('username', $items[0]);
    if (count($items) !=1) { $output .= ", "; }  // this doesn't work yet, still places comma after last name
  }
}
$output .= ".";

}
else { $output .= "."; }

echo $output;
        

I have limited experience so that's as far as I can take it.

marcvangend’s picture

This part of your code will probably not work:

  foreach ($items as $item) {
    $output .= theme('username', $items[0]);
    if (count($items) !=1) { $output .= ", "; }  // this doesn't work yet, still places comma after last name
  }

First of all, the foreach loop runs once for every value in the $items array. Within the loop, you chose $item as variable representing the current value. Therefore the second line should be
$output .= theme('username', $item);
Otherwise, you keep adding the first field of the array ($items[0]) to your output string in every loop.

The third line of your code presents another problem: it only checks if there is more than one user online. However it should check if the last name has already been added to the output. In that case, the comma should not be added. This problem is the reason why I chose a for-loop in the code I posted above (http://drupal.org/node/148911#comment-276478) instead of a foreach-loop. The for-loop is a little more complicated, but it gives you a variable ($i for instance) which helps you to keep track of the number of times the loop has been procesed. You could also create such a variable yourself:

  $i=1;
  foreach ($items as $item) {
    $output .= theme('username', $item);
    if (count($items) > $i) {   //if the number of users is greater than $i
      $output .= ", ";   //add a comma and a space
    }
    $i++;   // increase $i by 1
  }
BradM’s picture

Fantastic, thanks for the help, it works like a charm now. :)

nainainai’s picture

How to add

Total of 10 registered users there are currently 1 user and 0 guests online.

instead of

There are currently 1 user and 0 guests online.?

marcvangend’s picture

after this piece of code

// Perform database queries to gather online user lists. We use s.timestamp
// rather than u.access because it is much faster is much faster..
$anonymous_count = sess_count($interval);
$authenticated_users = db_query('SELECT u.uid, u.name FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.timestamp >= %d AND s.uid > 0 ORDER BY s.timestamp DESC', $interval);
$authenticated_count = db_num_rows($authenticated_users);

add this:

$total_users = db_query('SELECT u.uid FROM {users}');
$total_count = db_num_rows($total_users);

Then you can use the $total_count variable in your outputstring.

SeanBannister’s picture

I've always thought it would be cool to display the users Avatar along side their username in this block. Just haven't had the time to work it out.

Anyone else done this?

luckysmack’s picture

I want to place this block in my footer but the way its layed out is in the list format.

* User1
* User2
* User3

I just want to change the listing of the user to be one after another. how would i do this?

Who's online
There is currently 1 user and 1 guest online
Online Users: User1, User2, User3

Also if possible where each users name links to their profile (if easily done at all)

Bruno Vincent’s picture

I have tried to make this work for drupal 7 to get a who's online filed for ALL users.

Using globals php and views php module, user stats module also.

In the code output I put this code:

<?php print($row->login); ?>

The online users DO show up on my view,

But when logged out, they show as still online...

What is the correct code to put in there so this works?

blackberry’s picture

When adding this the user list disappeared...

Selva.M’s picture

I have 100 users registered in Mysite and they are from different countries. They have also posted their Content.

When they logged in their account, how do I show if they are Online/Offline to other users ?

Any help much appreciated.