You are here

function sess_write in Memcache API and Integration 6

Same name and namespace in other branches
  1. 5.2 session-memcache.inc \sess_write()
  2. 5.2 session-memcache-db.inc \sess_write()
  3. 5.2 session-memcache.db.inc \sess_write()
  4. 5 memcache-session.inc \sess_write()

Write a session to session storage.

We have the following cases to handle. 1. Anonymous user 1a. Without session data. 1b. With session data. 1c. Session saving has been turned off programatically (see session_save_session()). 1d. Without session data but had session data at the beginning of the request (thus a write must be made to clear stored session data). 2. Authenticated user. 2a. Without session data. 2b. With session data. 2c. Session saving has been turned off programatically (see session_save_session()).

Parameters

$key: The session ID.

$value: Any data to store in the session.

Return value

TRUE.

File

./memcache-session.inc, line 90
User session handling functions.

Code

function sess_write($key, $value) {
  global $user;

  // If the client doesn't have a session, and one isn't being created ($value),
  // do nothing. If session saving has been turned off, do nothing.
  // Cases 1a, 1c, and 2c are covered here.
  if (!session_save_session() || $user->uid == 0 && empty($_COOKIE[session_name()]) && empty($value)) {
    return TRUE;
  }

  // Prepare the information to be saved.
  $session = new stdClass();
  $session->sid = $key;
  $session->uid = $user->uid;
  $session->cache = isset($user->cache) ? $user->cache : '';
  $session->hostname = ip_address();
  $session->session = $value;
  $session->timestamp = $_SERVER['REQUEST_TIME'];

  // Be sure that we have the latest user object.  If user_save() has been
  // called, we need to refresh the object from the database.
  $user = sess_user_load($session);

  // If this is an authenticated user, or there is something to save in the
  // session, or this is an anonymous user who currently has nothing in the
  // session but did have something in session storage, write it to memcache.
  // If $user->session_data_present_at_load is not set, the current user
  // was created during this request and it's safest to do a write.
  // Cases 1b, 1d, 2a, and 2b are covered here.
  if ($user->uid || !empty($value) || empty($value) && (!isset($user->session_data_present_at_load) || $user->session_data_present_at_load)) {

    // Additionally, check if the session has changed since it was loaded.
    // if not, only write with the same frequency as session_write_interval.
    $last_read = isset($GLOBALS['memcache_session_last_read']) ? $GLOBALS['memcache_session_last_read'] : FALSE;
    $is_changed = empty($last_read) || $last_read['sid'] != $key || $last_read['value'] != $value;
    if ($is_changed || time() - $user->timestamp > variable_get('session_write_interval', 360)) {
      dmemcache_set($key, $session, ini_get('session.gc_maxlifetime'), 'session');
      $session_write = TRUE;
    }
    if ($user->uid && time() - $user->access > variable_get('session_write_interval', 360)) {

      // Update user->access if the session_write_interval threshold has
      // passed.
      db_query('UPDATE {users} SET access = %d WHERE uid = %d', $session->timestamp, $user->uid);

      // Update the user access time so that the dmemcache_set() call
      // caches the updated time.
      $user->access = $session->timestamp;
      $access_update = TRUE;
    }

    // If either the session $user->access has been updated, refresh the cached
    // user object.
    if (!empty($session_write) || !empty($access_update)) {

      // Always update the cached user object if the session has changed.
      $user->timestamp = $session->timestamp;

      // If users.access has been updated, also refresh the cached user object.
      // Data stored in session is stored in session memcache; no need
      // to duplicate it in users memcache.
      unset($user->session);
      unset($user->session_data_present_at_load);

      // Store the session id so we can locate the session with the user id.
      $user->sid = $key;
      dmemcache_set($user->uid, $user, ini_get('session.gc_maxlifetime'), 'users');
    }
  }
  return TRUE;
}