Commit df84e363 authored by Taylor Otwell's avatar Taylor Otwell

refactoring.

parent 1a7fd6d3
<?php
return array(
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| Here, you can specify any class aliases that you would like registered
| when Laravel loads. Aliases are lazy-loaded, so add as many as you want.
|
| Aliases make it more convenient to use namespaced classes. Instead of
| referring to the class using its full namespace, you may simply use
| the alias defined here.
|
| We have already aliased common Laravel classes to make your life easier.
|
*/
'Asset' => 'Laravel\\Asset',
'Auth' => 'Laravel\\Auth',
'Benchmark' => 'Laravel\\Benchmark',
'Cache' => 'Laravel\\Cache',
'Config' => 'Laravel\\Config',
'Cookie' => 'Laravel\\Cookie',
'Crypter' => 'Laravel\\Crypter',
'DB' => 'Laravel\\DB',
'Eloquent' => 'Laravel\\DB\\Eloquent\\Model',
'File' => 'Laravel\\File',
'Form' => 'Laravel\\Form',
'Hasher' => 'Laravel\\Hasher',
'HTML' => 'Laravel\\HTML',
'Inflector' => 'Laravel\\Inflector',
'Input' => 'Laravel\\Input',
'Lang' => 'Laravel\\Lang',
'Loader' => 'Laravel\\Loader',
'Package' => 'Laravel\\Package',
'URL' => 'Laravel\\URL',
'Redirect' => 'Laravel\\Redirect',
'Request' => 'Laravel\\Request',
'Response' => 'Laravel\\Response',
'Session' => 'Laravel\\Session',
'Str' => 'Laravel\\Str',
'Validator' => 'Laravel\\Validator',
'View' => 'Laravel\\View',
);
\ No newline at end of file
<?php
return array(
'/æ|ǽ/' => 'ae',
'/œ/' => 'oe',
'/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|А/' => 'A',
'/à|á|â|ã|ä|å|ǻ|ā|ă|ą|ǎ|ª|а/' => 'a',
'/Б/' => 'B',
'/б/' => 'b',
'/Ç|Ć|Ĉ|Ċ|Č|Ц/' => 'C',
'/ç|ć|ĉ|ċ|č|ц/' => 'c',
'/Ð|Ď|Đ|Д/' => 'D',
'/ð|ď|đ|д/' => 'd',
'/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Е|Ё|Э/' => 'E',
'/è|é|ê|ë|ē|ĕ|ė|ę|ě|е|ё|э/' => 'e',
'/Ф/' => 'F',
'/ƒ|ф/' => 'f',
'/Ĝ|Ğ|Ġ|Ģ|Г/' => 'G',
'/ĝ|ğ|ġ|ģ|г/' => 'g',
'/Ĥ|Ħ|Х/' => 'H',
'/ĥ|ħ|х/' => 'h',
'/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|И/' => 'I',
'/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|и/' => 'i',
'/Ĵ|Й/' => 'J',
'/ĵ|й/' => 'j',
'/Ķ|К/' => 'K',
'/ķ|к/' => 'k',
'/Ĺ|Ļ|Ľ|Ŀ|Ł|Л/' => 'L',
'/ĺ|ļ|ľ|ŀ|ł|л/' => 'l',
'/М/' => 'M',
'/м/' => 'm',
'/Ñ|Ń|Ņ|Ň|Н/' => 'N',
'/ñ|ń|ņ|ň|ʼn|н/' => 'n',
'/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|О/' => 'O',
'/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|о/' => 'o',
'/П/' => 'P',
'/п/' => 'p',
'/Ŕ|Ŗ|Ř|Р/' => 'R',
'/ŕ|ŗ|ř|р/' => 'r',
'/Ś|Ŝ|Ş|Š|С/' => 'S',
'/ś|ŝ|ş|š|ſ|с/' => 's',
'/Ţ|Ť|Ŧ|Т/' => 'T',
'/ţ|ť|ŧ|т/' => 't',
'/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|У/' => 'U',
'/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|у/' => 'u',
'/В/' => 'V',
'/в/' => 'v',
'/Ý|Ÿ|Ŷ|Ы/' => 'Y',
'/ý|ÿ|ŷ|ы/' => 'y',
'/Ŵ/' => 'W',
'/ŵ/' => 'w',
'/Ź|Ż|Ž|З/' => 'Z',
'/ź|ż|ž|з/' => 'z',
'/Æ|Ǽ/' => 'AE',
'/ß/'=> 'ss',
'/IJ/' => 'IJ',
'/ij/' => 'ij',
'/Œ/' => 'OE',
'/Ч/' => 'Ch',
'/ч/' => 'ch',
'/Ю/' => 'Ju',
'/ю/' => 'ju',
'/Я/' => 'Ja',
'/я/' => 'ja',
'/Ш/' => 'Sh',
'/ш/' => 'sh',
'/Щ/' => 'Shch',
'/щ/' => 'shch',
'/Ж/' => 'Zh',
'/ж/' => 'zh',
);
\ No newline at end of file
<?php
return array(
'hqx' => 'application/mac-binhex40',
'cpt' => 'application/mac-compactpro',
'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream'),
'bin' => 'application/macbinary',
'dms' => 'application/octet-stream',
'lha' => 'application/octet-stream',
'lzh' => 'application/octet-stream',
'exe' => array('application/octet-stream', 'application/x-msdownload'),
'class' => 'application/octet-stream',
'psd' => 'application/x-photoshop',
'so' => 'application/octet-stream',
'sea' => 'application/octet-stream',
'dll' => 'application/octet-stream',
'oda' => 'application/oda',
'pdf' => array('application/pdf', 'application/x-download'),
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',
'smi' => 'application/smil',
'smil' => 'application/smil',
'mif' => 'application/vnd.mif',
'xls' => array('application/excel', 'application/vnd.ms-excel', 'application/msexcel'),
'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint'),
'wbxml' => 'application/wbxml',
'wmlc' => 'application/wmlc',
'dcr' => 'application/x-director',
'dir' => 'application/x-director',
'dxr' => 'application/x-director',
'dvi' => 'application/x-dvi',
'gtar' => 'application/x-gtar',
'gz' => 'application/x-gzip',
'php' => array('application/x-httpd-php', 'text/x-php'),
'php4' => 'application/x-httpd-php',
'php3' => 'application/x-httpd-php',
'phtml' => 'application/x-httpd-php',
'phps' => 'application/x-httpd-php-source',
'js' => 'application/x-javascript',
'swf' => 'application/x-shockwave-flash',
'sit' => 'application/x-stuffit',
'tar' => 'application/x-tar',
'tgz' => array('application/x-tar', 'application/x-gzip-compressed'),
'xhtml' => 'application/xhtml+xml',
'xht' => 'application/xhtml+xml',
'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed'),
'mid' => 'audio/midi',
'midi' => 'audio/midi',
'mpga' => 'audio/mpeg',
'mp2' => 'audio/mpeg',
'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'),
'aif' => 'audio/x-aiff',
'aiff' => 'audio/x-aiff',
'aifc' => 'audio/x-aiff',
'ram' => 'audio/x-pn-realaudio',
'rm' => 'audio/x-pn-realaudio',
'rpm' => 'audio/x-pn-realaudio-plugin',
'ra' => 'audio/x-realaudio',
'rv' => 'video/vnd.rn-realvideo',
'wav' => 'audio/x-wav',
'bmp' => 'image/bmp',
'gif' => 'image/gif',
'jpeg' => array('image/jpeg', 'image/pjpeg'),
'jpg' => array('image/jpeg', 'image/pjpeg'),
'jpe' => array('image/jpeg', 'image/pjpeg'),
'png' => 'image/png',
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
'css' => 'text/css',
'html' => 'text/html',
'htm' => 'text/html',
'shtml' => 'text/html',
'txt' => 'text/plain',
'text' => 'text/plain',
'log' => array('text/plain', 'text/x-log'),
'rtx' => 'text/richtext',
'rtf' => 'text/rtf',
'xml' => 'text/xml',
'xsl' => 'text/xml',
'mpeg' => 'video/mpeg',
'mpg' => 'video/mpeg',
'mpe' => 'video/mpeg',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
'avi' => 'video/x-msvideo',
'movie' => 'video/x-sgi-movie',
'doc' => 'application/msword',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'word' => array('application/msword', 'application/octet-stream'),
'xl' => 'application/excel',
'eml' => 'message/rfc822',
'json' => array('application/json', 'text/json'),
);
\ No newline at end of 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);
}
}
\ No newline at end of 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',
......
......@@ -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 '<form'.HTML::attributes($attributes).'>'.$append.PHP_EOL;
}
/**
* 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);
}
return $html.PHP_EOL;
/**
* 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.
* 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
......
<?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);
}
}
\ No newline at end of file
<?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] == '*')
......
<?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);
}
\ No newline at end of file
<?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);
}
}
\ No newline at end of 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)
{
......
......@@ -113,6 +113,26 @@ class Inflector {
'equipment',
);
/**
* Get the plural form of a word if the specified count is greater than one.
*
* <code>
* // Returns "friend"
* Inflector::plural_if('friend', 1);
*
* // Returns "friends"
* Inflector::plural_if('friend', 2);
* </code>
*
* @param string $value
* @param int $count
* @return string
*/
public static function plural_if($value, $count)
{
return ($count > 1) ? static::plural($value) : $value;
}
/**
* Convert a word to its plural form.
*
......@@ -121,35 +141,7 @@ class Inflector {
*/
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;
return static::$plural_cache[$value] = static::inflect($value, static::$plural_cache, array_flip(static::$irregular), static::$plural);
}
/**
......@@ -160,47 +152,47 @@ class Inflector {
*/
public static function singular($value)
{
if (array_key_exists($value, static::$singular_cache))
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 static::$singular_cache[$value];
return $cache[$value];
}
if (in_array(strtolower($value), static::$uncountable))
{
return static::$singular_cache[$value] = $value;
return $value;
}
foreach (static::$irregular as $irregular => $pattern)
foreach ($irregular as $irregular => $pattern)
{
$pattern = '/'.$pattern.'$/i';
if (preg_match($pattern, $value))
if (preg_match($pattern = '/'.$pattern.'$/i', $value))
{
return static::$singular_cache[$value] = preg_replace($pattern, $irregular, $value);
return preg_replace($pattern, $irregular, $value);
}
}
foreach (static::$singular as $pattern => $singular)
foreach ($source as $pattern => $inflected)
{
if (preg_match($pattern, $value))
{
return static::$singular_cache[$value] = preg_replace($pattern, $singular, $value);
return preg_replace($pattern, $inflected, $value);
}
}
return static::$singular_cache[$value] = $value;
}
/**
* Get the plural form of a word if the count is greater than zero.
*
* @param string $value
* @param int $count
* @return string
*/
public static function plural_if($value, $count)
{
return ($count > 1) ? static::plural($value) : $value;
return $value;
}
}
\ No newline at end of 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);
}
}
\ No newline at end of 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();
......
......@@ -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
*/
......
......@@ -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.
*
* If the request is to the root of application, a single forward slash will be returned.
* Create a new request instance.
*
* @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));
}
static::$active = $this;
}
return static::$uri = (($uri = trim($uri, '/')) == '') ? '/' : $uri;
/**
* Get the request instance for the current request.
*
* @return Request
*/
public static function active()
{
return static::$active;
}
/**
* Get the raw request URI from the $_SERVER array.
* 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();
}
}
......
......@@ -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));
}
}
}
......
......@@ -4,7 +4,7 @@
*
* @package Laravel
* @version 2.0.0
* @author Taylor Otwell
* @author Taylor Otwell <taylorotwell@gmail.com>
* @link http://laravel.com
*/
......@@ -38,15 +38,17 @@ $active = array();
|
*/
$laravel = '../laravel';
$application = '../application';
$packages = '../packages';
$laravel = '../laravel';
$modules = '../modules';
$packages = '../packages';
$storage = '../storage';
$modules = '../modules';
$public = __DIR__;
$storage = '../storage';
$public = __DIR__;
/*
|--------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment