refactoring.

This commit is contained in:
Taylor Otwell
2011-08-23 21:04:40 -05:00
parent 1a7fd6d360
commit df84e36314
34 changed files with 799 additions and 349 deletions

View File

@@ -21,6 +21,13 @@ class Auth {
*/
protected $session;
/**
* The hashing engine that should be used to perform hashing.
*
* @var Hash\Engine
*/
protected $hasher;
/**
* The key used to store the user ID in the session.
*
@@ -31,11 +38,13 @@ class Auth {
/**
* Create a new Auth class instance.
*
* @param Session\Driver $session_driver
* @param Session\Driver $driver
* @param Hash\Engine $hasher
* @return void
*/
public function __construct(Session\Driver $driver)
public function __construct(Session\Driver $driver, Hash\Engine $hasher)
{
$this->hasher = $hasher;
$this->session = $driver;
}
@@ -97,7 +106,7 @@ class Auth {
{
if ( ! is_null($user = call_user_func(Config::get('auth.by_username'), $username)))
{
if (Hash::check($password, $user->password))
if ($this->hasher->check($password, $user->password))
{
$this->remember($user);
@@ -142,22 +151,4 @@ class Auth {
$this->session->forget(static::$key);
}
/**
* Pass all other methods to a generic Auth instance.
*
* This provides a convenient API for working with the default Auth configuration.
*
* <code>
* // Get the current user of your application
* $user = Auth::user();
*
* // Equivalent call using make method
* $user = Auth::make()->user();
* </code>
*/
public static function __callStatic($method, $parameters)
{
return call_user_func_array(array(new static(Session::driver()), $method), $parameters);
}
}

View File

@@ -29,7 +29,7 @@ return array(
'Eloquent' => 'Laravel\\DB\\Eloquent\\Model',
'File' => 'Laravel\\File',
'Form' => 'Laravel\\Form',
'Hash' => 'Laravel\\Hash',
'Hasher' => 'Laravel\\Hasher',
'HTML' => 'Laravel\\HTML',
'Inflector' => 'Laravel\\Inflector',
'Input' => 'Laravel\\Input',

View File

@@ -3,7 +3,10 @@
class Form {
/**
* Stores labels names.
* All of the label names that have been created.
*
* These names are stored so that input elements can automatically be assigned
* an ID based on the corresponding label name.
*
* @var array
*/
@@ -12,6 +15,21 @@ class Form {
/**
* Open a HTML form.
*
* <code>
* // Open a POST form for the current URI
* echo Form::open();
*
* // Open a POST form to a specified URI
* echo Form::open('user/login');
*
* // Open a PUT form to a specified URI
* echo Form::open('user/profile', 'put');
* </code>
*
* Note: If PUT or DELETE is specified as the form method, a hidden input field will be generated
* containing the request method. PUT and DELETE are not supported by HTML forms, so the
* hidden field will allow us to "spoof" PUT and DELETE requests.
*
* @param string $action
* @param string $method
* @param array $attributes
@@ -20,29 +38,48 @@ class Form {
*/
public static function open($action = null, $method = 'POST', $attributes = array(), $https = false)
{
$attributes['action'] = HTML::entities(URL::to(((is_null($action)) ? Request::uri() : $action), $https));
// PUT and DELETE methods are spoofed using a hidden field containing the request method.
// Since, HTML does not support PUT and DELETE on forms, we will use POST.
$attributes['method'] = ($method == 'PUT' or $method == 'DELETE') ? 'POST' : $method;
list($attributes['action'], $attributes['method']) = array(static::action($action, $https), static::method($method));
if ( ! array_key_exists('accept-charset', $attributes))
{
$attributes['accept-charset'] = Config::get('application.encoding');
}
$html = '<form'.HTML::attributes($attributes).'>';
$append = ($method == 'PUT' or $method == 'DELETE') ? static::hidden('REQUEST_METHOD', $method) : '';
if ($method == 'PUT' or $method == 'DELETE')
{
$html .= PHP_EOL.static::input('hidden', 'REQUEST_METHOD', $method);
}
return $html.PHP_EOL;
return '<form'.HTML::attributes($attributes).'>'.$append.PHP_EOL;
}
/**
* Open a HTML form with a HTTPS action.
* Determine the appropriate request method to use for a form.
*
* Since PUT and DELETE requests are spoofed using POST requests, we will substitute
* POST for any PUT or DELETE methods. Otherwise, the specified method will be used.
*
* @param string $method
* @return string
*/
private static function method($method)
{
return strtoupper(($method == 'PUT' or $method == 'DELETE') ? 'POST' : $method);
}
/**
* Determine the appropriate action parameter to use for a form.
*
* If no action is specified, the current request URI will be used.
*
* @param string $action
* @param bool $https
* @return string
*/
private static function action($action, $https)
{
return HTML::entities(URL::to(((is_null($action)) ? Request::uri() : $action), $https));
}
/**
* Open a HTML form with a HTTPS action URI.
*
* @param string $action
* @param string $method
@@ -71,7 +108,7 @@ class Form {
}
/**
* Open a HTML form that accepts file uploads with a HTTPS action.
* Open a HTML form that accepts file uploads with a HTTPS action URI.
*
* @param string $action
* @param string $method
@@ -96,31 +133,40 @@ class Form {
/**
* Generate a hidden field containing the current CSRF token.
*
* If a session driver is not provided, the default session driver will be used.
*
* @param Session\Driver $driver
* @return string
*/
public static function token()
public static function token(Session\Driver $driver = null)
{
return static::input('hidden', 'csrf_token', static::raw_token());
if (is_null($driver)) $driver = Session::driver();
return static::input('hidden', 'csrf_token', static::raw_token($driver));
}
/**
* Retrieve the current CSRF token.
*
* If a session driver is not provided, the default session driver will be used.
*
* @param Session\Driver $driver
* @return string
*/
public static function raw_token()
public static function raw_token(Session\Driver $driver = null)
{
if (Config::get('session.driver') == '')
{
throw new \Exception('Sessions must be enabled to retrieve a CSRF token.');
}
if (is_null($driver)) $driver = Session::driver();
return Session::get('csrf_token');
return $driver->get('csrf_token');
}
/**
* Create a HTML label element.
*
* <code>
* echo Form::label('email', 'E-Mail Address');
* </code>
*
* @param string $name
* @param string $value
* @param array $attributes
@@ -136,6 +182,17 @@ class Form {
/**
* Create a HTML input element.
*
* If an ID attribute is not specified and a label has been generated matching the input
* element name, the label name will be used as the element ID.
*
* <code>
* // Generate a text type input element
* echo Form::input('text', 'email');
*
* // Generate a hidden type input element with a specified value
* echo Form::input('hidden', 'secret', 'This is a secret.');
* </code>
*
* @param string $name
* @param mixed $value
* @param array $attributes
@@ -285,6 +342,11 @@ class Form {
/**
* Create a HTML select element.
*
* <code>
* // Generate a drop-down with the "S" item selected
* echo Form::select('sizes', array('L' => 'Large', 'S' => 'Small'), 'S');
* </code>
*
* @param string $name
* @param array $options
* @param string $selected

View File

@@ -1,45 +0,0 @@
<?php namespace Laravel;
class Hash {
/**
* Hash a string using PHPass.
*
* PHPass provides reliable bcrypt hashing, and is used by many popular PHP
* applications such as Wordpress and Joomla.
*
* @access public
* @param string $value
* @return string
*/
public static function make($value, $rounds = 10)
{
return static::hasher($rounds)->HashPassword($value);
}
/**
* Determine if an unhashed value matches a given hash.
*
* @param string $value
* @param string $hash
* @return bool
*/
public static function check($value, $hash)
{
return static::hasher()->CheckPassword($value, $hash);
}
/**
* Create a new PHPass instance.
*
* @param int $rounds
* @return PasswordHash
*/
private static function hasher($rounds = 10)
{
require_once SYS_PATH.'vendor/phpass'.EXT;
return new \PasswordHash($rounds, false);
}
}

View File

@@ -1,4 +1,4 @@
<?php
<?php namespace Laravel\Hash;
#
# Portable PHP password hashing framework.
#
@@ -24,13 +24,13 @@
# Obviously, since this code is in the public domain, the above are not
# requirements (there can be none), but merely suggestions.
#
class PasswordHash {
var $itoa64;
var $iteration_count_log2;
var $portable_hashes;
var $random_state;
class BCrypt implements Engine {
private $itoa64;
private $iteration_count_log2;
private $portable_hashes;
private $random_state;
function PasswordHash($iteration_count_log2, $portable_hashes)
public function __construct($iteration_count_log2, $portable_hashes)
{
$this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
@@ -45,7 +45,7 @@ class PasswordHash {
$this->random_state .= getmypid();
}
function get_random_bytes($count)
private function get_random_bytes($count)
{
$output = '';
if (is_readable('/dev/urandom') &&
@@ -68,7 +68,7 @@ class PasswordHash {
return $output;
}
function encode64($input, $count)
private function encode64($input, $count)
{
$output = '';
$i = 0;
@@ -91,7 +91,7 @@ class PasswordHash {
return $output;
}
function gensalt_private($input)
private function gensalt_private($input)
{
$output = '$P$';
$output .= $this->itoa64[min($this->iteration_count_log2 +
@@ -101,7 +101,7 @@ class PasswordHash {
return $output;
}
function crypt_private($password, $setting)
private function crypt_private($password, $setting)
{
$output = '*0';
if (substr($setting, 0, 2) == $output)
@@ -146,7 +146,7 @@ class PasswordHash {
return $output;
}
function gensalt_extended($input)
private function gensalt_extended($input)
{
$count_log2 = min($this->iteration_count_log2 + 8, 24);
# This should be odd to not reveal weak DES keys, and the
@@ -164,7 +164,7 @@ class PasswordHash {
return $output;
}
function gensalt_blowfish($input)
private function gensalt_blowfish($input)
{
# This one needs to use a different order of characters and a
# different encoding scheme from the one in encode64() above.
@@ -205,7 +205,7 @@ class PasswordHash {
return $output;
}
function HashPassword($password)
public function hash($password)
{
$random = '';
@@ -240,7 +240,7 @@ class PasswordHash {
return '*';
}
function CheckPassword($password, $stored_hash)
public function check($password, $stored_hash)
{
$hash = $this->crypt_private($password, $stored_hash);
if ($hash[0] == '*')

22
laravel/hash/engine.php Normal file
View File

@@ -0,0 +1,22 @@
<?php namespace Laravel\Hash;
interface Engine {
/**
* Perform a one-way hash on a string.
*
* @param string $value
* @return string
*/
public function hash($value);
/**
* Determine if an unhashed value matches a given hash.
*
* @param string $value
* @param string $hash
* @return bool
*/
public function check($value, $hash);
}

67
laravel/hasher.php Normal file
View File

@@ -0,0 +1,67 @@
<?php namespace Laravel;
class Hasher {
/**
* The hashing engine being used to perform the hashing.
*
* @var Hash\Engine
*/
public $engine;
/**
* Create a new Hasher instance.
*
* If no hashing engine is provided, the BCrypt engine will be used.
*
* @param Hash\Engine $engine
* @return void
*/
public function __construct(Hash\Engine $engine = null)
{
$this->engine = (is_null($engine)) ? new Hash\BCrypt(10, false) : $engine;
}
/**
* Create a new Hasher instance.
*
* If no hashing engine is provided, the BCrypt engine will be used.
*
* @param Hash\Engine $engine
* @return Hasher
*/
public static function make(Hash\Engine $engine = null)
{
return new static($engine);
}
/**
* Magic Method for delegating method calls to the hashing engine.
*
* <code>
* // Use the hashing engine to has a value
* $hash = Hasher::make()->hash('password');
*
* // Equivalent method using the engine property
* $hash = Hasher::make()->engine->hash('password');
* </code>
*/
public function __call($method, $parameters)
{
return call_user_func_array(array($this->engine, $method), $parameters);
}
/**
* Magic Method for performing methods on the default hashing engine.
*
* <code>
* // Hash a value using the default hashing engine
* $hash = Hasher::hash('password');
* </code>
*/
public static function __callStatic($method, $parameters)
{
return call_user_func_array(array(static::make()->engine, $method), $parameters);
}
}

View File

@@ -5,6 +5,8 @@ class HTML {
/**
* Convert HTML characters to entities.
*
* The encoding specified in the application configuration file will be used.
*
* @param string $value
* @return string
*/
@@ -36,7 +38,7 @@ class HTML {
{
if ( ! array_key_exists('media', $attributes)) $attributes['media'] = 'all';
$attributes = $attributes + array('rel' => 'stylesheet', 'type' => 'text/css');
$attributes = array_merge($attributes, array('rel' => 'stylesheet', 'type' => 'text/css'));
return '<link href="'.static::entities(URL::to_asset($url)).'"'.static::attributes($attributes).'>'.PHP_EOL;
}
@@ -110,6 +112,16 @@ class HTML {
/**
* Generate an HTML link to a route.
*
* An array of parameters may be specified to fill in URI segment wildcards.
*
* <code>
* // Link to the "login" route
* echo HTML::link_to_route('login', 'Login');
*
* // Link to the "profile" route, which has a URI of "/profile/(:any)"
* echo HTML::link_to_route('profile', 'Profile', array('taylor'));
* </code>
*
* @param string $name
* @param string $title
* @param array $parameters
@@ -138,6 +150,8 @@ class HTML {
/**
* Generate an HTML mailto link.
*
* The E-Mail address will be obfuscated to protect it from spam bots.
*
* @param string $email
* @param string $title
* @param array $attributes
@@ -282,6 +296,16 @@ class HTML {
/**
* Magic Method for handling dynamic static methods.
*
* This method primarily handles dynamic calls to create links to named routes.
*
* <code>
* // Link to the "login" route
* echo HTML::link_to_login('Login');
*
* // Link to the "profile" route, which has a URI of "/profile/(:any)"
* echo HTML::link_to_profile('Profile', array('taylor'));
* </code>
*/
public static function __callStatic($method, $parameters)
{

View File

@@ -114,85 +114,15 @@ class Inflector {
);
/**
* Convert a word to its plural form.
* Get the plural form of a word if the specified count is greater than one.
*
* @param string $value
* @return string
*/
public static function plural($value)
{
if (array_key_exists($value, static::$plural_cache))
{
return static::$plural_cache[$value];
}
if (in_array(strtolower($value), static::$uncountable))
{
return static::$plural_cache[$value] = $value;
}
foreach (static::$irregular as $pattern => $irregular)
{
$pattern = '/'.$pattern.'$/i';
if (preg_match($pattern, $value))
{
return static::$plural_cache[$value] = preg_replace($pattern, $irregular, $value);
}
}
foreach (static::$plural as $pattern => $plural)
{
if (preg_match($pattern, $value))
{
return static::$plural_cache[$value] = preg_replace($pattern, $plural, $value);
}
}
return static::$plural_cache[$value] = $value;
}
/**
* Convert a word to its singular form.
* <code>
* // Returns "friend"
* Inflector::plural_if('friend', 1);
*
* @param string $value
* @return string
*/
public static function singular($value)
{
if (array_key_exists($value, static::$singular_cache))
{
return static::$singular_cache[$value];
}
if (in_array(strtolower($value), static::$uncountable))
{
return static::$singular_cache[$value] = $value;
}
foreach (static::$irregular as $irregular => $pattern)
{
$pattern = '/'.$pattern.'$/i';
if (preg_match($pattern, $value))
{
return static::$singular_cache[$value] = preg_replace($pattern, $irregular, $value);
}
}
foreach (static::$singular as $pattern => $singular)
{
if (preg_match($pattern, $value))
{
return static::$singular_cache[$value] = preg_replace($pattern, $singular, $value);
}
}
return static::$singular_cache[$value] = $value;
}
/**
* Get the plural form of a word if the count is greater than zero.
* // Returns "friends"
* Inflector::plural_if('friend', 2);
* </code>
*
* @param string $value
* @param int $count
@@ -203,4 +133,66 @@ class Inflector {
return ($count > 1) ? static::plural($value) : $value;
}
/**
* Convert a word to its plural form.
*
* @param string $value
* @return string
*/
public static function plural($value)
{
return static::$plural_cache[$value] = static::inflect($value, static::$plural_cache, array_flip(static::$irregular), static::$plural);
}
/**
* Convert a word to its singular form.
*
* @param string $value
* @return string
*/
public static function singular($value)
{
return static::$singular_cache[$value] = static::inflect($value, static::$singular_cache, static::$irregular, static::$singular);
}
/**
* Convert a word to its singular or plural form.
*
* @param string $value
* @param array $cache
* @param array $irregular
* @param array $source
* @return string
*/
private static function inflect($value, $cache, $irregular, $source)
{
if (array_key_exists($value, $cache))
{
return $cache[$value];
}
if (in_array(strtolower($value), static::$uncountable))
{
return $value;
}
foreach ($irregular as $irregular => $pattern)
{
if (preg_match($pattern = '/'.$pattern.'$/i', $value))
{
return preg_replace($pattern, $irregular, $value);
}
}
foreach ($source as $pattern => $inflected)
{
if (preg_match($pattern, $value))
{
return preg_replace($pattern, $inflected, $value);
}
}
return $value;
}
}

View File

@@ -3,22 +3,92 @@
class Input {
/**
* The input data for the request.
* The applicable input for the request.
*
* @var array
*/
public static $input;
public $input;
/**
* The $_GET array for the request.
*
* @var array
*/
public $get;
/**
* The $_POST array for the request.
*
* @var array
*/
public $post;
/**
* The $_COOKIE array for the request.
*
* @var array
*/
public $cookies;
/**
* The $_FILES array for the request.
*
* @var array
*/
public $files;
/**
* Create a new Input instance.
*
* @param Request $request
* @param array $get
* @param array $post
* @param array $cookies
* @param array $files
*/
public function __construct(Request $request, $get, $post, $cookies, $files)
{
$this->get = $get;
$this->post = $post;
$this->files = $files;
$this->cookies = $cookies;
$this->hydrate($request->method(), $request->is_spoofed());
}
/**
* Hydrate the input for a given request.
*
* @param string $method
* @param bool $spoofed
* @return void
*/
private function hydrate($method, $spoofed)
{
if ($method == 'GET')
{
$this->input = $this->get;
}
elseif ($method == 'POST')
{
$this->input = $this->post;
}
elseif ($method == 'PUT' or $method == 'DELETE')
{
($spoofed) ? $this->input = $this->post : parse_str(file_get_contents('php://input'), $this->input);
}
}
/**
* Get all of the input data for the request.
*
* This method returns a merged array containing Input::get and Input::file.
* This method returns a merged array containing $input->get() and $input->files().
*
* @return array
*/
public static function all()
public function all()
{
return array_merge(static::get(), static::file());
return array_merge($this->get(), $this->file());
}
/**
@@ -27,9 +97,9 @@ class Input {
* @param string $key
* @return bool
*/
public static function has($key)
public function has($key)
{
return ( ! is_null(static::get($key)) and trim((string) static::get($key)) !== '');
return ( ! is_null($this->get($key)) and trim((string) $this->get($key)) !== '');
}
/**
@@ -39,11 +109,9 @@ class Input {
* @param mixed $default
* @return string
*/
public static function get($key = null, $default = null)
public function get($key = null, $default = null)
{
if (is_null(static::$input)) static::hydrate();
return Arr::get(static::$input, $key, $default);
return Arr::get($this->input, $key, $default);
}
/**
@@ -52,26 +120,24 @@ class Input {
* @param string $key
* @return bool
*/
public static function had($key)
public function had($key)
{
return ( ! is_null(static::old($key)) and trim((string) static::old($key)) !== '');
return ( ! is_null($this->old($key)) and trim((string) $this->old($key)) !== '');
}
/**
* Get input data from the previous request.
*
* @param string $key
* @param mixed $default
* @param string $key
* @param mixed $default
* @param Session\Driver $driver
* @return string
*/
public static function old($key = null, $default = null)
public function old($key = null, $default = null, Session\Driver $driver = null)
{
if (Config::get('session.driver') == '')
{
throw new \Exception("Sessions must be enabled to retrieve old input data.");
}
if (is_null($driver)) $driver = Session::driver();
return Arr::get(Session::get('laravel_old_input', array()), $key, $default);
return Arr::get($driver->get('laravel_old_input', array()), $key, $default);
}
/**
@@ -81,9 +147,9 @@ class Input {
* @param mixed $default
* @return array
*/
public static function file($key = null, $default = null)
public function file($key = null, $default = null)
{
return Arr::get($_FILES, $key, $default);
return Arr::get($this->files, $key, $default);
}
/**
@@ -93,39 +159,17 @@ class Input {
* @param string $path
* @return bool
*/
public static function upload($key, $path)
public function upload($key, $path)
{
return array_key_exists($key, $_FILES) ? move_uploaded_file($_FILES[$key]['tmp_name'], $path) : false;
return array_key_exists($key, $this->files) ? move_uploaded_file($this->files[$key]['tmp_name'], $path) : false;
}
/**
* Hydrate the input data for the request.
*
* @return void
* Magic Method for retrieving items from the request input.
*/
public static function hydrate()
public function __get($key)
{
switch (Request::method())
{
case 'GET':
static::$input =& $_GET;
break;
case 'POST':
static::$input =& $_POST;
break;
case 'PUT':
case 'DELETE':
if (Request::spoofed())
{
static::$input =& $_POST;
}
else
{
parse_str(file_get_contents('php://input'), static::$input);
}
}
return $this->get($key);
}
}

View File

@@ -8,6 +8,7 @@ define('EXT', '.php');
// --------------------------------------------------------------
// Define the core framework paths.
// --------------------------------------------------------------
define('APP_PATH', realpath($application).'/');
define('BASE_PATH', realpath(str_replace('laravel', '', $laravel)).'/');
define('MODULE_PATH', realpath($modules).'/');
define('PACKAGE_PATH', realpath($packages).'/');
@@ -15,19 +16,26 @@ define('PUBLIC_PATH', realpath($public).'/');
define('STORAGE_PATH', realpath($storage).'/');
define('SYS_PATH', realpath($laravel).'/');
unset($laravel, $config, $modules, $packages, $public, $storage);
unset($laravel, $application, $config, $modules, $packages, $public, $storage);
// --------------------------------------------------------------
// Define various other framework paths.
// --------------------------------------------------------------
define('CACHE_PATH', STORAGE_PATH.'cache/');
define('CONFIG_PATH', SYS_PATH.'config/');
define('CONFIG_PATH', APP_PATH.'config/');
define('DATABASE_PATH', STORAGE_PATH.'db/');
define('LANG_PATH', SYS_PATH.'lang/');
define('SCRIPT_PATH', PUBLIC_PATH.'js/');
define('SESSION_PATH', STORAGE_PATH.'sessions/');
define('STYLE_PATH', PUBLIC_PATH.'css/');
// --------------------------------------------------------------
// Define the default module and path.
// --------------------------------------------------------------
define('DEFAULT_MODULE', 'application');
define('DEFAULT_MODULE_PATH', APP_PATH);
// --------------------------------------------------------------
// Load the classes used by the auto-loader.
// --------------------------------------------------------------
@@ -36,33 +44,28 @@ require SYS_PATH.'config'.EXT;
require SYS_PATH.'module'.EXT;
require SYS_PATH.'arr'.EXT;
// --------------------------------------------------------------
// Define the default module.
// --------------------------------------------------------------
define('DEFAULT_MODULE', 'application');
// --------------------------------------------------------------
// Register the active modules.
// --------------------------------------------------------------
Module::$modules = array_merge(array('application'), $active);
Module::$modules = array_merge(array(DEFAULT_MODULE => DEFAULT_MODULE_PATH), $active);
unset($active);
// --------------------------------------------------------------
// Define the default module path.
// --------------------------------------------------------------
define('DEFAULT_MODULE_PATH', Module::path(DEFAULT_MODULE));
// --------------------------------------------------------------
// Register the auto-loader.
// --------------------------------------------------------------
Loader::bootstrap(array(
Module::path(DEFAULT_MODULE).'libraries/',
Module::path(DEFAULT_MODULE).'models/',
APP_PATH.'libraries/',
APP_PATH.'models/',
));
spl_autoload_register(array('Laravel\\Loader', 'load'));
// --------------------------------------------------------------
// Set the default timezone.
// --------------------------------------------------------------
date_default_timezone_set(Config::get('application.timezone'));
// --------------------------------------------------------------
// Set the error reporting and display levels.
// --------------------------------------------------------------
@@ -71,9 +74,26 @@ error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 'Off');
// --------------------------------------------------------------
// Set the default timezone.
// Initialize the request instance for the request.
// --------------------------------------------------------------
date_default_timezone_set(Config::get('application.timezone'));
$request = new Request($_SERVER);
// --------------------------------------------------------------
// Hydrate the input for the current request.
// --------------------------------------------------------------
$request->input = new Input($request, $_GET, $_POST, $_COOKIE, $_FILES);
// --------------------------------------------------------------
// Determine the module that should handle the request.
// --------------------------------------------------------------
$segments = explode('/', $request->uri());
define('ACTIVE_MODULE', (array_key_exists($segments[0], Module::$modules)) ? $segments[0] : DEFAULT_MODULE);
// --------------------------------------------------------------
// Determine the path to the root of the active module.
// --------------------------------------------------------------
define('ACTIVE_MODULE_PATH', Module::path(ACTIVE_MODULE));
// --------------------------------------------------------------
// Register the error / exception handlers.
@@ -111,20 +131,6 @@ register_shutdown_function(function() use ($error_dependencies)
}
});
// --------------------------------------------------------------
// Determine the module that should handle the request.
// --------------------------------------------------------------
require SYS_PATH.'request'.EXT;
$segments = explode('/', Request::uri());
define('ACTIVE_MODULE', (array_key_exists($segments[0], Module::$modules)) ? $segments[0] : DEFAULT_MODULE);
// --------------------------------------------------------------
// Determine the path to the root of the active module.
// --------------------------------------------------------------
define('ACTIVE_MODULE_PATH', Module::path(ACTIVE_MODULE));
// --------------------------------------------------------------
// Load the session.
// --------------------------------------------------------------
@@ -167,7 +173,7 @@ if (file_exists(ACTIVE_MODULE_PATH.'filters'.EXT))
// --------------------------------------------------------------
foreach (array('before', ACTIVE_MODULE.'::before') as $filter)
{
$response = Routing\Filter::call($filter, array(Request::method(), Request::uri()), true);
$response = Routing\Filter::call($filter, array($request->method(), $request->uri()), true);
if ( ! is_null($response)) break;
}
@@ -179,7 +185,7 @@ if (is_null($response))
{
$loader = new Routing\Loader(ACTIVE_MODULE_PATH);
$route = Routing\Router::make(Request::method(), Request::uri(), $loader)->route();
$route = Routing\Router::make($request, $loader)->route();
$response = (is_null($route)) ? Response::error('404') : $route->call();
}
@@ -191,13 +197,13 @@ $response = Response::prepare($response);
// --------------------------------------------------------------
foreach (array(ACTIVE_MODULE.'::after', 'after') as $filter)
{
Routing\Filter::call($filter, array($response, Request::method(), Request::uri()));
Routing\Filter::call($filter, array($response, $request->method(), $request->uri()));
}
// --------------------------------------------------------------
// Stringify the response.
// --------------------------------------------------------------
$response->content = (string) $response->content;
$response->content = ($response->content instanceof View) ? $response->content->get() : (string) $response->content;
// --------------------------------------------------------------
// Close the session.
@@ -206,7 +212,7 @@ if (Config::get('session.driver') != '')
{
$driver = Session::driver();
$driver->flash('laravel_old_input', Input::get());
$driver->flash('laravel_old_input', $request->input->get());
$driver->close();

View File

@@ -61,14 +61,18 @@ class Module {
{
if (array_key_exists($module, static::$paths)) return static::$paths[$module];
if (in_array($module, static::$modules))
if (array_key_exists($module, static::$modules))
{
return (static::$modules[$module] == DEFAULT_MODULE_PATH) ? static::$modules[$module] : MODULE_PATH.static::$modules[$module].'/';
}
elseif (in_array($module, static::$modules))
{
return static::$paths[$module] = MODULE_PATH.$module.'/';
}
}
/**
* Get the an array of paths to all of the modules.
* Get an array of paths to all of the modules.
*
* @return array
*/

View File

@@ -2,93 +2,128 @@
class Request {
/**
* The request instance for the current request.
*
* @var Request
*/
private static $active;
/**
* The $_SERVER array for the request.
*
* @var array
*/
private $server;
/**
* The input instance for the request.
*
* @var Input
*/
public $input;
/**
* The route handling the current request.
*
* @var Route
* @var Routing\Route
*/
public static $route;
public $route;
/**
* The request URI.
*
* @var string
*/
public static $uri;
private $uri;
/**
* Get the request URI.
* Create a new request instance.
*
* If the request is to the root of application, a single forward slash will be returned.
*
* @return string
* @param array $server
* @return void
*/
public static function uri()
public function __construct($server)
{
if ( ! is_null(static::$uri)) return static::$uri;
$this->server = $server;
$uri = static::raw_uri();
if (strpos($uri, $base = parse_url(Config::get('application.url'), PHP_URL_PATH)) === 0)
{
$uri = substr($uri, strlen($base));
}
if (strpos($uri, $index = '/index.php') === 0)
{
$uri = substr($uri, strlen($index));
}
return static::$uri = (($uri = trim($uri, '/')) == '') ? '/' : $uri;
static::$active = $this;
}
/**
* Get the raw request URI from the $_SERVER array.
* Get the request instance for the current request.
*
* @return Request
*/
public static function active()
{
return static::$active;
}
/**
* Get the raw request URI.
*
* @return string
*/
private static function raw_uri()
public function uri()
{
if (isset($_SERVER['PATH_INFO']))
if ( ! is_null($this->uri)) return $this->uri;
if (isset($this->server['PATH_INFO']))
{
$uri = $_SERVER['PATH_INFO'];
$uri = $this->server['PATH_INFO'];
}
elseif (isset($_SERVER['REQUEST_URI']))
elseif (isset($this->server['REQUEST_URI']))
{
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$uri = parse_url($this->server['REQUEST_URI'], PHP_URL_PATH);
}
else
{
throw new \Exception('Unable to determine the request URI.');
die('Unable to determine the request URI.');
}
if ($uri === false)
if ($uri === false) die('Malformed request URI. Request terminated.');
return $this->uri = $this->remove_from_uri($uri, array(parse_url(Config::get('application.url'), PHP_URL_PATH), '/index.php'));
}
/**
* Remove an array of values from the beginning from a URI.
*
* @param string $uri
* @param array $values
* @return string
*/
private function remove_from_uri($uri, $values)
{
foreach ($values as $value)
{
throw new \Exception("Malformed request URI. Request terminated.");
$uri = (strpos($uri, $value) === 0) ? substr($uri, strlen($value)) : $uri;
}
return $uri;
}
/**
* Get the request method.
*
* Note: If the request method is being spoofed, the spoofed method will be returned.
*
* @return string
*/
public static function method()
public function method()
{
return (static::spoofed()) ? $_POST['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD'];
return ($this->is_spoofed()) ? $_POST['REQUEST_METHOD'] : $this->server['REQUEST_METHOD'];
}
/**
* Determine if the request method is being spoofed by a hidden Form element.
*
* Hidden form elements are used to spoof PUT and DELETE requests since
* they are not supported by HTML forms.
* Hidden elements are used to spoof PUT and DELETE requests since they are not supported by HTML forms.
*
* @return bool
*/
public static function spoofed()
public function is_spoofed()
{
return is_array($_POST) and array_key_exists('REQUEST_METHOD', $_POST);
}
@@ -98,30 +133,30 @@ class Request {
*
* @return string
*/
public static function ip()
public function ip()
{
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
if (isset($this->server['HTTP_X_FORWARDED_FOR']))
{
return $_SERVER['HTTP_X_FORWARDED_FOR'];
return $this->server['HTTP_X_FORWARDED_FOR'];
}
elseif (isset($_SERVER['HTTP_CLIENT_IP']))
elseif (isset($this->server['HTTP_CLIENT_IP']))
{
return $_SERVER['HTTP_CLIENT_IP'];
return $this->server['HTTP_CLIENT_IP'];
}
elseif (isset($_SERVER['REMOTE_ADDR']))
elseif (isset($this->server['REMOTE_ADDR']))
{
return $_SERVER['REMOTE_ADDR'];
return $this->server['REMOTE_ADDR'];
}
}
/**
* Get the HTTP protocol for the request.
* Get the HTTP protocol for the request (http or https).
*
* @return string
*/
public static function protocol()
public function protocol()
{
return (isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
return (isset($this->server['HTTPS']) and $this->server['HTTPS'] !== 'off') ? 'https' : 'http';
}
/**
@@ -129,9 +164,9 @@ class Request {
*
* @return bool
*/
public static function is_secure()
public function is_secure()
{
return (static::protocol() == 'https');
return ($this->protocol() == 'https');
}
/**
@@ -139,9 +174,9 @@ class Request {
*
* @return bool
*/
public static function is_ajax()
public function is_ajax()
{
return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) and strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
return (isset($this->server['HTTP_X_REQUESTED_WITH']) and strtolower($this->server['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
}
/**
@@ -150,19 +185,32 @@ class Request {
* @param string $name
* @return bool
*/
public static function route_is($name)
public function route_is($name)
{
return (is_array(static::$route->callback) and isset(static::$route->callback['name']) and static::$route->callback['name'] === $name);
if (is_null($this->route) or ! is_array($this->route->callback) or ! isset($this->route->callback['name'])) return false;
return $this->route->callback['name'] === $name;
}
/**
* Magic Method to handle dynamic static methods.
*/
public static function __callStatic($method, $parameters)
public function __call($method, $parameters)
{
if (strpos($method, 'route_is_') === 0)
{
return static::route_is(substr($method, 9));
return $this->route_is(substr($method, 9));
}
}
/**
* Magic Method for dynamically retrieving properties of the request instance.
*/
public function __get($key)
{
if ($key === 'input')
{
return $this->input->all();
}
}

View File

@@ -9,7 +9,7 @@ class Router {
*
* @var string
*/
public $request;
public $destination;
/**
* All of the loaded routes.
@@ -18,34 +18,47 @@ class Router {
*/
public $routes;
/**
* The current request instance.
*
* @var Request
*/
private $request;
/**
* The route loader instance.
*
* @var Loader
*/
private $loader;
/**
* Create a new router for a request method and URI.
*
* @param string $method
* @param string $uri
* @param Loader $loader
* @param Request $request
* @param Loader $loader
* @return void
*/
public function __construct($method, $uri, $loader)
public function __construct(Request $request, Loader $loader)
{
$this->loader = $loader;
$this->request = $request;
// Put the request method and URI in route form. Routes begin with
// the request method and a forward slash.
$this->request = $method.' /'.trim($uri, '/');
$this->routes = $loader->load($uri);
$this->destination = $request->method().' /'.trim($request->uri(), '/');
}
/**
* Create a new router for a request method and URI.
*
* @param string $method
* @param string $uri
* @param Loader $loader
* @param Request $request
* @param Loader $loader
* @return Router
*/
public static function make($method, $uri, $loader)
public static function make(Request $request, Loader $loader)
{
return new static($method, $uri, $loader);
return new static($request, $loader);
}
/**
@@ -55,11 +68,13 @@ class Router {
*/
public function route()
{
if (is_null($this->routes)) $this->routes = $this->loader->load($this->request->uri());
// Check for a literal route match first. If we find one, there is
// no need to spin through all of the routes.
if (isset($this->routes[$this->request]))
if (isset($this->routes[$this->destination]))
{
return Request::$route = new Route($this->request, $this->routes[$this->request]);
return $this->request->route = new Route($this->destination, $this->routes[$this->destination]);
}
foreach ($this->routes as $keys => $callback)
@@ -70,9 +85,9 @@ class Router {
{
foreach (explode(', ', $keys) as $key)
{
if (preg_match('#^'.$this->translate_wildcards($key).'$#', $this->request))
if (preg_match('#^'.$this->translate_wildcards($key).'$#', $this->destination))
{
return Request::$route = new Route($keys, $callback, $this->parameters($this->request, $key));
return $this->request->route = new Route($keys, $callback, $this->parameters($this->destination, $key));
}
}
}