Show if a user is online, idle, or offline on their account page? I want to display the status of the user on the account page. I added the following code in the theme I am using. It works, but users are never displayed offline.
Why? What is wrong in the code?
user.html.twig
&lt;div class=&quot;bs-field-status&quot;&gt;
  {% if status == 'Online' %}
    &lt;i class=&quot;user-online fa fa-circle fa-lg&quot;&gt;&lt;/i&gt; Online
  {% elseif status == 'Absent' %}
    &lt;i class=&quot;user-absent fa fa-circle fa-lg&quot;&gt;&lt;/i&gt; Absent
  {% else %}
    &lt;i class=&quot;user-offline fa fa-circle fa-lg&quot;&gt;&lt;/i&gt; Offline
  {% endif %}
&lt;/div&gt;

bootstrap_subtheme_front_office.theme
&lt;?php
/**
 * @file
 * Bootstrap sub-theme.
 *
 * Place your custom PHP code in this file.
 */

use Drupal\Core\Database\Database;

/**
 * Implements hook_entity_presave().
 */
function bootstrap_subtheme_front_office_preprocess_user(&amp;$variables) {
  // get user object
  $user = $variables['elements']['#user'];
  //- The user has logged in at least once
  if ($user-&gt;getLastLoginTime()) {
    if (account_is_logged_in_less_then_thirty_minutes($user-&gt;id())) {
      $status = 'Online';
    }
    else {
      $status = 'Absent';
    }
  }
  else {
    $status = 'Offline';
  }
  $variables['status'] = $status;
}

/**
 * @param $uid
 *
 * @return bool
 */
function account_is_logged_in_less_then_thirty_minutes($uid) {
  $connection = Database::getConnection();
  $query = $connection-&gt;select('sessions', 'sessions')
    -&gt;fields('sessions', ['sid', 'uid', 'timestamp'])
    -&gt;condition('sessions.uid', $uid, '=')
    //- chef if the user was online in 30 minutes (60 * 30)
    -&gt;condition('sessions.timestamp', \Drupal::time()
        -&gt;getRequestTime() - (60 * 30), '&gt;')
    -&gt;execute();
  //- Get result.
  $results = $query-&gt;fetchAll(\PDO::FETCH_OBJ);
  return (count($results) &gt; 0) ? TRUE : FALSE;
}
I guess the problem lies here, for starters:

//- The user has logged in at least once
  if ($user-&gt;getLastLoginTime()) {
    if (account_is_logged_in_less_then_thirty_minutes($user-&gt;id())) {
      $status = 'Online';
    }
    else {
      $status = 'Absent';
    }
  }
  else {
    $status = 'Offline';
  }


The if ($user-&gt;getLastLoginTime()) { will be TRUE always, after the user has logged in once. This will prevent the else from ever being hit, thus, 'Offline' never gets set.

I don't know what the difference is for you in terms of time between "Absent" or "Offline", but it sounds like you'd want to figure another calculation here to know what to set status to.

This can be simplified to:

function bootstrap_subtheme_front_office_preprocess_user(&amp;$variables) {
  // get user object
 $user = $variables['elements']['#user'];

 $last = $user-&gt;getLastAccessedTime();
 $now = \Drupal::time()-&gt;getRequestTime();

 switch ($last) {
   case ($last &gt; ($now - 900)) :
     $variables['status'] = 'Online';
     break;
   case (($last &lt; ($now - 900)) &amp;&amp; $last &gt; ($now - 1800)) :
     $variables['status'] = 'Absent';
     break;
   default:
     $variables['status'] = 'Offline';
     break;
 }
}


Then break down smaller functions to evaulate the time against how many minutes ago they were active... use it in the switch above.

getLastAccessedTime() does:


  The timestamp when the account last accessed the site.
  
  A value of 0 means the user has never accessed the site.


So you don’t need a db_select.