major session refactoring.
This commit is contained in:
parent
36ff7b81aa
commit
997a90bcf5
|
@ -154,7 +154,7 @@
|
||||||
'Redis' => 'Laravel\\Redis',
|
'Redis' => 'Laravel\\Redis',
|
||||||
'Request' => 'Laravel\\Request',
|
'Request' => 'Laravel\\Request',
|
||||||
'Response' => 'Laravel\\Response',
|
'Response' => 'Laravel\\Response',
|
||||||
'Session' => 'Laravel\\Session\\Manager',
|
'Session' => 'Laravel\\Facades\\Session',
|
||||||
'Str' => 'Laravel\\Str',
|
'Str' => 'Laravel\\Str',
|
||||||
'Validator' => 'Laravel\\Validation\\Validator',
|
'Validator' => 'Laravel\\Validation\\Validator',
|
||||||
'View' => 'Laravel\\View',
|
'View' => 'Laravel\\View',
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
<?php namespace Laravel;
|
||||||
|
|
||||||
|
class Autoloader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class alises defined for the application.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $aliases = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PSR-0 compliant libraries registered with the auto-loader.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $libraries = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The paths to be searched by the auto-loader.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $paths = array(BASE_PATH, CLASS_PATH);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new auto-loader instance.
|
||||||
|
*
|
||||||
|
* @param array $aliases
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct($aliases = array())
|
||||||
|
{
|
||||||
|
$this->aliases = $aliases;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the file corresponding to a given class.
|
||||||
|
*
|
||||||
|
* @param string $class
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function load($class)
|
||||||
|
{
|
||||||
|
// Most of the core classes are aliases for convenient access in spite
|
||||||
|
// of the namespace. If an alias is defined for the class, we will load
|
||||||
|
// the alias and bail out of the auto-load method.
|
||||||
|
if (array_key_exists($class, $this->aliases))
|
||||||
|
{
|
||||||
|
return class_alias($this->aliases[$class], $class);
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = str_replace('\\', '/', $class);
|
||||||
|
|
||||||
|
$namespace = substr($class, 0, strpos($class, '\\'));
|
||||||
|
|
||||||
|
// If the class namespace exists in the libraries array, it means that
|
||||||
|
// the library is PSR-0 compliant, and we will load it following those
|
||||||
|
// standards. This allows us to add many third-party libraries to an
|
||||||
|
// application and be able to auto-load them automatically.
|
||||||
|
if (array_key_exists($namespace, $this->libraries))
|
||||||
|
{
|
||||||
|
require CLASS_PATH.$this->psr($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->paths as $path)
|
||||||
|
{
|
||||||
|
if (file_exists($path = $path.strtolower($file).EXT))
|
||||||
|
{
|
||||||
|
require $path;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the namespace exists in the classes directory, we will assume the
|
||||||
|
// library is PSR-0 compliant, and will add the namespace to the array
|
||||||
|
// of libraries and load the class accordingly.
|
||||||
|
if (is_dir(CLASS_PATH.$namespace))
|
||||||
|
{
|
||||||
|
$this->libraries[] = $namespace;
|
||||||
|
|
||||||
|
require CLASS_PATH.$this->psr($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a path for PSR-0 compliant auto-loading.
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function psr($file)
|
||||||
|
{
|
||||||
|
return str_replace('_', '/', $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,11 +4,6 @@
|
||||||
define('CRLF', chr(13).chr(10));
|
define('CRLF', chr(13).chr(10));
|
||||||
define('EXT', '.php');
|
define('EXT', '.php');
|
||||||
|
|
||||||
/**
|
|
||||||
* Define a function that registers an array of constants if they haven't
|
|
||||||
* haven't already been registered. This allows the constants to
|
|
||||||
* be changed from their default values when unit testing.
|
|
||||||
*/
|
|
||||||
function constants($constants)
|
function constants($constants)
|
||||||
{
|
{
|
||||||
foreach ($constants as $key => $value)
|
foreach ($constants as $key => $value)
|
||||||
|
@ -17,11 +12,6 @@ function constants($constants)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Register the core framework paths. All other paths are built on
|
|
||||||
* top of these core paths. All of these paths are changable by
|
|
||||||
* the developer in the front controller.
|
|
||||||
*/
|
|
||||||
$constants = array(
|
$constants = array(
|
||||||
'APP_PATH' => realpath($application).'/',
|
'APP_PATH' => realpath($application).'/',
|
||||||
'BASE_PATH' => realpath("$laravel/..").'/',
|
'BASE_PATH' => realpath("$laravel/..").'/',
|
||||||
|
@ -34,19 +24,13 @@ function constants($constants)
|
||||||
|
|
||||||
unset($application, $public, $storage, $laravel);
|
unset($application, $public, $storage, $laravel);
|
||||||
|
|
||||||
/**
|
|
||||||
* Register all of the other framework paths. All of these paths
|
|
||||||
* are built on top of the core paths above. We still allow the
|
|
||||||
* developer to override these for easy unit testing.
|
|
||||||
*/
|
|
||||||
$constants = array(
|
$constants = array(
|
||||||
'CACHE_PATH' => STORAGE_PATH.'cache/',
|
'CACHE_PATH' => STORAGE_PATH.'cache/',
|
||||||
|
'CLASS_PATH' => APP_PATH.'classes/',
|
||||||
'CONFIG_PATH' => APP_PATH.'config/',
|
'CONFIG_PATH' => APP_PATH.'config/',
|
||||||
'CONTROLLER_PATH' => APP_PATH.'controllers/',
|
'CONTROLLER_PATH' => APP_PATH.'controllers/',
|
||||||
'DATABASE_PATH' => STORAGE_PATH.'database/',
|
'DATABASE_PATH' => STORAGE_PATH.'database/',
|
||||||
'LANG_PATH' => APP_PATH.'language/',
|
'LANG_PATH' => APP_PATH.'language/',
|
||||||
'LIBRARY_PATH' => APP_PATH.'libraries/',
|
|
||||||
'MODEL_PATH' => APP_PATH.'models/',
|
|
||||||
'ROUTE_PATH' => APP_PATH.'routes/',
|
'ROUTE_PATH' => APP_PATH.'routes/',
|
||||||
'SESSION_PATH' => STORAGE_PATH.'sessions/',
|
'SESSION_PATH' => STORAGE_PATH.'sessions/',
|
||||||
'SYS_CONFIG_PATH' => SYS_PATH.'config/',
|
'SYS_CONFIG_PATH' => SYS_PATH.'config/',
|
||||||
|
@ -57,11 +41,6 @@ function constants($constants)
|
||||||
|
|
||||||
constants($constants);
|
constants($constants);
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the Laravel environment configuration path constant.
|
|
||||||
* The environment is controlled by setting an environment
|
|
||||||
* variable on the server running Laravel.
|
|
||||||
*/
|
|
||||||
$environment = (isset($_SERVER['LARAVEL_ENV'])) ? CONFIG_PATH.$_SERVER['LARAVEL_ENV'].'/' : '';
|
$environment = (isset($_SERVER['LARAVEL_ENV'])) ? CONFIG_PATH.$_SERVER['LARAVEL_ENV'].'/' : '';
|
||||||
|
|
||||||
constants(array('ENV_CONFIG_PATH' => $environment));
|
constants(array('ENV_CONFIG_PATH' => $environment));
|
||||||
|
|
|
@ -2,69 +2,20 @@
|
||||||
|
|
||||||
require 'constants.php';
|
require 'constants.php';
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the classes that can't be resolved through the auto-loader.
|
|
||||||
* These are typically classes that are used by the auto-loader or
|
|
||||||
* configuration classes, and therefore cannot be auto-loaded.
|
|
||||||
*/
|
|
||||||
require SYS_PATH.'arr'.EXT;
|
require SYS_PATH.'arr'.EXT;
|
||||||
require SYS_PATH.'config'.EXT;
|
require SYS_PATH.'config'.EXT;
|
||||||
|
require SYS_PATH.'facades'.EXT;
|
||||||
|
require SYS_PATH.'container'.EXT;
|
||||||
|
require SYS_PATH.'autoloader'.EXT;
|
||||||
|
|
||||||
/**
|
|
||||||
* Load some core configuration files by default so we don't have to
|
|
||||||
* let them fall through the Config parser. This will allow us to
|
|
||||||
* load these files faster for each request.
|
|
||||||
*/
|
|
||||||
Config::load('application');
|
Config::load('application');
|
||||||
Config::load('container');
|
Config::load('container');
|
||||||
Config::load('session');
|
Config::load('session');
|
||||||
|
|
||||||
/**
|
IoC::bootstrap();
|
||||||
* Bootstrap the application inversion of control (IoC) container.
|
|
||||||
* The container provides the convenient resolution of objects and
|
|
||||||
* their dependencies, allowing for flexibility and testability
|
|
||||||
* within the framework and application.
|
|
||||||
*/
|
|
||||||
require SYS_PATH.'container'.EXT;
|
|
||||||
|
|
||||||
$container = new Container(Config::$items['container']);
|
spl_autoload_register(array(IoC::container()->core('autoloader'), 'load'));
|
||||||
|
|
||||||
IoC::$container = $container;
|
|
||||||
|
|
||||||
unset($container);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register the application auto-loader. The auto-loader closure
|
|
||||||
* is responsible for the lazy-loading of all of the Laravel core
|
|
||||||
* classes, as well as the developer created libraries and models.
|
|
||||||
*/
|
|
||||||
$aliases = Config::$items['application']['aliases'];
|
|
||||||
|
|
||||||
spl_autoload_register(function($class) use ($aliases)
|
|
||||||
{
|
|
||||||
if (array_key_exists($class, $aliases))
|
|
||||||
{
|
|
||||||
return class_alias($aliases[$class], $class);
|
|
||||||
}
|
|
||||||
|
|
||||||
$file = strtolower(str_replace('\\', '/', $class));
|
|
||||||
|
|
||||||
foreach (array(BASE_PATH, MODEL_PATH, LIBRARY_PATH) as $path)
|
|
||||||
{
|
|
||||||
if (file_exists($path = $path.$file.EXT))
|
|
||||||
{
|
|
||||||
require_once $path;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
unset($aliases);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define a few convenient global functions.
|
|
||||||
*/
|
|
||||||
function e($value)
|
function e($value)
|
||||||
{
|
{
|
||||||
return HTML::entities($value);
|
return HTML::entities($value);
|
||||||
|
|
|
@ -2,25 +2,11 @@
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
|
||||||
/*
|
'laravel.autoloader' => array('singleton' => true, 'resolver' => function($c)
|
||||||
|--------------------------------------------------------------------------
|
{
|
||||||
| Laravel Routing Components
|
return new Autoloader(Config::$items['application']['aliases']);
|
||||||
|--------------------------------------------------------------------------
|
}),
|
||||||
|
|
|
||||||
| The following components are used by the Laravel routing system.
|
|
||||||
|
|
|
||||||
| The router is used to map a given method and URI to a route intance.
|
|
||||||
|
|
|
||||||
| The route loader is responsible for loading the appropriates routes file
|
|
||||||
| for a given request URI, as well as loading all routes when the framework
|
|
||||||
| needs to find a named route wtihin the application.
|
|
||||||
|
|
|
||||||
| The route caller is responsible for receiving a route and taking the
|
|
||||||
| appropriate action to execute that route. Some routes delegate execution
|
|
||||||
| to a controller, so this class will also resolve controllers out of the
|
|
||||||
| container and call the appropriate methods on those controllers.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'laravel.routing.router' => array('singleton' => true, 'resolver' => function($c)
|
'laravel.routing.router' => array('singleton' => true, 'resolver' => function($c)
|
||||||
{
|
{
|
||||||
|
@ -39,17 +25,6 @@
|
||||||
return new Routing\Caller($c, require APP_PATH.'filters'.EXT, CONTROLLER_PATH);
|
return new Routing\Caller($c, require APP_PATH.'filters'.EXT, CONTROLLER_PATH);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Laravel Database Connectors
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| The following components are used to establish PDO database connections
|
|
||||||
| to the various database systems supported by Laravel. By resolving these
|
|
||||||
| connectors out of the IoC container, new database systems may be added
|
|
||||||
| by simply registering a connector in the container.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'laravel.database.connectors.sqlite' => array('resolver' => function($c)
|
'laravel.database.connectors.sqlite' => array('resolver' => function($c)
|
||||||
{
|
{
|
||||||
|
@ -66,16 +41,6 @@
|
||||||
return new Database\Connectors\Postgres;
|
return new Database\Connectors\Postgres;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Laravel Caching Components
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| The following components are used by the wonderfully simple Laravel cache
|
|
||||||
| system. Each driver is resolved through the container, so new drivers may
|
|
||||||
| be added by simply registering them in the container.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'laravel.cache.apc' => array('resolver' => function($c)
|
'laravel.cache.apc' => array('resolver' => function($c)
|
||||||
{
|
{
|
||||||
|
@ -118,29 +83,6 @@
|
||||||
return $memcache;
|
return $memcache;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Laravel Session Components
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| The following components are used by the Laravel session system.
|
|
||||||
|
|
|
||||||
| The framework allows the session ID to be transported via a variety
|
|
||||||
| of different mechanisms by resolve the ID itself and the session
|
|
||||||
| transporter instance out of the container. This allows sessions
|
|
||||||
| to be used by clients who cannot receive cookies.
|
|
||||||
|
|
|
||||||
| The session manager is responsible for loading the session payload
|
|
||||||
| from the session driver, as well as examining the payload validitiy
|
|
||||||
| and things like the CSRF token.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'laravel.session.transporter' => array('resolver' => function($c)
|
|
||||||
{
|
|
||||||
return new Session\Transporters\Cookie;
|
|
||||||
}),
|
|
||||||
|
|
||||||
|
|
||||||
'laravel.session.apc' => array('resolver' => function($c)
|
'laravel.session.apc' => array('resolver' => function($c)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,16 @@ class IoC {
|
||||||
*/
|
*/
|
||||||
public static $container;
|
public static $container;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bootstrap the global IoC instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function bootstrap()
|
||||||
|
{
|
||||||
|
static::$container = new Container(Config::$items['container']);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the active container instance.
|
* Get the active container instance.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
<?php namespace Laravel\Facades;
|
||||||
|
|
||||||
|
use Laravel\IoC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Laravel framework makes thorough use of dependency injection assisted by an application
|
||||||
|
* inversion of control container. This allows for great flexibility, easy testing, and better
|
||||||
|
* architecture. However, most PHP framework users may be used to accessing classes through
|
||||||
|
* a variety of static methods. Laravel provides "facades" to simulate this behavior while
|
||||||
|
* still using heavy dependency injection.
|
||||||
|
*
|
||||||
|
* Each class that is commonly used by the developer has a corresponding facade defined in
|
||||||
|
* this file. All of the various facades inherit from the abstract Facade class, which only
|
||||||
|
* has a single __callStatic magic method. The facade simply resolves the requested class
|
||||||
|
* out of the IoC container and calls the appropriate method.
|
||||||
|
*/
|
||||||
|
abstract class Facade {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic Method for passing methods to a class registered in the IoC container.
|
||||||
|
* This provides a convenient method of accessing functions on classes that
|
||||||
|
* could not otherwise be accessed staticly.
|
||||||
|
*
|
||||||
|
* Facades allow Laravel to still have a high level of dependency injection
|
||||||
|
* and testability while still accomodating the common desire to conveniently
|
||||||
|
* use classes via static methods.
|
||||||
|
*/
|
||||||
|
public static function __callStatic($method, $parameters)
|
||||||
|
{
|
||||||
|
$class = IoC::container()->resolve(static::$resolve);
|
||||||
|
|
||||||
|
$count = count($parameters);
|
||||||
|
|
||||||
|
if ($count > 5)
|
||||||
|
{
|
||||||
|
return call_user_func_array(array($class, $method), $parameters);
|
||||||
|
}
|
||||||
|
elseif ($count == 1)
|
||||||
|
{
|
||||||
|
return $class->$method($parameters[0]);
|
||||||
|
}
|
||||||
|
elseif ($count == 2)
|
||||||
|
{
|
||||||
|
return $class->$method($parameters[0], $parameters[1]);
|
||||||
|
}
|
||||||
|
elseif ($count == 3)
|
||||||
|
{
|
||||||
|
return $class->$method($parameters[0], $parameters[1], $parameters[2]);
|
||||||
|
}
|
||||||
|
elseif ($count == 4)
|
||||||
|
{
|
||||||
|
return $class->$method($parameters[0], $parameters[1], $parameters[2], $parameters[3]);
|
||||||
|
}
|
||||||
|
elseif ($count == 5)
|
||||||
|
{
|
||||||
|
return $class->$method($parameters[0], $parameters[1], $parameters[2], $parameters[3], $parameters[4]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Autoloader extends Facade { public static $resolve = 'laravel.autoloader'; }
|
||||||
|
class Session extends Facade { public static $resolve = 'laravel.session'; }
|
|
@ -159,7 +159,7 @@ public static function raw_token()
|
||||||
throw new \Exception("A session driver must be specified before using CSRF tokens.");
|
throw new \Exception("A session driver must be specified before using CSRF tokens.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Session\Manager::get('csrf_token');
|
return IoC::container()->core('session')->get('csrf_token');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -96,7 +96,9 @@ public static function old($key = null, $default = null)
|
||||||
throw new \Exception('A session driver must be specified in order to access old input.');
|
throw new \Exception('A session driver must be specified in order to access old input.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return Arr::get(Session\Manager::get(Input::old_input, array()), $key, $default);
|
$session = IoC::container()->core('session');
|
||||||
|
|
||||||
|
return Arr::get($session->get(Input::old_input, array()), $key, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -26,11 +26,21 @@
|
||||||
*/
|
*/
|
||||||
if (Config::$items['session']['driver'] !== '')
|
if (Config::$items['session']['driver'] !== '')
|
||||||
{
|
{
|
||||||
|
require SYS_PATH.'cookie'.EXT;
|
||||||
|
require SYS_PATH.'session/payload'.EXT;
|
||||||
|
|
||||||
$driver = IoC::container()->core('session.'.Config::$items['session']['driver']);
|
$driver = IoC::container()->core('session.'.Config::$items['session']['driver']);
|
||||||
|
|
||||||
$transporter = IoC::container()->core('session.transporter');
|
if ( ! is_null($id = Cookie::get(Session\Payload::cookie)))
|
||||||
|
{
|
||||||
|
$payload = new Session\Payload($driver->load($id));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$payload = new Session\Payload;
|
||||||
|
}
|
||||||
|
|
||||||
Session\Manager::start($driver, $transporter);
|
IoC::container()->instance('laravel.session', $payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -113,13 +123,13 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the session and write the active payload to persistent
|
* Close the session and write the active payload to persistent
|
||||||
* storage. The input for the current request is also flashed
|
* storage. The session cookie will also be written and if the
|
||||||
* to the session so it will be available for the next request
|
* driver is a sweeper, session garbage collection might be
|
||||||
* via the Input::old method.
|
* performed depending on the "sweepage" probability.
|
||||||
*/
|
*/
|
||||||
if (Config::$items['session']['driver'] !== '')
|
if (Config::$items['session']['driver'] !== '')
|
||||||
{
|
{
|
||||||
Session\Manager::close();
|
IoC::container()->core('session')->save($driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -61,7 +61,7 @@ public function with($key, $value)
|
||||||
throw new \Exception('A session driver must be set before setting flash data.');
|
throw new \Exception('A session driver must be set before setting flash data.');
|
||||||
}
|
}
|
||||||
|
|
||||||
Session\Manager::flash($key, $value);
|
IoC::container()->core('session')->flash($key, $value);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1 @@
|
||||||
|
*
|
Loading…
Reference in New Issue