You are here

function _drupal_session_write in Memcache Storage 7

Writes an entire session to the memcached.

This function is registered with session_set_save_handler() to support memcached-backed sessions.

This function is an internal function and must not be called directly. Doing so may result in corrupted session data or other unexpected behavior. Session data must always be accessed via the $_SESSION superglobal.

Parameters

$sid: The session ID of the session to write to.

$value: Session data to write as a serialized string.

Return value

boolean Always returns TRUE.

1 string reference to '_drupal_session_write'
drupal_session_initialize in includes/session.inc
Initializes the session handler, starting a session if needed.

File

includes/session.inc, line 129
User session handling functions.

Code

function _drupal_session_write($sid, $value) {
  global $user, $is_https;
  if (!drupal_save_session()) {

    // We don't have anything to do if we are not allowed to save the session.
    return FALSE;
  }

  // Check whether $_SESSION has been changed in this request.
  $last_read =& drupal_static('drupal_session_last_read');
  $is_changed = !isset($last_read) || $last_read['sid'] != $sid || $last_read['value'] !== $value;

  // For performance reasons, do not update the sessions table, unless
  // $_SESSION has changed or more than 180 seconds has passed since the last update.
  $write_interval = variable_get('session_write_interval', 180);
  if ($is_changed || !isset($user->timestamp) || REQUEST_TIME - $user->timestamp > $write_interval) {

    // Use the session ID as 'sid' and an empty string as 'ssid' by default.
    // _drupal_session_read() does not allow empty strings so that's a safe
    // default.
    $session = new stdClass();
    $session->sid = $sid;
    $session->ssid = '';
    $session->uid = $user->uid;
    $session->cache = isset($user->cache) ? $user->cache : 0;
    $session->hostname = ip_address();
    $session->session = $value;
    $session->timestamp = REQUEST_TIME;

    // On HTTPS connections, use the session ID as both 'sid' and 'ssid'.
    if ($is_https) {
      $session->ssid = $sid;

      // The "secure pages" setting allows a site to simultaneously use both
      // secure and insecure session cookies. If enabled and both cookies are
      // presented then use both keys.
      if (variable_get('https', FALSE)) {
        $insecure_session_name = substr(session_name(), 1);
        if (isset($_COOKIE[$insecure_session_name])) {
          $session->sid = $_COOKIE[$insecure_session_name];
        }
      }
    }
    MemcacheStorageAPI::set($session->sid, $session, ini_get('session.gc_maxlifetime'), 'sessions');
  }

  // Add mapping for user sessions.
  // Store only authenticated users.
  if ($user->uid) {

    // Get current session mapping for an active user.
    $current_sessions = MemcacheStorageAPI::get($user->uid, 'sessions_map');
    if (empty($current_sessions)) {
      $current_sessions = array();
    }

    // Add mapping between user and its session id.
    if (empty($current_sessions[$sid])) {
      $current_sessions[$sid] = $sid;
      MemcacheStorageAPI::set($user->uid, $current_sessions, 0, 'sessions_map');
    }
  }

  // Likewise, do not update access time more than once per 180 seconds.
  if ($user->uid && REQUEST_TIME - $user->access > $write_interval) {
    $account = MemcacheStorageAPI::get($user->uid, 'users');
    if ($account) {
      $account->access = REQUEST_TIME;
      MemcacheStorageAPI::set($account->uid, $account, 0, 'users');
    }

    // The exception handler is not active at this point, so we need to do it
    // manually.
    try {
      db_update('users')
        ->fields(array(
        'access' => REQUEST_TIME,
      ))
        ->condition('uid', $user->uid)
        ->execute();
    } catch (Exception $exception) {
      require_once DRUPAL_ROOT . '/includes/errors.inc';

      // If we are displaying errors, then do so with no possibility of a further
      // uncaught exception being thrown.
      if (error_displayable()) {
        print '<h1>Uncaught exception thrown in session handler.</h1>';
        print '<p>' . _drupal_render_exception_safe($exception) . '</p><hr />';
      }
      return FALSE;
    }
    return TRUE;
  }
}