You are here

protected function SessionLimit::_onSessionCollision__DropOldest in Session Limit 8

Same name and namespace in other branches
  1. 2.x src/Services/SessionLimit.php \Drupal\session_limit\Services\SessionLimit::_onSessionCollision__DropOldest()

React to a session collision by dropping older sessions.

Parameters

SessionLimitCollisionEvent $event: The session collision event.

1 call to SessionLimit::_onSessionCollision__DropOldest()
SessionLimit::onSessionCollision in src/Services/SessionLimit.php
React to a collision event.

File

src/Services/SessionLimit.php, line 293

Class

SessionLimit

Namespace

Drupal\session_limit\Services

Code

protected function _onSessionCollision__DropOldest(SessionLimitCollisionEvent $event) {

  // Get the number of sessions that should be removed.
  // @todo replace the straight db query with a select.
  $limit = $this->database
    ->query("SELECT COUNT(DISTINCT(sid)) - :max_sessions FROM {sessions} WHERE uid = :uid", array(
    ':max_sessions' => $event
      ->getUserMaxSessions(),
    ':uid' => $event
      ->getAccount()
      ->id(),
  ))
    ->fetchField();
  if ($limit > 0) {

    // Secure sessionId ids are separate rows in the database, but we don't
    // want to kick the user off there http sessionId and not there https
    // sessionId or vice versa. This is why this query is DISTINCT.
    $result = $this->database
      ->select('sessions', 's')
      ->distinct()
      ->fields('s', array(
      'sid',
      'timestamp',
    ))
      ->condition('s.uid', $event
      ->getAccount()
      ->id())
      ->orderBy('timestamp', 'ASC')
      ->range(0, $limit)
      ->execute();
    foreach ($result as $session) {

      /** @var SessionLimitDisconnectEvent $disconnectEvent */
      $disconnectEvent = $this
        ->getEventDispatcher()
        ->dispatch('session_limit.disconnect', new SessionLimitDisconnectEvent($session->id, $event, $this
        ->getMessage($event
        ->getAccount())));
      if (!$disconnectEvent
        ->shouldPreventDisconnect()) {
        $this
          ->sessionDisconnect($session->sid, $disconnectEvent
          ->getMessage());
      }
    }
  }
}