major session refactoring.
This commit is contained in:
@@ -1,289 +0,0 @@
|
||||
<?php namespace Laravel\Session;
|
||||
|
||||
use Closure;
|
||||
use Laravel\Str;
|
||||
use Laravel\Config;
|
||||
use Laravel\Session\Drivers\Driver;
|
||||
use Laravel\Session\Transporters\Transporter;
|
||||
|
||||
class Manager {
|
||||
|
||||
/**
|
||||
* The current session payload.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $session = array();
|
||||
|
||||
/**
|
||||
* Indicates if the session exists in persistent storage.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public static $exists = true;
|
||||
|
||||
/**
|
||||
* Indicates if the session ID has been regenerated.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public static $regenerated = false;
|
||||
|
||||
/**
|
||||
* The driver being used by the session.
|
||||
*
|
||||
* @var Drivers\Driver
|
||||
*/
|
||||
protected static $driver;
|
||||
|
||||
/**
|
||||
* The session ID transporter used by the session.
|
||||
*
|
||||
* @var Transporters\Transpoter
|
||||
*/
|
||||
protected static $transporter;
|
||||
|
||||
/**
|
||||
* Start the session handling for the current request.
|
||||
*
|
||||
* @param Drivers\Driver $driver
|
||||
* @param Transporters\Transporter $transporter
|
||||
* @return Payload
|
||||
*/
|
||||
public static function start(Driver $driver, Transporter $transporter)
|
||||
{
|
||||
$config = Config::$items['session'];
|
||||
|
||||
$session = $driver->load($transporter->get($config));
|
||||
|
||||
// If the session is expired, a new session will be generated and all of
|
||||
// the data from the previous session will be lost. The new session will
|
||||
// be assigned a random, long string ID to uniquely identify it among
|
||||
// the application's current users.
|
||||
if (is_null($session) or (time() - $session['last_activity']) > ($config['lifetime'] * 60))
|
||||
{
|
||||
static::$exists = false;
|
||||
|
||||
$session = array('id' => Str::random(40), 'data' => array());
|
||||
}
|
||||
|
||||
// Now that we should have a valid session, we can set the static session
|
||||
// property and check for session data such as the CSRF token. We will
|
||||
// also set the static driver and transporter properties, since they
|
||||
// will be used to close the session at the end of the request.
|
||||
static::$session = $session;
|
||||
|
||||
if ( ! static::has('csrf_token')) static::put('csrf_token', Str::random(16));
|
||||
|
||||
list(static::$driver, static::$transporter) = array($driver, $transporter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the session or flash data contains an item.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public static function has($key)
|
||||
{
|
||||
return ( ! is_null(static::get($key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item from the session.
|
||||
*
|
||||
* <code>
|
||||
* // Get an item from the session
|
||||
* $name = Session::get('name');
|
||||
*
|
||||
* // Return a default value if the item doesn't exist
|
||||
* $name = Session::get('name', 'Taylor');
|
||||
* </code>
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get($key, $default = null)
|
||||
{
|
||||
foreach (array($key, ':old:'.$key, ':new:'.$key) as $possibility)
|
||||
{
|
||||
if (array_key_exists($possibility, static::$session['data']))
|
||||
{
|
||||
return static::$session['data'][$possibility];
|
||||
}
|
||||
}
|
||||
|
||||
return ($default instanceof Closure) ? call_user_func($default) : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an item to the session.
|
||||
*
|
||||
* <code>
|
||||
* // Write an item to the session
|
||||
* Session::put('name', 'Taylor');
|
||||
* </code>
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public static function put($key, $value)
|
||||
{
|
||||
static::$session['data'][$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an item to the session flash data.
|
||||
*
|
||||
* Flash data only exists for the next request. After that, it will be
|
||||
* removed from the session. Flash data is useful for temporary status
|
||||
* or welcome messages.
|
||||
*
|
||||
* <code>
|
||||
* // Flash an item to the session
|
||||
* Session::flash('name', 'Taylor');
|
||||
* </code>
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public static function flash($key, $value)
|
||||
{
|
||||
static::put(':new:'.$key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep all of the session flash data from expiring at the end of the request.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function reflash()
|
||||
{
|
||||
static::replace(':old:', ':new:', array_keys(static::$session['data']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep a session flash item from expiring at the end of the request.
|
||||
*
|
||||
* If a string is passed to the method, only that item will be kept.
|
||||
* An array may also be passed to the method, in which case all
|
||||
* items in the array will be kept.
|
||||
*
|
||||
* <code>
|
||||
* // Keep a session flash item from expiring
|
||||
* Session::keep('name');
|
||||
* </code>
|
||||
*
|
||||
* @param string|array $key
|
||||
* @return void
|
||||
*/
|
||||
public static function keep($key)
|
||||
{
|
||||
if (is_array($key))
|
||||
{
|
||||
return array_map(array('Laravel\\Session\\Manager', 'keep'), $key);
|
||||
}
|
||||
|
||||
static::flash($key, static::get($key));
|
||||
|
||||
static::forget(':old:'.$key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item from the session.
|
||||
*
|
||||
* @param string $key
|
||||
* @return Driver
|
||||
*/
|
||||
public static function forget($key)
|
||||
{
|
||||
unset(static::$session['data'][$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all items from the session.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function flush()
|
||||
{
|
||||
static::$session['data'] = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerate the session ID.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function regenerate()
|
||||
{
|
||||
static::$session['id'] = Str::random(40);
|
||||
|
||||
static::$regenerated = true;
|
||||
|
||||
static::$exists = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Age the session payload, preparing it for storage after a request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function age()
|
||||
{
|
||||
static::$session['last_activity'] = time();
|
||||
|
||||
foreach (static::$session['data'] as $key => $value)
|
||||
{
|
||||
if (strpos($key, ':old:') === 0) static::forget($key);
|
||||
}
|
||||
|
||||
static::replace(':new:', ':old:', array_keys(static::$session['data']));
|
||||
|
||||
return static::$session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Readdress the session data by performing a string replacement on the keys.
|
||||
*
|
||||
* @param string $search
|
||||
* @param string $replace
|
||||
* @param array $keys
|
||||
* @return void
|
||||
*/
|
||||
protected static function replace($search, $replace, $keys)
|
||||
{
|
||||
$keys = str_replace($search, $replace, $keys);
|
||||
|
||||
static::$session['data'] = array_combine($keys, array_values(static::$session['data']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the session handling for the request.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function close()
|
||||
{
|
||||
$config = Config::$items['session'];
|
||||
|
||||
static::$driver->save(static::age(), $config, static::$exists);
|
||||
|
||||
static::$transporter->put(static::$session['id'], $config);
|
||||
|
||||
// Some session drivers clean-up expired sessions manually; however, since
|
||||
// this can be an expensive process, it is only performed once in a while.
|
||||
// The probability of session garbage collection occuring for any given
|
||||
// request is controlled by the "sweepage" configuration option.
|
||||
$sweep = (mt_rand(1, $config['sweepage'][1]) <= $config['sweepage'][0]);
|
||||
|
||||
if ($sweep and static::$driver instanceof Drivers\Sweeper)
|
||||
{
|
||||
static::$driver->sweep(time() - ($config['lifetime'] * 60));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
279
laravel/session/payload.php
Normal file
279
laravel/session/payload.php
Normal file
@@ -0,0 +1,279 @@
|
||||
<?php namespace Laravel\Session;
|
||||
|
||||
use Laravel\Str;
|
||||
use Laravel\Config;
|
||||
use Laravel\Cookie;
|
||||
use Laravel\Session\Drivers\Driver;
|
||||
use Laravel\Session\Drivers\Sweeper;
|
||||
|
||||
class Payload {
|
||||
|
||||
/**
|
||||
* The session array that is stored by the driver.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $session;
|
||||
|
||||
/**
|
||||
* Indicates if the session already exists in storage.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $exists = true;
|
||||
|
||||
/**
|
||||
* The name of the session cookie used to store the session ID.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const cookie = 'laravel_session';
|
||||
|
||||
/**
|
||||
* Create a new session payload instance.
|
||||
*
|
||||
* @param array $session
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($session = null)
|
||||
{
|
||||
$this->session = $session;
|
||||
|
||||
if ($this->invalid())
|
||||
{
|
||||
$this->exists = false;
|
||||
|
||||
// A CSRF token is stored in every session. The token is used by the
|
||||
// Form class and the "csrf" filter to protect the application from
|
||||
// cross-site request forgery attacks. The token is simply a long,
|
||||
// random string which should be posted with each request.
|
||||
$token = Str::random(40);
|
||||
|
||||
$this->session = array('id' => Str::random(40), 'data' => compact('token'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deteremine if the session payload instance is valid.
|
||||
*
|
||||
* The session is considered valid if it exists and has not expired.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function invalid()
|
||||
{
|
||||
$lifetime = Config::$items['session']['lifetime'];
|
||||
|
||||
return is_null($this->session) or (time() - $this->last_activity > ($lifetime * 60));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the session or flash data contains an item.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return ( ! is_null($this->get($key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item from the session.
|
||||
*
|
||||
* The session flash data will also be checked for the requested item.
|
||||
*
|
||||
* <code>
|
||||
* // Get an item from the session
|
||||
* $name = Session::get('name');
|
||||
*
|
||||
* // Return a default value if the item doesn't exist
|
||||
* $name = Session::get('name', 'Taylor');
|
||||
* </code>
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
foreach (array($key, ':old:'.$key, ':new:'.$key) as $possibility)
|
||||
{
|
||||
if (array_key_exists($possibility, $this->session['data']))
|
||||
{
|
||||
return $this->session['data'][$possibility];
|
||||
}
|
||||
}
|
||||
|
||||
return ($default instanceof Closure) ? call_user_func($default) : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an item to the session.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function put($key, $value)
|
||||
{
|
||||
$this->session['data'][$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an item to the session flash data.
|
||||
*
|
||||
* Flash data only exists for the next request to the application.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function flash($key, $value)
|
||||
{
|
||||
$this->put(':new:'.$key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep all of the session flash data from expiring at the end of the request.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function reflash()
|
||||
{
|
||||
$this->keep(array_keys($this->session['data']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep a session flash item from expiring at the end of the request.
|
||||
*
|
||||
* @param string|array $key
|
||||
* @return void
|
||||
*/
|
||||
public function keep($keys)
|
||||
{
|
||||
foreach ((array) $keys as $key) $this->flash($key, $this->get($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item from the session data.
|
||||
*
|
||||
* @param string $key
|
||||
* @return Driver
|
||||
*/
|
||||
public function forget($key)
|
||||
{
|
||||
unset($this->session['data'][$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all of the items from the session.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
$this->session['data'] = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a new, random ID to the session.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function regenerate()
|
||||
{
|
||||
$this->session['id'] = Str::random(40);
|
||||
|
||||
$this->exists = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the session payload in storage.
|
||||
*
|
||||
* @param Driver $driver
|
||||
* @return void
|
||||
*/
|
||||
public function save(Driver $driver)
|
||||
{
|
||||
$this->session['last_activity'] = time();
|
||||
|
||||
$this->age();
|
||||
|
||||
$config = Config::$items['session'];
|
||||
|
||||
// To keep the session persistence code clean, session drivers are
|
||||
// responsible for the storage of the session array to the various
|
||||
// available persistent storage mechanisms.
|
||||
$driver->save($this->session, $config, $this->exists);
|
||||
|
||||
$this->cookie();
|
||||
|
||||
// Some session drivers implement the Sweeper interface, meaning that they
|
||||
// must clean up expired sessions manually. If the driver is a sweeper, we
|
||||
// need to determine if garbage collection should be run for the request.
|
||||
// Since garbage collection can be expensive, the probability of it
|
||||
// occuring is controlled by the "sweepage" configuration option.
|
||||
if ($driver instanceof Sweeper and (mt_rand(1, $config['sweepage'][1]) <= $config['sweepage'][0]))
|
||||
{
|
||||
$driver->sweep(time() - ($config['lifetime'] * 60));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Age the session flash data.
|
||||
*
|
||||
* Session flash data is only available during the request in which it
|
||||
* was flashed, and the request after that. To "age" the data, we will
|
||||
* remove all of the :old: items and re-address the new items.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function age()
|
||||
{
|
||||
foreach ($this->session['data'] as $key => $value)
|
||||
{
|
||||
if (strpos($key, ':old:') === 0) $this->forget($key);
|
||||
}
|
||||
|
||||
$this->replace(':new:', ':old:', array_keys($this->session['data']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-address the session data by performing a string replacement on the keys.
|
||||
*
|
||||
* @param string $search
|
||||
* @param string $replace
|
||||
* @param array $keys
|
||||
* @return void
|
||||
*/
|
||||
protected function replace($search, $replace, $keys)
|
||||
{
|
||||
$keys = str_replace($search, $replace, $keys);
|
||||
|
||||
$this->session['data'] = array_combine($keys, array_values($this->session['data']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the session ID cookie to the browser.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function cookie()
|
||||
{
|
||||
$config = Config::$items['session'];
|
||||
|
||||
$minutes = ( ! $config['expire_on_close']) ? $config['lifetime'] : 0;
|
||||
|
||||
Cookie::put(Payload::cookie, $this->id, $minutes, $config['path'], $config['domain'], $config['secure']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically retrieve items from the session array.
|
||||
*/
|
||||
public function __get($key)
|
||||
{
|
||||
return (isset($this->session[$key])) ? $this->session[$key] : $this->get($key);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
<?php namespace Laravel\Session\Transporters;
|
||||
|
||||
class Cookie implements Transporter {
|
||||
|
||||
/**
|
||||
* The name of the cookie used to store the session ID.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const key = 'laravel_session';
|
||||
|
||||
/**
|
||||
* Get the session identifier for the request.
|
||||
*
|
||||
* @param array $config
|
||||
* @return string
|
||||
*/
|
||||
public function get($config)
|
||||
{
|
||||
return \Laravel\Cookie::get(Cookie::key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the session identifier for the request.
|
||||
*
|
||||
* @param string $id
|
||||
* @param array $config
|
||||
* @return void
|
||||
*/
|
||||
public function put($id, $config)
|
||||
{
|
||||
extract($config, EXTR_SKIP);
|
||||
|
||||
$minutes = ( ! $expire_on_close) ? $lifetime : 0;
|
||||
|
||||
\Laravel\Cookie::put(Cookie::key, $id, $minutes, $path, $domain, $secure);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
<?php namespace Laravel\Session\Transporters;
|
||||
|
||||
/**
|
||||
* Session transporters are responsible for getting the session identifier
|
||||
* to the client. This can be done via cookies or some other means.
|
||||
*/
|
||||
interface Transporter {
|
||||
|
||||
/**
|
||||
* Get the session identifier for the request.
|
||||
*
|
||||
* @param array $config
|
||||
* @return string
|
||||
*/
|
||||
public function get($config);
|
||||
|
||||
/**
|
||||
* Store the session identifier for the request.
|
||||
*
|
||||
* @param string $id
|
||||
* @param array $config
|
||||
* @return void
|
||||
*/
|
||||
public function put($id, $config);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user