2008-05-30 11:40:08 +00:00
< ? php
/**
2013-09-28 01:31:35 +00:00
* Session class for CakePHP .
2008-05-30 11:40:08 +00:00
*
2013-09-28 01:31:35 +00:00
* CakePHP abstracts the handling of sessions .
2008-05-30 11:40:08 +00:00
* There are several convenient methods to access session information .
* This class is the implementation of those methods .
* They are mostly used by the Session Component .
*
2009-11-06 06:46:59 +00:00
* CakePHP ( tm ) : Rapid Development Framework ( http :// cakephp . org )
2013-02-08 11:59:49 +00:00
* Copyright ( c ) Cake Software Foundation , Inc . ( http :// cakefoundation . org )
2008-05-30 11:40:08 +00:00
*
* Licensed under The MIT License
2013-02-08 12:22:51 +00:00
* For full copyright and license information , please see the LICENSE . txt
2008-05-30 11:40:08 +00:00
* Redistributions of files must retain the above copyright notice .
*
2013-02-08 11:59:49 +00:00
* @ copyright Copyright ( c ) Cake Software Foundation , Inc . ( http :// cakefoundation . org )
2009-11-06 06:00:11 +00:00
* @ link http :// cakephp . org CakePHP ( tm ) Project
2011-07-26 06:16:14 +00:00
* @ package Cake . Model . Datasource
2008-10-30 17:30:26 +00:00
* @ since CakePHP ( tm ) v . 0.10 . 0.1222
2013-05-30 22:11:14 +00:00
* @ license http :// www . opensource . org / licenses / mit - license . php MIT License
2008-05-30 11:40:08 +00:00
*/
2009-04-13 19:47:40 +00:00
2012-03-08 04:26:40 +00:00
App :: uses ( 'Hash' , 'Utility' );
2010-12-15 05:43:05 +00:00
App :: uses ( 'Security' , 'Utility' );
2010-12-04 07:21:42 +00:00
2008-05-30 11:40:08 +00:00
/**
2013-09-28 01:31:35 +00:00
* Session class for CakePHP .
2008-05-30 11:40:08 +00:00
*
2013-09-28 01:31:35 +00:00
* CakePHP abstracts the handling of sessions . There are several convenient methods to access session information .
2008-05-30 11:40:08 +00:00
* This class is the implementation of those methods . They are mostly used by the Session Component .
*
2011-07-26 06:16:14 +00:00
* @ package Cake . Model . Datasource
2008-05-30 11:40:08 +00:00
*/
2010-07-04 10:06:24 +00:00
class CakeSession {
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* True if the Session is still valid
*
2014-07-03 13:36:42 +00:00
* @ var bool
2008-05-30 11:40:08 +00:00
*/
2010-06-23 01:25:04 +00:00
public static $valid = false ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Error messages for this session
*
* @ var array
*/
2010-06-23 01:25:04 +00:00
public static $error = false ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* User agent string
*
* @ var string
*/
2010-06-23 01:25:04 +00:00
protected static $_userAgent = '' ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Path to where the session is active .
*
* @ var string
*/
2010-06-23 01:25:04 +00:00
public static $path = '/' ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Error number of last occurred error
*
2014-07-03 13:36:42 +00:00
* @ var int
2008-05-30 11:40:08 +00:00
*/
2010-06-23 01:25:04 +00:00
public static $lastError = null ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Start time for this session .
*
2014-07-03 13:36:42 +00:00
* @ var int
2008-05-30 11:40:08 +00:00
*/
2010-06-23 01:25:04 +00:00
public static $time = false ;
2009-07-24 19:18:37 +00:00
2010-06-23 01:42:21 +00:00
/**
* Cookie lifetime
*
2014-07-03 13:36:42 +00:00
* @ var int
2010-06-23 01:42:21 +00:00
*/
public static $cookieLifeTime ;
2008-05-30 11:40:08 +00:00
/**
* Time when this session becomes invalid .
*
2014-07-03 13:36:42 +00:00
* @ var int
2008-05-30 11:40:08 +00:00
*/
2010-06-23 01:25:04 +00:00
public static $sessionTime = false ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Current Session id
*
* @ var string
*/
2010-06-23 01:25:04 +00:00
public static $id = null ;
2009-07-24 19:18:37 +00:00
2010-03-26 11:51:58 +00:00
/**
* Hostname
*
* @ var string
*/
2010-06-23 01:25:04 +00:00
public static $host = null ;
2010-03-26 11:53:30 +00:00
2010-04-28 23:45:20 +00:00
/**
* Session timeout multiplier factor
*
2014-07-03 13:36:42 +00:00
* @ var int
2010-04-28 23:45:20 +00:00
*/
2010-06-23 01:25:04 +00:00
public static $timeout = null ;
2010-04-28 23:45:20 +00:00
2010-07-25 21:50:08 +00:00
/**
* Number of requests that can occur during a session time without the session being renewed .
2012-01-29 16:54:26 +00:00
* This feature is only used when config value `Session.autoRegenerate` is set to true .
2010-07-25 21:50:08 +00:00
*
2014-07-03 13:36:42 +00:00
* @ var int
2010-07-25 21:50:08 +00:00
* @ see CakeSession :: _checkValid ()
*/
public static $requestCountdown = 10 ;
2013-12-08 12:44:16 +00:00
/**
* Whether or not the init function in this class was already called
*
2014-07-03 13:36:42 +00:00
* @ var bool
2013-12-08 12:44:16 +00:00
*/
protected static $_initialized = false ;
2014-01-20 07:56:35 +00:00
/**
* Session cookie name
*
* @ var string
*/
protected static $_cookieName = null ;
2008-05-30 11:40:08 +00:00
/**
2012-05-05 16:37:29 +00:00
* Pseudo constructor .
2008-05-30 11:40:08 +00:00
*
2015-01-04 00:40:09 +00:00
* @ param string | null $base The base path for the Session
2011-07-30 22:38:57 +00:00
* @ return void
2008-05-30 11:40:08 +00:00
*/
2012-01-07 23:01:50 +00:00
public static function init ( $base = null ) {
2015-07-21 08:22:53 +00:00
static :: $time = time ();
2013-12-08 12:44:16 +00:00
2015-12-28 22:26:35 +00:00
if ( env ( 'HTTP_USER_AGENT' ) && ! static :: $_userAgent ) {
2015-07-21 08:22:53 +00:00
static :: $_userAgent = md5 ( env ( 'HTTP_USER_AGENT' ) . Configure :: read ( 'Security.salt' ));
2008-05-30 11:40:08 +00:00
}
2013-12-08 12:44:16 +00:00
2015-07-21 08:22:53 +00:00
static :: _setPath ( $base );
static :: _setHost ( env ( 'HTTP_HOST' ));
2012-05-05 16:37:29 +00:00
2015-07-21 08:22:53 +00:00
if ( ! static :: $_initialized ) {
2013-12-08 12:44:16 +00:00
register_shutdown_function ( 'session_write_close' );
}
2015-07-21 08:22:53 +00:00
static :: $_initialized = true ;
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2010-07-22 01:05:39 +00:00
/**
* Setup the Path variable
*
2015-01-04 00:40:09 +00:00
* @ param string | null $base base path
2010-07-22 01:05:39 +00:00
* @ return void
*/
protected static function _setPath ( $base = null ) {
if ( empty ( $base )) {
2015-07-21 08:22:53 +00:00
static :: $path = '/' ;
2010-07-22 01:05:39 +00:00
return ;
}
if ( strpos ( $base , 'index.php' ) !== false ) {
2012-11-14 11:24:08 +00:00
$base = str_replace ( 'index.php' , '' , $base );
2010-07-22 01:05:39 +00:00
}
if ( strpos ( $base , '?' ) !== false ) {
2012-11-14 11:24:08 +00:00
$base = str_replace ( '?' , '' , $base );
2010-07-22 01:05:39 +00:00
}
2015-07-21 08:22:53 +00:00
static :: $path = $base ;
2010-07-22 01:05:39 +00:00
}
/**
2010-07-22 09:09:48 +00:00
* Set the host name
2010-07-22 01:05:39 +00:00
*
2010-07-22 09:09:48 +00:00
* @ param string $host Hostname
2010-07-22 01:05:39 +00:00
* @ return void
*/
2010-07-22 09:09:48 +00:00
protected static function _setHost ( $host ) {
2015-07-21 08:22:53 +00:00
static :: $host = $host ;
if ( strpos ( static :: $host , ':' ) !== false ) {
static :: $host = substr ( static :: $host , 0 , strpos ( static :: $host , ':' ));
2010-07-22 01:05:39 +00:00
}
}
2008-05-30 11:40:08 +00:00
/**
* Starts the Session .
*
2014-07-03 13:36:42 +00:00
* @ return bool True if session was started
2008-05-30 11:40:08 +00:00
*/
2010-06-23 01:25:04 +00:00
public static function start () {
2015-07-21 08:22:53 +00:00
if ( static :: started ()) {
2010-07-22 08:42:56 +00:00
return true ;
2010-03-25 23:46:48 +00:00
}
2013-12-08 12:44:16 +00:00
2015-07-21 08:22:53 +00:00
$id = static :: id ();
static :: _startSession ();
if ( ! $id && static :: started ()) {
static :: _checkValid ();
2010-07-21 03:35:59 +00:00
}
2010-07-22 08:42:56 +00:00
2015-07-21 08:22:53 +00:00
static :: $error = false ;
static :: $valid = true ;
return static :: started ();
2010-07-21 03:35:59 +00:00
}
2008-05-30 11:40:08 +00:00
/**
* Determine if Session has been started .
*
2014-07-03 13:36:42 +00:00
* @ return bool True if session has been started .
2008-05-30 11:40:08 +00:00
*/
2010-06-23 01:25:04 +00:00
public static function started () {
2015-12-29 04:50:35 +00:00
if ( function_exists ( 'session_status' )) {
2015-12-28 22:26:35 +00:00
return isset ( $_SESSION ) && ( session_status () === PHP_SESSION_ACTIVE );
}
return isset ( $_SESSION ) && session_id ();
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Returns true if given variable is set in session .
*
* @ param string $name Variable name to check for
2014-07-03 13:36:42 +00:00
* @ return bool True if variable is there
2008-05-30 11:40:08 +00:00
*/
2015-01-04 00:40:09 +00:00
public static function check ( $name ) {
2016-10-21 14:54:39 +00:00
if ( ! static :: _hasSession () || ! static :: start ()) {
2008-06-20 20:17:23 +00:00
return false ;
2008-05-30 11:40:08 +00:00
}
2016-10-21 14:54:39 +00:00
if ( isset ( $_SESSION [ $name ])) {
return true ;
}
2014-01-20 07:56:35 +00:00
2012-09-15 00:33:05 +00:00
return Hash :: get ( $_SESSION , $name ) !== null ;
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
2013-06-18 21:49:42 +00:00
* Returns the session id .
* Calling this method will not auto start the session . You might have to manually
* assert a started session .
2008-09-26 14:03:16 +00:00
*
2013-06-18 21:49:42 +00:00
* Passing an id into it , you can also replace the session id if the session
* has not already been started .
* Note that depending on the session handler , not all characters are allowed
* within the session id . For example , the file session handler only allows
* characters in the range a - z A - Z 0 - 9 , ( comma ) and - ( minus ) .
*
2015-01-04 00:40:09 +00:00
* @ param string | null $id Id to replace the current session id
2008-05-30 11:40:08 +00:00
* @ return string Session id
*/
2010-06-23 01:25:04 +00:00
public static function id ( $id = null ) {
2008-05-30 11:40:08 +00:00
if ( $id ) {
2015-07-21 08:22:53 +00:00
static :: $id = $id ;
session_id ( static :: $id );
2008-05-30 11:40:08 +00:00
}
2015-07-21 08:22:53 +00:00
if ( static :: started ()) {
2008-05-30 11:40:08 +00:00
return session_id ();
}
2015-07-21 08:22:53 +00:00
return static :: $id ;
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Removes a variable from session .
*
* @ param string $name Session variable to remove
2014-07-03 13:36:42 +00:00
* @ return bool Success
2008-05-30 11:40:08 +00:00
*/
2010-06-23 01:25:04 +00:00
public static function delete ( $name ) {
2015-07-21 08:22:53 +00:00
if ( static :: check ( $name )) {
static :: _overwrite ( $_SESSION , Hash :: remove ( $_SESSION , $name ));
return ! static :: check ( $name );
2008-05-30 11:40:08 +00:00
}
return false ;
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
2013-06-18 21:49:42 +00:00
* Used to write new data to _SESSION , since PHP doesn ' t like us setting the _SESSION var itself .
2008-05-30 11:40:08 +00:00
*
2014-06-04 18:58:55 +00:00
* @ param array & $old Set of old variables => values
2008-05-30 11:40:08 +00:00
* @ param array $new New set of variable => value
2011-07-30 22:38:57 +00:00
* @ return void
2008-05-30 11:40:08 +00:00
*/
2011-08-20 04:43:34 +00:00
protected static function _overwrite ( & $old , $new ) {
2008-10-23 00:10:44 +00:00
if ( ! empty ( $old )) {
2008-05-30 11:40:08 +00:00
foreach ( $old as $key => $var ) {
if ( ! isset ( $new [ $key ])) {
unset ( $old [ $key ]);
}
}
}
foreach ( $new as $key => $var ) {
$old [ $key ] = $var ;
}
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Return error description for given error number .
*
2014-07-03 13:36:42 +00:00
* @ param int $errorNumber Error to set
2008-05-30 11:40:08 +00:00
* @ return string Error as string
*/
2011-08-20 04:43:34 +00:00
protected static function _error ( $errorNumber ) {
2015-07-21 08:22:53 +00:00
if ( ! is_array ( static :: $error ) || ! array_key_exists ( $errorNumber , static :: $error )) {
2008-05-30 11:40:08 +00:00
return false ;
}
2015-07-21 08:22:53 +00:00
return static :: $error [ $errorNumber ];
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Returns last occurred error as a string , if any .
*
* @ return mixed Error description as a string , or false .
*/
2010-06-23 01:25:04 +00:00
public static function error () {
2015-07-21 08:22:53 +00:00
if ( static :: $lastError ) {
return static :: _error ( static :: $lastError );
2008-05-30 11:40:08 +00:00
}
2010-06-23 01:25:04 +00:00
return false ;
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Returns true if session is valid .
*
2014-07-03 13:36:42 +00:00
* @ return bool Success
2008-05-30 11:40:08 +00:00
*/
2010-06-23 01:25:04 +00:00
public static function valid () {
2015-07-21 08:22:53 +00:00
if ( static :: start () && static :: read ( 'Config' )) {
if ( static :: _validAgentAndTime () && static :: $error === false ) {
static :: $valid = true ;
2008-05-30 11:40:08 +00:00
} else {
2015-07-21 08:22:53 +00:00
static :: $valid = false ;
static :: _setError ( 1 , 'Session Highjacking Attempted !!!' );
2008-05-30 11:40:08 +00:00
}
}
2015-07-21 08:22:53 +00:00
return static :: $valid ;
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2010-07-27 03:01:23 +00:00
/**
* Tests that the user agent is valid and that the session hasn 't ' timed out ' .
2015-07-21 08:22:53 +00:00
* Since timeouts are implemented in CakeSession it checks the current static :: $time
2012-12-22 22:48:15 +00:00
* against the time the session is set to expire . The User agent is only checked
2010-07-27 03:01:23 +00:00
* if Session . checkAgent == true .
*
2014-07-03 13:36:42 +00:00
* @ return bool
2010-07-27 03:01:23 +00:00
*/
protected static function _validAgentAndTime () {
2016-01-30 21:11:50 +00:00
$userAgent = static :: read ( 'Config.userAgent' );
$time = static :: read ( 'Config.time' );
2010-07-27 03:01:23 +00:00
$validAgent = (
Configure :: read ( 'Session.checkAgent' ) === false ||
2016-01-30 21:11:50 +00:00
isset ( $userAgent ) && static :: $_userAgent === $userAgent
2010-07-27 03:01:23 +00:00
);
2016-01-30 21:11:50 +00:00
return ( $validAgent && static :: $time <= $time );
2010-07-27 03:01:23 +00:00
}
2010-07-21 03:35:59 +00:00
/**
2013-06-18 21:49:42 +00:00
* Get / Set the user agent
2010-07-21 03:35:59 +00:00
*
2015-01-04 00:40:09 +00:00
* @ param string | null $userAgent Set the user agent
2015-09-25 15:11:20 +00:00
* @ return string Current user agent .
2010-07-21 03:35:59 +00:00
*/
public static function userAgent ( $userAgent = null ) {
if ( $userAgent ) {
2015-07-21 08:22:53 +00:00
static :: $_userAgent = $userAgent ;
2010-07-21 03:35:59 +00:00
}
2015-07-21 08:22:53 +00:00
if ( empty ( static :: $_userAgent )) {
CakeSession :: init ( static :: $path );
2012-01-07 23:01:50 +00:00
}
2015-07-21 08:22:53 +00:00
return static :: $_userAgent ;
2010-07-21 03:35:59 +00:00
}
2008-05-30 11:40:08 +00:00
/**
* Returns given session variable , or all of them , if no parameters given .
*
2015-01-04 00:40:09 +00:00
* @ param string | null $name The name of the session variable ( or a path as sent to Set . extract )
2014-01-20 07:56:35 +00:00
* @ return mixed The value of the session variable , null if session not available ,
2015-01-28 22:54:32 +00:00
* session not started , or provided name not found in the session , false on failure .
2008-05-30 11:40:08 +00:00
*/
2010-06-23 01:25:04 +00:00
public static function read ( $name = null ) {
2015-07-21 08:22:53 +00:00
if ( ! static :: _hasSession () || ! static :: start ()) {
2014-01-20 07:56:35 +00:00
return null ;
}
2013-08-16 18:12:49 +00:00
if ( $name === null ) {
2015-07-21 08:22:53 +00:00
return static :: _returnSessionVars ();
2008-05-30 11:40:08 +00:00
}
2012-03-08 04:26:40 +00:00
$result = Hash :: get ( $_SESSION , $name );
2008-05-30 11:40:08 +00:00
2012-03-08 04:26:40 +00:00
if ( isset ( $result )) {
2008-05-30 11:40:08 +00:00
return $result ;
}
return null ;
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Returns all session variables .
*
* @ return mixed Full $_SESSION array , or false on error .
*/
2011-08-20 04:43:34 +00:00
protected static function _returnSessionVars () {
2008-05-30 11:40:08 +00:00
if ( ! empty ( $_SESSION )) {
return $_SESSION ;
}
2015-07-21 08:22:53 +00:00
static :: _setError ( 2 , 'No Session vars set' );
2008-05-30 11:40:08 +00:00
return false ;
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Writes value to given session variable name .
*
2012-05-13 00:43:31 +00:00
* @ param string | array $name Name of variable
2008-05-30 11:40:08 +00:00
* @ param string $value Value to write
2014-07-03 13:36:42 +00:00
* @ return bool True if the write was successful , false if the write failed
2008-05-30 11:40:08 +00:00
*/
2010-07-16 03:54:01 +00:00
public static function write ( $name , $value = null ) {
2016-10-21 14:54:39 +00:00
if ( ! static :: start ()) {
2008-05-30 11:40:08 +00:00
return false ;
}
2014-01-20 07:56:35 +00:00
2010-07-16 03:54:01 +00:00
$write = $name ;
if ( ! is_array ( $name )) {
$write = array ( $name => $value );
2008-05-30 11:40:08 +00:00
}
2010-07-16 03:54:01 +00:00
foreach ( $write as $key => $val ) {
2015-07-21 08:22:53 +00:00
static :: _overwrite ( $_SESSION , Hash :: insert ( $_SESSION , $key , $val ));
2012-03-08 04:26:40 +00:00
if ( Hash :: get ( $_SESSION , $key ) !== $val ) {
2010-07-16 03:54:01 +00:00
return false ;
}
}
return true ;
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2014-12-23 02:39:05 +00:00
/**
* Reads and deletes a variable from session .
*
* @ param string $name The key to read and remove ( or a path as sent to Hash . extract ) .
* @ return mixed The value of the session variable , null if session not available ,
* session not started , or provided name not found in the session .
*/
public static function consume ( $name ) {
if ( empty ( $name )) {
return null ;
}
2015-07-21 08:22:53 +00:00
$value = static :: read ( $name );
2014-12-23 02:39:05 +00:00
if ( $value !== null ) {
2015-07-21 08:22:53 +00:00
static :: _overwrite ( $_SESSION , Hash :: remove ( $_SESSION , $name ));
2014-12-23 02:39:05 +00:00
}
return $value ;
}
2008-05-30 11:40:08 +00:00
/**
* Helper method to destroy invalid sessions .
*
2008-09-25 16:49:56 +00:00
* @ return void
2008-05-30 11:40:08 +00:00
*/
2010-07-11 23:57:04 +00:00
public static function destroy () {
2015-07-21 08:22:53 +00:00
if ( ! static :: started ()) {
static :: _startSession ();
2013-12-07 21:25:33 +00:00
}
2015-07-21 08:22:53 +00:00
if ( static :: started ()) {
2015-12-28 23:40:14 +00:00
if ( session_id () && static :: _hasSession ()) {
2015-12-28 16:41:23 +00:00
session_write_close ();
2015-12-28 22:26:35 +00:00
session_start ();
2015-12-28 16:41:23 +00:00
}
2015-01-15 10:00:27 +00:00
session_destroy ();
2015-12-29 04:26:58 +00:00
unset ( $_COOKIE [ static :: _cookieName ()]);
2015-01-15 10:00:27 +00:00
}
2013-12-07 21:25:33 +00:00
$_SESSION = null ;
2015-07-21 08:22:53 +00:00
static :: $id = null ;
static :: $_cookieName = null ;
2010-09-30 03:01:23 +00:00
}
/**
2015-01-04 00:40:09 +00:00
* Clears the session .
2010-09-30 03:01:23 +00:00
*
2015-01-04 00:40:09 +00:00
* Optionally also clears the session id and renews the session .
*
2015-01-04 09:52:18 +00:00
* @ param bool $renew If the session should also be renewed . Defaults to true .
2010-09-30 03:01:23 +00:00
* @ return void
*/
2015-01-04 09:52:18 +00:00
public static function clear ( $renew = true ) {
2015-01-28 22:54:32 +00:00
if ( ! $renew ) {
$_SESSION = array ();
return ;
2015-01-04 00:40:09 +00:00
}
2015-01-28 22:54:32 +00:00
$_SESSION = null ;
2015-07-21 08:22:53 +00:00
static :: $id = null ;
static :: renew ();
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
2013-09-28 01:31:35 +00:00
* Helper method to initialize a session , based on CakePHP core settings .
2008-05-30 11:40:08 +00:00
*
2010-07-25 04:42:28 +00:00
* Sessions can be configured with a few shortcut names as well as have any number of ini settings declared .
*
2010-07-25 05:14:41 +00:00
* @ return void
2010-12-12 00:01:07 +00:00
* @ throws CakeSessionException Throws exceptions when ini_set () fails .
2008-05-30 11:40:08 +00:00
*/
2010-07-25 05:14:41 +00:00
protected static function _configureSession () {
2010-07-25 04:42:28 +00:00
$sessionConfig = Configure :: read ( 'Session' );
if ( isset ( $sessionConfig [ 'defaults' ])) {
2015-07-21 08:22:53 +00:00
$defaults = static :: _defaultConfig ( $sessionConfig [ 'defaults' ]);
2010-07-25 04:42:28 +00:00
if ( $defaults ) {
2012-03-11 01:57:18 +00:00
$sessionConfig = Hash :: merge ( $defaults , $sessionConfig );
2010-07-25 04:42:28 +00:00
}
}
if ( ! isset ( $sessionConfig [ 'ini' ][ 'session.cookie_secure' ]) && env ( 'HTTPS' )) {
$sessionConfig [ 'ini' ][ 'session.cookie_secure' ] = 1 ;
}
if ( isset ( $sessionConfig [ 'timeout' ]) && ! isset ( $sessionConfig [ 'cookieTimeout' ])) {
$sessionConfig [ 'cookieTimeout' ] = $sessionConfig [ 'timeout' ];
2008-08-12 23:47:00 +00:00
}
2010-07-25 04:42:28 +00:00
if ( ! isset ( $sessionConfig [ 'ini' ][ 'session.cookie_lifetime' ])) {
$sessionConfig [ 'ini' ][ 'session.cookie_lifetime' ] = $sessionConfig [ 'cookieTimeout' ] * 60 ;
}
2014-01-20 07:56:35 +00:00
2010-07-25 04:42:28 +00:00
if ( ! isset ( $sessionConfig [ 'ini' ][ 'session.name' ])) {
$sessionConfig [ 'ini' ][ 'session.name' ] = $sessionConfig [ 'cookie' ];
}
2015-07-21 08:22:53 +00:00
static :: $_cookieName = $sessionConfig [ 'ini' ][ 'session.name' ];
2014-01-20 07:56:35 +00:00
2010-07-25 04:42:28 +00:00
if ( ! empty ( $sessionConfig [ 'handler' ])) {
2010-07-25 05:14:41 +00:00
$sessionConfig [ 'ini' ][ 'session.save_handler' ] = 'user' ;
2014-12-27 19:34:47 +00:00
} elseif ( ! empty ( $sessionConfig [ 'session.save_path' ]) && Configure :: read ( 'debug' )) {
if ( ! is_dir ( $sessionConfig [ 'session.save_path' ])) {
mkdir ( $sessionConfig [ 'session.save_path' ], 0775 , true );
}
2008-05-30 11:40:08 +00:00
}
2014-12-27 19:34:47 +00:00
2012-05-24 02:25:19 +00:00
if ( ! isset ( $sessionConfig [ 'ini' ][ 'session.gc_maxlifetime' ])) {
$sessionConfig [ 'ini' ][ 'session.gc_maxlifetime' ] = $sessionConfig [ 'timeout' ] * 60 ;
}
2012-06-13 00:00:19 +00:00
if ( ! isset ( $sessionConfig [ 'ini' ][ 'session.cookie_httponly' ])) {
$sessionConfig [ 'ini' ][ 'session.cookie_httponly' ] = 1 ;
}
2016-01-19 03:17:30 +00:00
// For IE<=8
if ( ! isset ( $sessionConfig [ 'cacheLimiter' ])) {
$sessionConfig [ 'cacheLimiter' ] = 'must-revalidate' ;
}
2008-05-30 11:40:08 +00:00
2010-07-25 04:42:28 +00:00
if ( empty ( $_SESSION )) {
if ( ! empty ( $sessionConfig [ 'ini' ]) && is_array ( $sessionConfig [ 'ini' ])) {
foreach ( $sessionConfig [ 'ini' ] as $setting => $value ) {
if ( ini_set ( $setting , $value ) === false ) {
2013-08-16 10:12:27 +00:00
throw new CakeSessionException ( __d ( 'cake_dev' , 'Unable to configure the session, setting %s failed.' , $setting ));
2010-07-25 04:42:28 +00:00
}
}
}
}
if ( ! empty ( $sessionConfig [ 'handler' ]) && ! isset ( $sessionConfig [ 'handler' ][ 'engine' ])) {
call_user_func_array ( 'session_set_save_handler' , $sessionConfig [ 'handler' ]);
}
2010-07-25 15:42:05 +00:00
if ( ! empty ( $sessionConfig [ 'handler' ][ 'engine' ])) {
2015-07-21 08:22:53 +00:00
$handler = static :: _getHandler ( $sessionConfig [ 'handler' ][ 'engine' ]);
2010-07-25 15:42:05 +00:00
session_set_save_handler (
2010-09-06 04:43:58 +00:00
array ( $handler , 'open' ),
array ( $handler , 'close' ),
array ( $handler , 'read' ),
array ( $handler , 'write' ),
array ( $handler , 'destroy' ),
array ( $handler , 'gc' )
2010-07-25 15:42:05 +00:00
);
}
2010-07-26 04:32:31 +00:00
Configure :: write ( 'Session' , $sessionConfig );
2015-07-21 08:22:53 +00:00
static :: $sessionTime = static :: $time + ( $sessionConfig [ 'timeout' ] * 60 );
2010-07-25 18:27:45 +00:00
}
2008-05-30 11:40:08 +00:00
2014-01-20 07:56:35 +00:00
/**
* Get session cookie name .
*
* @ return string
*/
protected static function _cookieName () {
2015-07-21 08:22:53 +00:00
if ( static :: $_cookieName !== null ) {
return static :: $_cookieName ;
2014-01-20 07:56:35 +00:00
}
2015-07-21 08:22:53 +00:00
static :: init ();
static :: _configureSession ();
2014-01-20 07:56:35 +00:00
2015-07-21 08:22:53 +00:00
return static :: $_cookieName = session_name ();
2014-01-20 07:56:35 +00:00
}
/**
* Returns whether a session exists
2014-06-04 18:58:55 +00:00
*
2014-07-03 13:36:42 +00:00
* @ return bool
2014-01-20 07:56:35 +00:00
*/
protected static function _hasSession () {
2016-01-19 22:29:56 +00:00
return static :: started () || isset ( $_COOKIE [ static :: _cookieName ()]) || ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' );
2014-01-20 07:56:35 +00:00
}
2010-07-25 18:27:45 +00:00
/**
* Find the handler class and make sure it implements the correct interface .
*
2014-06-04 18:58:55 +00:00
* @ param string $handler Handler name .
2010-07-25 18:27:45 +00:00
* @ return void
2011-07-31 20:55:52 +00:00
* @ throws CakeSessionException
2010-07-25 18:27:45 +00:00
*/
protected static function _getHandler ( $handler ) {
2010-07-25 23:09:29 +00:00
list ( $plugin , $class ) = pluginSplit ( $handler , true );
2010-12-08 00:29:07 +00:00
App :: uses ( $class , $plugin . 'Model/Datasource/Session' );
2010-07-25 18:27:45 +00:00
if ( ! class_exists ( $class )) {
2011-03-20 15:35:43 +00:00
throw new CakeSessionException ( __d ( 'cake_dev' , 'Could not load %s to handle the session.' , $class ));
2008-05-30 11:40:08 +00:00
}
2010-09-06 04:43:58 +00:00
$handler = new $class ();
if ( $handler instanceof CakeSessionHandlerInterface ) {
return $handler ;
2010-07-25 18:27:45 +00:00
}
2011-03-20 15:35:43 +00:00
throw new CakeSessionException ( __d ( 'cake_dev' , 'Chosen SessionHandler does not implement CakeSessionHandlerInterface it cannot be used with an engine key.' ));
2010-07-25 04:42:28 +00:00
}
/**
* Get one of the prebaked default session configurations .
*
2014-06-04 18:58:55 +00:00
* @ param string $name Config name .
2014-07-03 13:36:42 +00:00
* @ return bool | array
2010-07-25 04:42:28 +00:00
*/
protected static function _defaultConfig ( $name ) {
$defaults = array (
'php' => array (
'cookie' => 'CAKEPHP' ,
'timeout' => 240 ,
'ini' => array (
'session.use_trans_sid' => 0 ,
2015-07-21 08:22:53 +00:00
'session.cookie_path' => static :: $path
2010-07-25 04:42:28 +00:00
)
),
'cake' => array (
'cookie' => 'CAKEPHP' ,
'timeout' => 240 ,
'ini' => array (
'session.use_trans_sid' => 0 ,
'url_rewriter.tags' => '' ,
'session.serialize_handler' => 'php' ,
'session.use_cookies' => 1 ,
2015-07-21 08:22:53 +00:00
'session.cookie_path' => static :: $path ,
2010-07-25 05:14:41 +00:00
'session.save_path' => TMP . 'sessions' ,
'session.save_handler' => 'files'
2010-07-25 04:42:28 +00:00
)
),
'cache' => array (
'cookie' => 'CAKEPHP' ,
'timeout' => 240 ,
'ini' => array (
'session.use_trans_sid' => 0 ,
'url_rewriter.tags' => '' ,
'session.use_cookies' => 1 ,
2015-07-21 08:22:53 +00:00
'session.cookie_path' => static :: $path ,
2010-07-25 04:42:28 +00:00
'session.save_handler' => 'user' ,
),
'handler' => array (
2010-07-25 17:20:30 +00:00
'engine' => 'CacheSession' ,
'config' => 'default'
2010-07-25 04:42:28 +00:00
)
),
'database' => array (
'cookie' => 'CAKEPHP' ,
'timeout' => 240 ,
'ini' => array (
'session.use_trans_sid' => 0 ,
'url_rewriter.tags' => '' ,
'session.use_cookies' => 1 ,
2015-07-21 08:22:53 +00:00
'session.cookie_path' => static :: $path ,
2010-07-25 04:42:28 +00:00
'session.save_handler' => 'user' ,
'session.serialize_handler' => 'php' ,
),
'handler' => array (
2010-07-25 17:20:30 +00:00
'engine' => 'DatabaseSession' ,
'model' => 'Session'
2010-07-25 04:42:28 +00:00
)
)
);
if ( isset ( $defaults [ $name ])) {
return $defaults [ $name ];
}
return false ;
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Helper method to start a session
*
2014-07-03 13:36:42 +00:00
* @ return bool Success
2008-05-30 11:40:08 +00:00
*/
2010-11-09 03:05:31 +00:00
protected static function _startSession () {
2015-07-21 08:22:53 +00:00
static :: init ();
2013-12-08 12:44:16 +00:00
session_write_close ();
2015-07-21 08:22:53 +00:00
static :: _configureSession ();
2013-12-08 12:44:16 +00:00
2008-05-30 11:40:08 +00:00
if ( headers_sent ()) {
2009-01-14 03:52:37 +00:00
if ( empty ( $_SESSION )) {
2008-05-30 11:40:08 +00:00
$_SESSION = array ();
}
} else {
2016-01-19 03:17:30 +00:00
$limit = Configure :: read ( 'Session.cacheLimiter' );
if ( ! empty ( $limit )) {
session_cache_limiter ( $limit );
}
2008-05-30 11:40:08 +00:00
session_start ();
}
2010-07-07 07:56:23 +00:00
return true ;
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Helper method to create a new session .
*
2008-09-25 16:49:56 +00:00
* @ return void
2008-05-30 11:40:08 +00:00
*/
2010-06-23 01:25:04 +00:00
protected static function _checkValid () {
2015-07-21 08:22:53 +00:00
$config = static :: read ( 'Config' );
2013-12-07 21:25:33 +00:00
if ( $config ) {
2010-07-25 21:50:08 +00:00
$sessionConfig = Configure :: read ( 'Session' );
2010-07-27 02:38:40 +00:00
2015-07-21 08:22:53 +00:00
if ( static :: valid ()) {
static :: write ( 'Config.time' , static :: $sessionTime );
2010-07-27 02:42:32 +00:00
if ( isset ( $sessionConfig [ 'autoRegenerate' ]) && $sessionConfig [ 'autoRegenerate' ] === true ) {
2010-12-06 14:08:06 +00:00
$check = $config [ 'countdown' ];
2010-05-11 04:39:10 +00:00
$check -= 1 ;
2015-07-21 08:22:53 +00:00
static :: write ( 'Config.countdown' , $check );
2008-05-30 11:40:08 +00:00
2012-01-29 20:37:14 +00:00
if ( $check < 1 ) {
2015-07-21 08:22:53 +00:00
static :: renew ();
static :: write ( 'Config.countdown' , static :: $requestCountdown );
2008-05-30 11:40:08 +00:00
}
}
} else {
2013-12-07 21:25:33 +00:00
$_SESSION = array ();
2015-07-21 08:22:53 +00:00
static :: destroy ();
static :: _setError ( 1 , 'Session Highjacking Attempted !!!' );
static :: _startSession ();
static :: _writeConfig ();
2008-05-30 11:40:08 +00:00
}
} else {
2015-07-21 08:22:53 +00:00
static :: _writeConfig ();
2008-05-30 11:40:08 +00:00
}
}
2009-07-24 19:18:37 +00:00
2013-12-07 21:25:33 +00:00
/**
* Writes configuration variables to the session
*
* @ return void
*/
protected static function _writeConfig () {
2015-07-21 08:22:53 +00:00
static :: write ( 'Config.userAgent' , static :: $_userAgent );
static :: write ( 'Config.time' , static :: $sessionTime );
static :: write ( 'Config.countdown' , static :: $requestCountdown );
2013-12-07 21:25:33 +00:00
}
2008-05-30 11:40:08 +00:00
/**
2010-07-22 08:14:49 +00:00
* Restarts this session .
2008-05-30 11:40:08 +00:00
*
2008-09-25 16:49:56 +00:00
* @ return void
2008-05-30 11:40:08 +00:00
*/
2010-07-22 08:14:49 +00:00
public static function renew () {
2015-03-30 01:42:43 +00:00
if ( session_id () === '' ) {
2014-05-22 18:28:56 +00:00
return ;
}
2016-01-19 22:29:56 +00:00
if ( isset ( $_COOKIE [ static :: _cookieName ()])) {
2015-07-21 08:22:53 +00:00
setcookie ( Configure :: read ( 'Session.cookie' ), '' , time () - 42000 , static :: $path );
2008-05-30 11:40:08 +00:00
}
2015-12-28 23:40:14 +00:00
if ( ! headers_sent ()) {
2015-12-28 16:41:23 +00:00
session_write_close ();
session_start ();
session_regenerate_id ( true );
}
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Helper method to set an internal error message .
*
2014-07-03 13:36:42 +00:00
* @ param int $errorNumber Number of the error
2008-05-30 11:40:08 +00:00
* @ param string $errorMessage Description of the error
2008-09-25 16:49:56 +00:00
* @ return void
2008-05-30 11:40:08 +00:00
*/
2011-08-20 04:43:34 +00:00
protected static function _setError ( $errorNumber , $errorMessage ) {
2015-07-21 08:22:53 +00:00
if ( static :: $error === false ) {
static :: $error = array ();
2008-05-30 11:40:08 +00:00
}
2015-07-21 08:22:53 +00:00
static :: $error [ $errorNumber ] = $errorMessage ;
static :: $lastError = $errorNumber ;
2008-05-30 11:40:08 +00:00
}
2012-03-04 19:18:04 +00:00
2010-07-25 15:42:05 +00:00
}