2003-11-18 19:44:36 +00:00
< ? php
2004-08-21 06:42:38 +00:00
/**
* @ file
* User session handling functions .
2008-09-08 21:08:24 +00:00
*
* The user - level session storage handlers :
2009-07-01 12:47:30 +00:00
* - _drupal_session_open ()
* - _drupal_session_close ()
* - _drupal_session_read ()
* - _drupal_session_write ()
* - _drupal_session_destroy ()
* - _drupal_session_garbage_collection ()
2008-09-15 20:48:10 +00:00
* are assigned by session_set_save_handler () in bootstrap . inc and are called
* automatically by PHP . These functions should not be called directly . Session
2008-09-08 21:08:24 +00:00
* data should instead be accessed via the $_SESSION superglobal .
2004-08-21 06:42:38 +00:00
*/
2013-05-02 04:46:53 +00:00
use Drupal\Component\Utility\Crypt ;
2013-06-11 14:04:34 +00:00
use Drupal\Core\Session\UserSession ;
2014-01-09 11:50:54 +00:00
use Drupal\Core\Utility\Error ;
2013-06-11 14:04:34 +00:00
2008-09-08 21:08:24 +00:00
/**
* Session handler assigned by session_set_save_handler () .
2008-09-15 20:48:10 +00:00
*
* This function is used to handle any initialization , such as file paths or
* database connections , that is needed before accessing session data . Drupal
2008-09-08 21:08:24 +00:00
* does not need to initialize anything in this function .
*
* This function should not be called directly .
*
* @ return
* This function will always return TRUE .
2008-09-15 20:48:10 +00:00
*/
2009-07-01 12:47:30 +00:00
function _drupal_session_open () {
2006-02-10 05:42:11 +00:00
return TRUE ;
2003-11-18 19:44:36 +00:00
}
2008-09-08 21:08:24 +00:00
/**
* Session handler assigned by session_set_save_handler () .
2008-09-15 20:48:10 +00:00
*
* This function is used to close the current session . Because Drupal stores
* session data in the database immediately on write , this function does
2008-09-08 21:08:24 +00:00
* not need to do anything .
*
* This function should not be called directly .
*
* @ return
* This function will always return TRUE .
2008-09-15 20:48:10 +00:00
*/
2009-07-01 12:47:30 +00:00
function _drupal_session_close () {
2006-02-10 05:42:11 +00:00
return TRUE ;
2003-11-18 19:44:36 +00:00
}
2008-09-08 21:08:24 +00:00
/**
2011-09-28 04:04:02 +00:00
* Reads an entire session from the database ( internal use only ) .
2008-09-15 20:48:10 +00:00
*
2011-09-28 04:04:02 +00:00
* Also initializes the $user object for the user associated with the session .
* This function is registered with session_set_save_handler () to support
* database - backed sessions . It is called on every page load when PHP sets
* up the $_SESSION superglobal .
2008-09-08 21:08:24 +00:00
*
2011-09-28 04:04:02 +00:00
* This function is an internal function and must not be called directly .
* Doing so may result in logging out the current user , corrupting session data
* or other unexpected behavior . Session data must always be accessed via the
* $_SESSION superglobal .
2008-09-08 21:08:24 +00:00
*
2009-07-01 12:47:30 +00:00
* @ param $sid
2011-09-28 04:04:02 +00:00
* The session ID of the session to retrieve .
2010-07-16 02:53:02 +00:00
*
2008-09-08 21:08:24 +00:00
* @ return
2011-09-28 04:04:02 +00:00
* The user ' s session , or an empty string if no session exists .
2008-09-15 15:18:59 +00:00
*/
2009-07-01 12:47:30 +00:00
function _drupal_session_read ( $sid ) {
2013-04-30 15:48:07 +00:00
global $user ;
2005-03-01 20:15:10 +00:00
2008-09-15 20:48:10 +00:00
// Write and Close handlers are called after destructing objects
2008-09-08 21:08:24 +00:00
// since PHP 5.0.5.
2006-11-11 22:41:20 +00:00
// Thus destructors can use sessions but session handler can't use objects.
// So we are moving session closure before destructing objects.
2010-02-17 22:44:52 +00:00
drupal_register_shutdown_function ( 'session_write_close' );
2006-11-11 22:41:20 +00:00
2008-09-08 21:08:24 +00:00
// Handle the case of first time visitors and clients that don't store
// cookies (eg. web crawlers).
2009-09-05 13:05:31 +00:00
$insecure_session_name = substr ( session_name (), 1 );
2013-12-05 18:02:36 +00:00
$cookies = \Drupal :: request () -> cookies ;
if ( ! $cookies -> has ( session_name ()) && ! $cookies -> has ( $insecure_session_name )) {
2013-07-24 19:40:03 +00:00
$user = new UserSession ();
2006-08-16 13:13:34 +00:00
return '' ;
2006-02-10 05:42:11 +00:00
}
2003-11-18 23:37:48 +00:00
2008-09-15 20:48:10 +00:00
// Otherwise, if the session is still active, we have a record of the
2009-09-05 13:05:31 +00:00
// client's session in the database. If it's HTTPS then we are either have
// a HTTPS session or we are about to log in so we check the sessions table
2014-01-27 11:44:25 +00:00
// for an anonymous session with the non-HTTPS-only cookie. The session ID
// that is in the user's cookie is hashed before being stored in the database
// as a security measure. Thus, we have to hash it to match the database.
2013-09-16 03:58:06 +00:00
if ( \Drupal :: request () -> isSecure ()) {
2014-01-27 11:44:25 +00:00
$values = db_query ( " SELECT u.*, s.* FROM { users} u INNER JOIN { sessions} s ON u.uid = s.uid WHERE s.ssid = :ssid " , array ( ':ssid' => Crypt :: hashBase64 ( $sid ))) -> fetchAssoc ();
2013-06-11 14:04:34 +00:00
if ( ! $values ) {
2013-12-05 18:02:36 +00:00
if ( $cookies -> has ( $insecure_session_name )) {
2013-06-11 14:04:34 +00:00
$values = db_query ( " SELECT u.*, s.* FROM { users} u INNER JOIN { sessions} s ON u.uid = s.uid WHERE s.sid = :sid AND s.uid = 0 " , array (
2014-01-27 11:44:25 +00:00
':sid' => Crypt :: hashBase64 ( $cookies -> get ( $insecure_session_name ))))
2013-06-11 14:04:34 +00:00
-> fetchAssoc ();
2009-09-05 13:05:31 +00:00
}
}
}
else {
2014-01-27 11:44:25 +00:00
$values = db_query ( " SELECT u.*, s.* FROM { users} u INNER JOIN { sessions} s ON u.uid = s.uid WHERE s.sid = :sid " , array ( ':sid' => Crypt :: hashBase64 ( $sid ))) -> fetchAssoc ();
2013-06-11 14:04:34 +00:00
}
2010-03-09 03:52:02 +00:00
// We found the client's session record and they are an authenticated,
// active user.
2013-06-11 14:04:34 +00:00
if ( $values && $values [ 'uid' ] > 0 && $values [ 'status' ] == 1 ) {
2008-09-27 20:37:01 +00:00
// Add roles element to $user.
2013-07-24 19:40:03 +00:00
$rids = db_query ( " SELECT ur.rid FROM { users_roles} ur WHERE ur.uid = :uid " , array ( ':uid' => $values [ 'uid' ])) -> fetchCol ();
$values [ 'roles' ] = array_merge ( array ( DRUPAL_AUTHENTICATED_RID ), $rids );
$user = new UserSession ( $values );
2006-01-21 08:28:55 +00:00
}
2013-07-24 19:40:03 +00:00
elseif ( $values ) {
2010-10-15 04:15:41 +00:00
// The user is anonymous or blocked. Only preserve two fields from the
// {sessions} table.
2013-07-24 19:40:03 +00:00
$user = new UserSession ( array (
'session' => $values [ 'session' ],
'access' => $values [ 'access' ],
));
2010-10-15 04:15:41 +00:00
}
2007-12-22 23:24:26 +00:00
else {
2010-10-15 04:15:41 +00:00
// The session has expired.
2013-07-24 19:40:03 +00:00
$user = new UserSession ();
2006-01-21 08:28:55 +00:00
}
2003-11-18 19:44:36 +00:00
2010-10-15 04:15:41 +00:00
// Store the session that was read for comparison in _drupal_session_write().
$last_read = & drupal_static ( 'drupal_session_last_read' );
$last_read = array (
'sid' => $sid ,
'value' => $user -> session ,
);
2006-08-16 13:13:34 +00:00
return $user -> session ;
2003-11-18 19:44:36 +00:00
}
2008-09-08 21:08:24 +00:00
/**
2011-09-28 04:04:02 +00:00
* Writes an entire session to the database ( internal use only ) .
2008-09-15 20:48:10 +00:00
*
2011-09-28 04:04:02 +00:00
* This function is registered with session_set_save_handler () to support
* database - backed sessions .
2008-09-08 21:08:24 +00:00
*
2011-09-28 04:04:02 +00:00
* 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 .
2008-09-08 21:08:24 +00:00
*
2009-07-01 12:47:30 +00:00
* @ param $sid
2011-09-28 04:04:02 +00:00
* The session ID of the session to write to .
2008-09-08 21:08:24 +00:00
* @ param $value
2011-09-28 04:04:02 +00:00
* Session data to write as a serialized string .
2010-07-16 02:53:02 +00:00
*
2008-09-08 21:08:24 +00:00
* @ return
2011-09-28 04:04:02 +00:00
* Always returns TRUE .
2008-09-15 15:18:59 +00:00
*/
2009-07-01 12:47:30 +00:00
function _drupal_session_write ( $sid , $value ) {
2013-04-30 15:48:07 +00:00
global $user ;
2003-11-18 19:44:36 +00:00
2010-10-15 04:15:41 +00:00
// The exception handler is not active at this point, so we need to do it
// manually.
2010-06-05 13:30:42 +00:00
try {
if ( ! drupal_save_session ()) {
// We don't have anything to do if we are not allowed to save the session.
return ;
}
2006-08-16 13:13:34 +00:00
2010-10-15 04:15:41 +00:00
// 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 has passed since the last update.
2013-07-24 19:40:03 +00:00
if ( $is_changed || ! $user -> getLastAccessedTime () || REQUEST_TIME - $user -> getLastAccessedTime () > settings () -> get ( 'session_write_interval' , 180 )) {
2010-10-15 04:15:41 +00:00
// Either ssid or sid or both will be added from $key below.
$fields = array (
2013-07-11 17:29:02 +00:00
'uid' => $user -> id (),
2013-09-16 03:58:06 +00:00
'hostname' => \Drupal :: request () -> getClientIP (),
2010-10-15 04:15:41 +00:00
'session' => $value ,
'timestamp' => REQUEST_TIME ,
);
2010-11-05 19:05:02 +00:00
// 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.
2014-01-27 11:44:25 +00:00
$key = array ( 'sid' => Crypt :: hashBase64 ( $sid ), 'ssid' => '' );
2010-11-05 19:05:02 +00:00
// On HTTPS connections, use the session ID as both 'sid' and 'ssid'.
2013-09-16 03:58:06 +00:00
if ( \Drupal :: request () -> isSecure ()) {
2014-01-27 11:44:25 +00:00
$key [ 'ssid' ] = Crypt :: hashBase64 ( $sid );
2013-12-05 18:02:36 +00:00
$cookies = \Drupal :: request () -> cookies ;
2010-11-05 19:05:02 +00:00
// The "secure pages" setting allows a site to simultaneously use both
// secure and insecure session cookies. If enabled and both cookies are
2014-01-27 11:44:25 +00:00
// presented then use both keys. The session ID from the cookie is
// hashed before being stored in the database as a security measure.
2013-04-09 20:38:06 +00:00
if ( settings () -> get ( 'mixed_mode_sessions' , FALSE )) {
2010-11-05 19:05:02 +00:00
$insecure_session_name = substr ( session_name (), 1 );
2013-12-05 18:02:36 +00:00
if ( $cookies -> has ( $insecure_session_name )) {
2014-01-27 11:44:25 +00:00
$key [ 'sid' ] = Crypt :: hashBase64 ( $cookies -> get ( $insecure_session_name ));
2010-11-05 19:05:02 +00:00
}
2010-10-15 04:15:41 +00:00
}
}
2013-04-09 20:38:06 +00:00
elseif ( settings () -> get ( 'mixed_mode_sessions' , FALSE )) {
2012-02-16 13:35:24 +00:00
unset ( $key [ 'ssid' ]);
}
2010-06-14 12:31:46 +00:00
2010-10-15 04:15:41 +00:00
db_merge ( 'sessions' )
2014-03-05 19:57:36 +00:00
-> keys ( $key )
2010-10-15 04:15:41 +00:00
-> fields ( $fields )
-> execute ();
}
2006-02-10 05:42:11 +00:00
2010-10-15 04:15:41 +00:00
// Likewise, do not update access time more than once per 180 seconds.
2013-07-24 19:40:03 +00:00
if ( $user -> isAuthenticated () && REQUEST_TIME - $user -> getLastAccessedTime () > settings () -> get ( 'session_write_interval' , 180 )) {
2010-06-05 13:30:42 +00:00
db_update ( 'users' )
-> fields ( array (
'access' => REQUEST_TIME
))
2013-07-11 17:29:02 +00:00
-> condition ( 'uid' , $user -> id ())
2010-06-05 13:30:42 +00:00
-> execute ();
}
return TRUE ;
}
catch ( Exception $exception ) {
2013-05-09 09:25:10 +00:00
require_once __DIR__ . '/errors.inc' ;
2010-10-15 04:15:41 +00:00
// If we are displaying errors, then do so with no possibility of a further
// uncaught exception being thrown.
2010-06-05 13:30:42 +00:00
if ( error_displayable ()) {
print '<h1>Uncaught exception thrown in session handler.</h1>' ;
2014-01-09 11:50:54 +00:00
print '<p>' . Error :: renderExceptionSafe ( $exception ) . '</p><hr />' ;
2010-06-05 13:30:42 +00:00
}
return FALSE ;
}
2003-11-18 19:44:36 +00:00
}
2009-01-19 10:46:52 +00:00
/**
2010-10-15 04:15:41 +00:00
* Initializes the session handler , starting a session if needed .
2009-01-19 10:46:52 +00:00
*/
2009-06-02 06:58:17 +00:00
function drupal_session_initialize () {
2013-04-30 15:48:07 +00:00
global $user ;
2009-06-02 06:58:17 +00:00
2009-07-01 12:47:30 +00:00
session_set_save_handler ( '_drupal_session_open' , '_drupal_session_close' , '_drupal_session_read' , '_drupal_session_write' , '_drupal_session_destroy' , '_drupal_session_garbage_collection' );
2009-06-02 06:58:17 +00:00
2013-09-16 03:58:06 +00:00
$is_https = \Drupal :: request () -> isSecure ();
2013-12-05 18:02:36 +00:00
$cookies = \Drupal :: request () -> cookies ;
if (( $cookies -> has ( session_name ()) && ( $session_name = $cookies -> get ( session_name ()))) || ( $is_https && settings () -> get ( 'mixed_mode_sessions' , FALSE ) && ( $cookies -> has ( substr ( session_name (), 1 ))) && ( $session_name = $cookies -> get ( substr ( session_name (), 1 ))))) {
2009-06-02 06:58:17 +00:00
// If a session cookie exists, initialize the session. Otherwise the
// session is only started on demand in drupal_session_commit(), making
// anonymous users not use a session cookie unless something is stored in
// $_SESSION. This allows HTTP proxies to cache anonymous pageviews.
drupal_session_start ();
2013-07-11 17:29:02 +00:00
if ( $user -> isAuthenticated () || ! empty ( $_SESSION )) {
2009-06-02 06:58:17 +00:00
drupal_page_is_cacheable ( FALSE );
}
}
else {
// Set a session identifier for this request. This is necessary because
2010-01-25 10:38:35 +00:00
// we lazily start sessions at the end of this request, and some
2009-06-02 06:58:17 +00:00
// processes (like drupal_get_token()) needs to know the future
// session ID in advance.
2012-02-16 13:35:24 +00:00
$GLOBALS [ 'lazy_session' ] = TRUE ;
2009-06-02 06:58:17 +00:00
$user = drupal_anonymous_user ();
2010-05-01 08:12:23 +00:00
// Less random sessions (which are much faster to generate) are used for
// anonymous users than are generated in drupal_session_regenerate() when
// a user becomes authenticated.
2014-02-27 04:48:12 +00:00
session_id ( Crypt :: randomBytesBase64 ());
2013-04-09 20:38:06 +00:00
if ( $is_https && settings () -> get ( 'mixed_mode_sessions' , FALSE )) {
2012-02-16 13:35:24 +00:00
$insecure_session_name = substr ( session_name (), 1 );
2014-02-27 04:48:12 +00:00
$session_id = Crypt :: randomBytesBase64 ();
2013-12-05 18:02:36 +00:00
$cookies -> set ( $insecure_session_name , $session_id );
2012-02-16 13:35:24 +00:00
}
2009-01-19 10:46:52 +00:00
}
2011-02-19 16:59:43 +00:00
date_default_timezone_set ( drupal_get_user_timezone ());
2009-01-19 10:46:52 +00:00
}
/**
2013-01-10 23:50:55 +00:00
* Starts a session forcefully , preserving already set session data .
2009-09-28 22:22:54 +00:00
*
* @ ingroup php_wrappers
2009-01-19 10:46:52 +00:00
*/
2009-06-02 06:58:17 +00:00
function drupal_session_start () {
2010-01-14 02:05:34 +00:00
// Command line clients do not support cookies nor sessions.
if ( ! drupal_session_started () && ! drupal_is_cli ()) {
2009-06-02 06:58:17 +00:00
// Save current session data before starting it, as PHP will destroy it.
$session_data = isset ( $_SESSION ) ? $_SESSION : NULL ;
session_start ();
drupal_session_started ( TRUE );
// Restore session data.
if ( ! empty ( $session_data )) {
$_SESSION += $session_data ;
}
}
2009-01-19 10:46:52 +00:00
}
/**
2010-10-15 04:15:41 +00:00
* Commits the current session , if necessary .
2009-01-19 10:46:52 +00:00
*
2009-06-02 06:58:17 +00:00
* If an anonymous user already have an empty session , destroy it .
2009-01-19 10:46:52 +00:00
*/
2009-06-02 06:58:17 +00:00
function drupal_session_commit () {
2013-04-30 15:48:07 +00:00
global $user ;
2009-06-02 06:58:17 +00:00
2009-07-01 12:47:30 +00:00
if ( ! drupal_save_session ()) {
// We don't have anything to do if we are not allowed to save the session.
return ;
}
2013-07-11 17:29:02 +00:00
if ( $user -> isAnonymous () && empty ( $_SESSION )) {
2009-07-01 12:47:30 +00:00
// There is no session data to store, destroy the session if it was
// previously started.
2009-06-02 06:58:17 +00:00
if ( drupal_session_started ()) {
session_destroy ();
}
2009-01-19 10:46:52 +00:00
}
else {
2009-07-01 12:47:30 +00:00
// There is session data to store. Start the session if it is not already
// started.
2009-06-02 06:58:17 +00:00
if ( ! drupal_session_started ()) {
drupal_session_start ();
2013-09-16 03:58:06 +00:00
if ( \Drupal :: request () -> isSecure () && settings () -> get ( 'mixed_mode_sessions' , FALSE )) {
2012-02-16 13:35:24 +00:00
$insecure_session_name = substr ( session_name (), 1 );
$params = session_get_cookie_params ();
$expire = $params [ 'lifetime' ] ? REQUEST_TIME + $params [ 'lifetime' ] : 0 ;
2013-12-05 18:02:36 +00:00
$cookie_params = \Drupal :: request () -> cookies ;
setcookie ( $insecure_session_name , $cookie_params -> get ( $insecure_session_name ), $expire , $params [ 'path' ], $params [ 'domain' ], FALSE , $params [ 'httponly' ]);
2012-02-16 13:35:24 +00:00
}
2009-06-02 06:58:17 +00:00
}
// Write the session data.
session_write_close ();
2009-01-19 10:46:52 +00:00
}
}
/**
2010-10-15 04:15:41 +00:00
* Returns whether a session has been started .
2009-01-19 10:46:52 +00:00
*/
2009-06-02 06:58:17 +00:00
function drupal_session_started ( $set = NULL ) {
static $session_started = FALSE ;
if ( isset ( $set )) {
$session_started = $set ;
}
return $session_started && session_id ();
2009-01-19 10:46:52 +00:00
}
2006-08-31 19:52:39 +00:00
/**
* Called when an anonymous user becomes authenticated or vice - versa .
2009-09-28 22:22:54 +00:00
*
* @ ingroup php_wrappers
2006-08-31 19:52:39 +00:00
*/
2008-09-15 15:18:59 +00:00
function drupal_session_regenerate () {
2013-04-30 15:48:07 +00:00
global $user ;
2012-08-06 09:08:40 +00:00
// Nothing to do if we are not allowed to change the session.
if ( ! drupal_save_session ()) {
return ;
}
2013-09-16 03:58:06 +00:00
$is_https = \Drupal :: request () -> isSecure ();
2013-12-05 18:02:36 +00:00
$cookies = \Drupal :: request () -> cookies ;
2013-04-30 15:48:07 +00:00
2013-04-09 20:38:06 +00:00
if ( $is_https && settings () -> get ( 'mixed_mode_sessions' , FALSE )) {
2009-09-05 13:05:31 +00:00
$insecure_session_name = substr ( session_name (), 1 );
2013-12-05 18:02:36 +00:00
if ( ! isset ( $GLOBALS [ 'lazy_session' ]) && $cookies -> has ( $insecure_session_name )) {
$old_insecure_session_id = $cookies -> get ( $insecure_session_name );
2010-06-14 12:31:46 +00:00
}
2009-09-05 13:05:31 +00:00
$params = session_get_cookie_params ();
2014-02-27 04:48:12 +00:00
$session_id = Crypt :: randomBytesBase64 ();
2010-09-17 14:56:27 +00:00
// If a session cookie lifetime is set, the session will expire
// $params['lifetime'] seconds from the current request. If it is not set,
// it will expire when the browser is closed.
2010-07-07 13:52:00 +00:00
$expire = $params [ 'lifetime' ] ? REQUEST_TIME + $params [ 'lifetime' ] : 0 ;
setcookie ( $insecure_session_name , $session_id , $expire , $params [ 'path' ], $params [ 'domain' ], FALSE , $params [ 'httponly' ]);
2013-12-05 18:02:36 +00:00
$cookies -> set ( $insecure_session_name , $session_id );
2009-09-05 13:05:31 +00:00
}
2009-06-02 06:58:17 +00:00
if ( drupal_session_started ()) {
$old_session_id = session_id ();
}
2014-02-27 04:48:12 +00:00
session_id ( Crypt :: randomBytesBase64 ());
2009-06-02 06:58:17 +00:00
if ( isset ( $old_session_id )) {
2010-06-27 20:55:14 +00:00
$params = session_get_cookie_params ();
2010-07-07 13:52:00 +00:00
$expire = $params [ 'lifetime' ] ? REQUEST_TIME + $params [ 'lifetime' ] : 0 ;
setcookie ( session_name (), session_id (), $expire , $params [ 'path' ], $params [ 'domain' ], $params [ 'secure' ], $params [ 'httponly' ]);
2014-01-27 11:44:25 +00:00
$fields = array ( 'sid' => Crypt :: hashBase64 ( session_id ()));
2010-06-14 12:31:46 +00:00
if ( $is_https ) {
2014-01-27 11:44:25 +00:00
$fields [ 'ssid' ] = Crypt :: hashBase64 ( session_id ());
2010-06-14 12:31:46 +00:00
// If the "secure pages" setting is enabled, use the newly-created
// insecure session identifier as the regenerated sid.
2013-04-09 20:38:06 +00:00
if ( settings () -> get ( 'mixed_mode_sessions' , FALSE )) {
2014-01-27 11:44:25 +00:00
$fields [ 'sid' ] = Crypt :: hashBase64 ( $session_id );
2010-06-14 12:31:46 +00:00
}
}
db_update ( 'sessions' )
-> fields ( $fields )
2014-01-27 11:44:25 +00:00
-> condition ( $is_https ? 'ssid' : 'sid' , Crypt :: hashBase64 ( $old_session_id ))
2010-06-14 12:31:46 +00:00
-> execute ();
}
elseif ( isset ( $old_insecure_session_id )) {
// If logging in to the secure site, and there was no active session on the
// secure site but a session was active on the insecure site, update the
// insecure session with the new session identifiers.
2009-06-02 06:58:17 +00:00
db_update ( 'sessions' )
2014-01-27 11:44:25 +00:00
-> fields ( array ( 'sid' => Crypt :: hashBase64 ( $session_id ), 'ssid' => Crypt :: hashBase64 ( session_id ())))
-> condition ( 'sid' , Crypt :: hashBase64 ( $old_insecure_session_id ))
2009-06-02 06:58:17 +00:00
-> execute ();
}
2010-06-27 20:55:14 +00:00
else {
// Start the session when it doesn't exist yet.
// Preserve the logged in user, as it will be reset to anonymous
// by _drupal_session_read.
$account = $user ;
drupal_session_start ();
$user = $account ;
}
2011-02-19 16:59:43 +00:00
date_default_timezone_set ( drupal_get_user_timezone ());
2006-08-31 19:52:39 +00:00
}
/**
2008-09-15 15:18:59 +00:00
* Session handler assigned by session_set_save_handler () .
2008-09-15 20:48:10 +00:00
*
2010-10-15 04:15:41 +00:00
* Cleans up a specific session .
2006-12-04 10:41:20 +00:00
*
2009-12-30 08:16:55 +00:00
* @ param $sid
2008-09-27 20:37:01 +00:00
* Session ID .
2006-12-04 10:41:20 +00:00
*/
2009-07-01 12:47:30 +00:00
function _drupal_session_destroy ( $sid ) {
2013-04-30 15:48:07 +00:00
global $user ;
2009-07-01 12:47:30 +00:00
2012-08-06 09:08:40 +00:00
// Nothing to do if we are not allowed to change the session.
if ( ! drupal_save_session ()) {
return ;
}
2013-09-16 03:58:06 +00:00
$is_https = \Drupal :: request () -> isSecure ();
2009-07-01 12:47:30 +00:00
// Delete session data.
2008-11-01 21:27:38 +00:00
db_delete ( 'sessions' )
2014-01-27 11:44:25 +00:00
-> condition ( $is_https ? 'ssid' : 'sid' , Crypt :: hashBase64 ( $sid ))
2008-11-01 21:27:38 +00:00
-> execute ();
2009-07-01 12:47:30 +00:00
// Reset $_SESSION and $user to prevent a new session from being started
// in drupal_session_commit().
$_SESSION = array ();
$user = drupal_anonymous_user ();
2009-09-05 13:05:31 +00:00
// Unset the session cookies.
_drupal_session_delete_cookie ( session_name ());
if ( $is_https ) {
2012-02-16 13:35:24 +00:00
_drupal_session_delete_cookie ( substr ( session_name (), 1 ), FALSE );
}
2013-04-09 20:38:06 +00:00
elseif ( settings () -> get ( 'mixed_mode_sessions' , FALSE )) {
2012-02-16 13:35:24 +00:00
_drupal_session_delete_cookie ( 'S' . session_name (), TRUE );
2009-09-05 13:05:31 +00:00
}
}
/**
* Deletes the session cookie .
*
* @ param $name
* Name of session cookie to delete .
2012-02-16 13:35:24 +00:00
* @ param boolean $secure
* Force the secure value of the cookie .
2009-09-05 13:05:31 +00:00
*/
2012-02-16 13:35:24 +00:00
function _drupal_session_delete_cookie ( $name , $secure = NULL ) {
2013-12-05 18:02:36 +00:00
$cookies = \Drupal :: request () -> cookies ;
if ( $cookies -> has ( $name ) || ( ! \Drupal :: request () -> isSecure () && $secure === TRUE )) {
2009-07-01 12:47:30 +00:00
$params = session_get_cookie_params ();
2012-02-16 13:35:24 +00:00
if ( $secure !== NULL ) {
$params [ 'secure' ] = $secure ;
}
setcookie ( $name , '' , REQUEST_TIME - 3600 , $params [ 'path' ], $params [ 'domain' ], $params [ 'secure' ], $params [ 'httponly' ]);
2013-12-05 18:02:36 +00:00
$cookies -> remove ( $name );
2009-07-01 12:47:30 +00:00
}
2006-12-04 10:41:20 +00:00
}
/**
2010-10-15 04:15:41 +00:00
* Ends a specific user ' s session ( s ) .
2006-08-31 19:52:39 +00:00
*
2009-12-30 08:16:55 +00:00
* @ param $uid
2008-09-27 20:37:01 +00:00
* User ID .
2006-08-31 19:52:39 +00:00
*/
2008-09-15 15:18:59 +00:00
function drupal_session_destroy_uid ( $uid ) {
2012-08-06 09:08:40 +00:00
// Nothing to do if we are not allowed to change the session.
if ( ! drupal_save_session ()) {
return ;
}
2008-11-01 21:27:38 +00:00
db_delete ( 'sessions' )
-> condition ( 'uid' , $uid )
-> execute ();
2003-11-18 19:44:36 +00:00
}
2008-09-15 15:18:59 +00:00
/**
* Session handler assigned by session_set_save_handler () .
2008-09-15 20:48:10 +00:00
*
2010-10-15 04:15:41 +00:00
* Cleans up stalled sessions .
2008-09-27 20:37:01 +00:00
*
2009-12-30 08:16:55 +00:00
* @ param $lifetime
2008-09-27 20:37:01 +00:00
* The value of session . gc_maxlifetime , passed by PHP .
2008-11-11 16:49:38 +00:00
* Sessions not updated for more than $lifetime seconds will be removed .
2008-09-15 15:18:59 +00:00
*/
2009-07-01 12:47:30 +00:00
function _drupal_session_garbage_collection ( $lifetime ) {
2006-02-10 05:42:11 +00:00
// Be sure to adjust 'php_value session.gc_maxlifetime' to a large enough
2006-05-07 00:08:36 +00:00
// value. For example, if you want user sessions to stay in your database
2006-02-10 05:42:11 +00:00
// for three weeks before deleting them, you need to set gc_maxlifetime
2006-05-07 00:08:36 +00:00
// to '1814400'. At that value, only after a user doesn't log in after
2006-02-10 05:42:11 +00:00
// three weeks (1814400 seconds) will his/her session be removed.
2008-11-01 21:27:38 +00:00
db_delete ( 'sessions' )
-> condition ( 'timestamp' , REQUEST_TIME - $lifetime , '<' )
-> execute ();
2006-02-10 05:42:11 +00:00
return TRUE ;
2006-10-24 15:31:35 +00:00
}
2007-12-05 19:12:59 +00:00
/**
2010-10-15 04:15:41 +00:00
* Determines whether to save session data of the current request .
2007-12-05 19:12:59 +00:00
*
2008-09-15 20:48:10 +00:00
* This function allows the caller to temporarily disable writing of
* session data , should the request end while performing potentially
2008-09-08 21:08:24 +00:00
* dangerous operations , such as manipulating the global $user object .
2008-09-27 20:37:01 +00:00
* See http :// drupal . org / node / 218104 for usage .
2007-12-05 19:12:59 +00:00
*
* @ param $status
2008-09-15 20:48:10 +00:00
* Disables writing of session data when FALSE , ( re - ) enables
2008-09-08 21:08:24 +00:00
* writing when TRUE .
2010-07-16 02:53:02 +00:00
*
2007-12-05 19:12:59 +00:00
* @ return
* FALSE if writing session data has been disabled . Otherwise , TRUE .
*/
2008-09-15 15:18:59 +00:00
function drupal_save_session ( $status = NULL ) {
2012-08-06 09:08:40 +00:00
// PHP session ID, session, and cookie handling happens in the global scope.
// This value has to persist across calls to drupal_static_reset(), since a
// potentially wrong or disallowed session would be written otherwise.
static $save_session = TRUE ;
2007-12-05 19:12:59 +00:00
if ( isset ( $status )) {
$save_session = $status ;
}
2008-11-01 21:27:38 +00:00
return $save_session ;
2007-12-05 19:12:59 +00:00
}