You are here

session_cache.module in Session Cache API 8

Same filename and directory in other branches
  1. 6 session_cache.module
  2. 7 session_cache.module

session_cache.module

A pluggable user session access facility for programmers who want a simple two-function API that is independent of the actual storage mechanism. Used in particular to avoid $_SESSION as the storage mechanism, so that anonymous user sessions can be used in the context of Varnish.

The database storage mechanism uses core's cache.inc.

See README.txt for details.

File

session_cache.module
View source
<?php

/**
 * @file
 * session_cache.module
 *
 * A pluggable user session access facility for programmers who want a simple
 * two-function API that is independent of the actual storage mechanism.
 * Used in particular to avoid $_SESSION as the storage mechanism, so that
 * anonymous user sessions can be used in the context of Varnish.
 *
 * The database storage mechanism uses core's cache.inc.
 *
 * See README.txt for details.
 */
const SESSION_CACHE_STORAGE_COOKIE = 3;
const SESSION_CACHE_STORAGE_DB_CORE = 2;
const SESSION_CACHE_STORAGE_SESSION = 1;
const SESSION_CACHE_DEFAULT_EXPIRATION_DAYS = 7.0;

/**
 * Write the supplied data to the user session, whatever the storage mechanism may be.
 *
 * @param string $bin, unique id, eg a string prefixed by the module name
 * @param $data, use NULL to delete the bin; it may be refilled at any time
 */
function session_cache_set($bin, $data) {
  if (!isset($bin)) {
    return;
  }
  $method = config('session_cache.settings')
    ->get('storage_method') ?: SESSION_CACHE_STORAGE_SESSION;
  switch ($method) {
    case SESSION_CACHE_STORAGE_COOKIE:

      // Tell the browser to return the cookie only via HTTP or HTTPS, to any
      // path under the root of this server.
      // Don't use "global $cookie_domain", as it may contain the invalid '.localhost'!
      $cookie_domain = ini_get('session.cookie_domain');
      $serialized_data = $data == NULL ? NULL : serialize($data);
      setcookie("Drupal.session_cache.{$bin}", $serialized_data, $data == NULL ? 0 : session_cache_expiration_time(), '/', $cookie_domain, NULL, TRUE);

      // Make sure that subsequent session_cache_get() calls get the data
      // updated here, not what was in the cookie at the start of the request!
      // Note that in array indices '.' are converted to '_'
      $_COOKIE["Drupal_session_cache_{$bin}"] = $serialized_data;
      return;
    case SESSION_CACHE_STORAGE_DB_CORE:
      $sid = session_cache_get_sid();
      if ($data == NULL) {
        cache('session_cache')
          ->delete("{$bin}:{$sid}");
      }
      else {
        cache('session_cache')
          ->set("{$bin}:{$sid}", $data, session_cache_expiration_time());
      }
      return;
    case SESSION_CACHE_STORAGE_SESSION:
      $_SESSION[$bin] = $data;

      // $data==NULL means unset()
      return;
    default:
      module_invoke_all('session_cache_set', $method, $bin, $data);
  }
}

/**
 * Read data from the user session, given its bin id.
 *
 * @param string $bin, unique id eg a string prefixed by the module name
 */
function session_cache_get($bin) {
  if (!isset($bin)) {
    return NULL;
  }
  $method = config('session_cache.settings')
    ->get('storage_method') ?: SESSION_CACHE_STORAGE_SESSION;
  switch ($method) {
    case SESSION_CACHE_STORAGE_COOKIE:

      // Note that in array indices '.' are converted to '_'
      return isset($_COOKIE["Drupal_session_cache_{$bin}"]) ? unserialize($_COOKIE["Drupal_session_cache_{$bin}"]) : NULL;
    case SESSION_CACHE_STORAGE_DB_CORE:
      $sid = session_cache_get_sid();
      $cached = cache('session_cache')
        ->get("{$bin}:{$sid}");
      return is_object($cached) ? $cached->data : NULL;
    case SESSION_CACHE_STORAGE_SESSION:
      return isset($_SESSION) && isset($_SESSION[$bin]) ? $_SESSION[$bin] : NULL;
    default:
      return module_invoke_all('session_cache_get', $method, $bin);
  }
}

/**
 * Implements hook_cron().
 */
function session_cache_cron() {
  if (config('session_cache.settings')
    ->get('storage_method') == SESSION_CACHE_STORAGE_DB_CORE) {

    // Don't believe we need to do anything. When a cache item has expired,
    // after the time provided in the cache()->set() call, the item is up for
    // grabs by the garbage collector at any time.
    return;
  }
}

/**
 * Returns an identifier for the current user session.
 *
 * Typically only called when a database storage mechanism is used.
 *
 * @return sid
 */
function session_cache_get_sid() {
  global $user;
  if (!empty($user->uid) && config('session_cache.settings')
    ->get('use_uid_as_sid')) {
    return 'user' . $user->uid;

    // good if concurrent sessions for the same authenticated user are NOT required
  }
  if (empty($_COOKIE['Drupal_session_cache_sid'])) {

    // Don't use core's session id. Security not a problem, so keep it short.
    $sid = drupal_substr(session_id(), 0, 12);

    // If setcookie() fails, then everything still works, but a new session will
    // be created when logging in or out.
    // Don't use "global $cookie_domain", as it may contain '.localhost', which
    // is invalid!
    $cookie_domain = ini_get('session.cookie_domain');
    setcookie('Drupal.session_cache.sid', $sid, session_cache_expiration_time(), '/', $cookie_domain, NULL, TRUE);
  }
  else {
    $sid = $_COOKIE['Drupal_session_cache_sid'];
  }
  return $sid;
}
function session_cache_expiration_time() {
  $expire_period_days = config('session_cache.settings')
    ->get('expire_period') ?: SESSION_CACHE_DEFAULT_EXPIRATION_DAYS;
  return REQUEST_TIME + 24 * 60 * 60 * $expire_period_days;
}

/**
 * Implements hook_menu().
 */
function session_cache_menu() {
  $items['admin/config/development/session-cache'] = array(
    'title' => 'Session Cache API',
    'description' => 'Select the session cache storage mechanism.',
    'route_name' => 'session_cache_settings',
  );
  return $items;
}

Functions

Namesort descending Description
session_cache_cron Implements hook_cron().
session_cache_expiration_time
session_cache_get Read data from the user session, given its bin id.
session_cache_get_sid Returns an identifier for the current user session.
session_cache_menu Implements hook_menu().
session_cache_set Write the supplied data to the user session, whatever the storage mechanism may be.

Constants