Source code for file /joomla/environment/session.php
Documentation is available at session.php
* @version $Id: session.php 6674 2007-02-19 05:52:03Z Jinx $
* @package Joomla.Framework
* @subpackage Environment
* @copyright Copyright (C) 2005 - 2007 Open Source Matters. All rights reserved.
* @license GNU/GPL, see LICENSE.php
* Joomla! is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See COPYRIGHT.php for copyright notices and details.
// Check to ensure this file is within the rest of the framework
jimport('joomla.environment.sessionstorage');
* Class for managing HTTP sessions
* Provides access to session-state values as well as session-level
* settings and lifetime management methods.
* Based on the standart PHP session handling mechanism it provides
* for you more advanced features such as expire timeouts.
* @package Joomla.Framework
* @subpackage Environment
* @var string $_state one of 'active'|'expired'|'destroyed|'error'
* Maximum age of unused session
* @var string $_expire minutes
* The session store object
* @var object A JSessionStorage object
* @var array $_security list of checks that will be done.
* @param array $options optional parameters
function __construct( $store =
'none', $options =
array() )
//set default sessios save handler
ini_set('session.save_handler', 'files');
// perform security checks
* Returns a reference to the global Session object, only creating it
* if it doesn't already exist.
* This method must be invoked as:
* <pre> $session = &JSession::getInstance();</pre>
* @return JSession The Session object.
$instance =
new JSession($handler, $options);
* Get current state of session
* @return string The session state
* Get expiration time in minutes
* @return integer The session expiration time in minutes
* Get a session token, if a token isn't set yet one will be generated.
* Tokens are used to secure forms from spamming attacks. Once a token
* has been generated the system will check the post request to see if
* it is present, if not it will invalidate the session.
* @param boolean $forceNew If true, force a new token to be created
* @return string The session token
$token =
$this->get( 'session.token' );
if( $token ===
null ||
$forceNew ) {
$this->set( 'session.token', $token );
* Method to determine if a token exists in the session. If not the
* session will be set to expired
* @param string Hashed token to be verified
* @param boolean If true, expires the session
function hasToken($tCheck, $forceExpire =
true)
// check if a token exists in the session
$tStored =
$this->get( 'session.token' );
if(($tStored !==
$tCheck))
* @return string The session name
if( $this->_state ===
'destroyed' ) {
* @return string The session name
if( $this->_state ===
'destroyed' ) {
* Get the session handlers
* @return array An array of available session handlers
jimport('joomla.filesystem.folder');
foreach($handlers as $handler)
jimport('joomla.environment.sessionstorage.'.
$name);
$class =
'JSessionStorage'.
$name;
* Check whether this session is currently created
* @return boolean $result true on success
$counter =
$this->get( 'session.counter' );
* Get data from the session store
* @param string $name Name of a variable
* @param mixed $default Default value of a variable if not set
* @param string $namespace Namespace to use, default to 'default'
* @return mixed Value of a variable
function &get($name, $default =
null, $namespace =
'default')
$namespace =
'__'.
$namespace; //add prefix to namespace to avoid collisions
if($this->_state !==
'active' &&
$this->_state !==
'expired') {
// @TODO :: generated error here
if (isset
($_SESSION[$namespace][$name])) {
return $_SESSION[$namespace][$name];
* Set data into the session store
* @param string $name Name of a variable
* @param mixed $value Value of a variable
* @param string $namespace Namespace to use, default to 'default'
* @return mixed Old value of a variable
function set($name, $value, $namespace =
'default')
$namespace =
'__'.
$namespace; //add prefix to namespace to avoid collisions
if($this->_state !==
'active') {
// @TODO :: generated error here
$old = isset
($_SESSION[$namespace][$name]) ?
$_SESSION[$namespace][$name] :
null;
unset
($_SESSION[$namespace][$name]);
$_SESSION[$namespace][$name] =
$value;
* Check wheter data exists in the session store
* @param string $name Name of variable
* @param string $namespace Namespace to use, default to 'default'
* @return boolean $result true if the variable exists
function has( $name, $namespace =
'default' )
$namespace =
'__'.
$namespace; //add prefix to namespace to avoid collisions
if( $this->_state !==
'active' ) {
// @TODO :: generated error here
return isset
( $_SESSION[$namespace][$name] );
* Unset data from the session store
* @param string $name Name of variable
* @param string $namespace Namespace to use, default to 'default'
* @return mixed $value the value from session or NULL if not set
function clear( $name, $namespace =
'default' )
$namespace =
'__'.
$namespace; //add prefix to namespace to avoid collisions
if( $this->_state !==
'active' ) {
// @TODO :: generated error here
if( isset
( $_SESSION[$namespace][$name] ) ) {
$value =
$_SESSION[$namespace][$name];
unset
( $_SESSION[$namespace][$name] );
* Creates a session (or resumes the current one based on the state of the session)
* @return boolean $result true on success
// start session if not startet
if( $this->_state ==
'restart' ) {
// Send modified header for IE 6.0 Security Policy
header('P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"');
* Frees all session variables and destroys all data registered to a session
* This method resets the $_SESSION variable and destroys all of the data associated
* with the current session in its storage (file or DB). It forces new session to be
* started after this method is called. It does not unset the session cookie.
// session was already destroyed
if( $this->_state ===
'destroyed' ) {
// In order to kill the session altogether, like to log the user out, the session id
// must also be unset. If a cookie is used to propagate the session id (default behavior),
// then the session cookie must be deleted.
* restart an expired or locked session
* @return boolean $result true on success
if( $this->_state !==
'destroyed' ) {
// @TODO :: generated error here
// Re-register the session handler after a session has been destroyed, to avoid PHP bug
* Create a new session and copy variables from the old one
* @return boolean $result true on success
if( $this->_state !==
'active' ) {
// @TODO :: generated error here
$trans =
ini_get( 'session.use_trans_sid' );
ini_set( 'session.use_trans_sid', 0 );
// re-register the session store after a session has been destroyed, to avoid PHP bug
ini_set( 'session.use_trans_sid', $trans );
// restart session with new id
* Writes session data and ends session
* Session data is usually stored after your script terminated without the need
* to call JSession::close(),but as session data is locked to prevent concurrent
* writes only one script may operate on a session at any time. When using
* framesets together with sessions you will experience the frames loading one
* by one due to this locking. You can reduce the time needed to load all the
* frames by ending the session as soon as all changes to session variables are
* @see session_write_close()
* @return string Session ID
* @param int $length lenght of string
* @return string $id generated token
static $chars =
'0123456789abcdef';
$max =
strlen( $chars ) -
1;
for( $i =
0; $i <
$length; ++
$i ) {
$token .=
$chars[ (rand( 0, $max )) ];
return md5($token.
$name);
* Set counter of session usage
* @return boolean $result true on success
$counter =
$this->get( 'session.counter', 0 );
$this->set( 'session.counter', $counter );
* @return boolean $result true on success
if( !$this->has( 'session.timer.start' ) )
$this->set( 'session.timer.start' , $start );
$this->set( 'session.timer.last' , $start );
$this->set( 'session.timer.now' , $start );
$this->set( 'session.timer.last', $this->get( 'session.timer.now' ) );
$this->set( 'session.timer.now', time() );
* set additional session options
* @param array $options list of parameter
* @return boolean $result true on success
if( isset
( $options['name'] ) ) {
if( isset
( $options['id'] ) ) {
if( isset
( $options['expire'] ) ) {
$this->_expire =
$options['expire'];
if( isset
( $options['security'] ) ) {
//sync the session maxlifetime
* Do some checks for security reason
* - timeout check (expire)
* If one check failed, session data has to be cleaned.
* @param boolean $restart reactivate session
* @return boolean $result true on success
* @see http://shiflett.org/articles/the-truth-about-sessions
// allow to restart a session
$this->set( 'session.client.address' , null );
$this->set( 'session.client.forwarded' , null );
$this->set( 'session.client.browser' , null );
$this->set( 'session.token' , null );
// check if session has expired
$curTime =
$this->get( 'session.timer.now' , 0 );
$maxTime =
$this->get( 'session.timer.last', 0 ) +
(60 *
$this->_expire);
// empty session variables
if( $maxTime <
$curTime ) {
// record proxy forwarded for in the session in case we need it later
if( isset
( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
$this->set( 'session.client.forwarded', $_SERVER['HTTP_X_FORWARDED_FOR']);
// check for client adress
$ip =
$this->get( 'session.client.address' );
$this->set( 'session.client.address', $_SERVER['REMOTE_ADDR'] );
else if( $_SERVER['REMOTE_ADDR'] !==
$ip )
// check for clients browser
if( in_array( 'fix_browser', $this->_security ) && isset
( $_SERVER['HTTP_USER_AGENT'] ) )
$browser =
$this->get( 'session.client.browser' );
if( $browser ===
null ) {
$this->set( 'session.client.browser', $_SERVER['HTTP_USER_AGENT']);
else if( $_SERVER['HTTP_USER_AGENT'] !==
$browser )