refactoring routing and comments.
This commit is contained in:
parent
a44ca9d53b
commit
a6eaa06981
|
@ -117,6 +117,8 @@ public static function first($array, $callback, $default = null)
|
|||
*/
|
||||
public static function without($array, $without = array())
|
||||
{
|
||||
$without = (array) $without;
|
||||
|
||||
foreach ((array) $array as $key => $value)
|
||||
{
|
||||
if (in_array($value, $without)) unset($array[$key]);
|
||||
|
|
|
@ -57,8 +57,8 @@ abstract protected function retrieve($key);
|
|||
abstract public function put($key, $value, $minutes);
|
||||
|
||||
/**
|
||||
* Get an item from the cache. If the item doesn't exist in the cache, store
|
||||
* the default value in the cache and return it.
|
||||
* Get an item from the cache. If the item doesn't exist in the
|
||||
* cache, store the default value in the cache and return it.
|
||||
*
|
||||
* <code>
|
||||
* // Get an item from the cache, or cache a value for 15 minutes if it doesn't exist
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?php namespace Laravel\Cache\Drivers; use Laravel\Config, Memcache;
|
||||
<?php namespace Laravel\Cache\Drivers; use Memcache, Laravel\Config;
|
||||
|
||||
class Memcached extends Driver {
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ class Manager {
|
|||
/**
|
||||
* Get a cache driver instance.
|
||||
*
|
||||
* If no driver name is specified, the default cache driver will be returned
|
||||
* as defined in the cache configuration file.
|
||||
* If no driver name is specified, the default cache driver will be
|
||||
* returned as defined in the cache configuration file.
|
||||
*
|
||||
* <code>
|
||||
* // Get the default cache driver instance
|
||||
|
@ -46,8 +46,8 @@ public static function driver($driver = null)
|
|||
/**
|
||||
* Pass all other methods to the default cache driver.
|
||||
*
|
||||
* Passing method calls to the driver instance provides a convenient API for the developer
|
||||
* when always using the default cache driver.
|
||||
* Passing method calls to the driver instance provides a convenient API
|
||||
* for the developer when always using the default cache driver.
|
||||
*
|
||||
* <code>
|
||||
* // Call the "get" method on the default driver
|
||||
|
|
|
@ -339,12 +339,12 @@ public function has_and_belongs_to_many($model, $table = null, $foreign_key = nu
|
|||
|
||||
$this->relating_table = (is_null($table)) ? $this->intermediate_table($model) : $table;
|
||||
|
||||
// Allowing the overriding of the foreign and associated keys provides the flexibility for
|
||||
// self-referential many-to-many relationships, such as a "buddy list".
|
||||
// Allowing the overriding of the foreign and associated keys provides
|
||||
// the flexibility for self-referential many-to-many relationships.
|
||||
$this->relating_key = (is_null($foreign_key)) ? strtolower(static::model_name($this)).'_id' : $foreign_key;
|
||||
|
||||
// The associated key is the foreign key name of the related model. So, if the related model
|
||||
// is "Role", the associated key on the intermediate table would be "role_id".
|
||||
// The associated key is the foreign key name of the related model.
|
||||
// If the related model is "Role", the key would be "role_id".
|
||||
$associated_key = (is_null($associated_key)) ? strtolower(static::model_name($model)).'_id' : $associated_key;
|
||||
|
||||
return static::query($model)
|
||||
|
|
|
@ -262,20 +262,18 @@ protected function offset(Query $query)
|
|||
*/
|
||||
public function insert(Query $query, $values)
|
||||
{
|
||||
// Force every insert to be treated like a batch insert.
|
||||
// This simply makes creating the SQL syntax a little
|
||||
// easier on us since we can always treat the values
|
||||
// as if is an array containing multiple inserts.
|
||||
// Force every insert to be treated like a batch insert. This simple makes
|
||||
// creating the SQL syntax a little easier on us since we can always treat
|
||||
// the values as if it is an array containing multiple inserts.
|
||||
if ( ! is_array(reset($values))) $values = array($values);
|
||||
|
||||
// Since we only care about the column names, we can pass
|
||||
// any of the insert arrays into the "columnize" method.
|
||||
// The names should be the same for every insert.
|
||||
// Since we only care about the column names, we can pass any of the insert
|
||||
// arrays into the "columnize" method. The names should be the same for
|
||||
// every insert to the table.
|
||||
$columns = $this->columnize(array_keys(reset($values)));
|
||||
|
||||
// We need to create a string of comma-delimited insert
|
||||
// segments. Each segment contains PDO place-holders for
|
||||
// each value being inserted into the table.
|
||||
// We need to create a string of comma-delimited insert segments. Each segment
|
||||
// contains PDO place-holders for each value being inserted into the table.
|
||||
$parameters = implode(', ', array_fill(0, count($values), '('.$this->parameterize(reset($values)).')'));
|
||||
|
||||
return 'INSERT INTO '.$this->wrap($query->from).' ('.$columns.') VALUES '.$parameters;
|
||||
|
@ -314,9 +312,9 @@ public function delete(Query $query)
|
|||
}
|
||||
|
||||
/**
|
||||
* The following functions primarily serve as utility functions
|
||||
* for the grammar. They perform tasks such as wrapping values
|
||||
* in keyword identifiers or creating variable lists of bindings.
|
||||
* The following functions primarily serve as utility functions for
|
||||
* the grammar. They perform tasks such as wrapping values in keyword
|
||||
* identifiers or creating variable lists of bindings.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -385,7 +383,7 @@ public function parameterize($values)
|
|||
* Get the appropriate query parameter string for a value.
|
||||
*
|
||||
* If the value is an expression, the raw expression string should
|
||||
* will be returned, otherwise, the parameter place-holder will be
|
||||
* be returned, otherwise, the parameter place-holder will be
|
||||
* returned by the method.
|
||||
*
|
||||
* @param mixed $value
|
||||
|
|
|
@ -24,8 +24,8 @@ class Query {
|
|||
public $selects;
|
||||
|
||||
/**
|
||||
* If the query is performing an aggregate function, this will contain the column
|
||||
* and and function to use when aggregating.
|
||||
* If the query is performing an aggregate function, this will contain
|
||||
* the column and and function to use when aggregating.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
|
@ -250,9 +250,6 @@ public function or_where_id($value)
|
|||
*/
|
||||
public function where_in($column, $values, $connector = 'AND', $not = false)
|
||||
{
|
||||
// The type set in this method will be used by the query grammar to call the
|
||||
// appropriate compiler function for the where clause. For cleanliness, the
|
||||
// compiler for "not in" and "in" statements is broken into two functions.
|
||||
$type = ($not) ? 'where_not_in' : 'where_in';
|
||||
|
||||
$this->wheres[] = compact('type', 'column', 'values', 'connector');
|
||||
|
@ -309,9 +306,6 @@ public function or_where_not_in($column, $values)
|
|||
*/
|
||||
public function where_null($column, $connector = 'AND', $not = false)
|
||||
{
|
||||
// The type set in this method will be used by the query grammar to call the
|
||||
// appropriate compiler function for the where clause. For cleanliness, the
|
||||
// compiler for "not null" and "null" statements is broken into two functions.
|
||||
$type = ($not) ? 'where_not_null' : 'where_null';
|
||||
|
||||
$this->wheres[] = compact('type', 'column', 'connector');
|
||||
|
@ -371,11 +365,13 @@ private function dynamic_where($method, $parameters)
|
|||
// Split the column names from the connectors.
|
||||
$segments = preg_split('/(_and_|_or_)/i', $finder, -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
// The connector variable will determine which connector will be used for the condition.
|
||||
// We'll change it as we come across new connectors in the dynamic method string.
|
||||
// The connector variable will determine which connector will be
|
||||
// used for the condition. We'll change it as we come across new
|
||||
// connectors in the dynamic method string.
|
||||
//
|
||||
// The index variable helps us get the correct parameter value for the where condition.
|
||||
// We increment it each time we add a condition.
|
||||
// The index variable helps us get the correct parameter value
|
||||
// for the where condition. We increment it each time we add
|
||||
// a condition to the query.
|
||||
$connector = 'AND';
|
||||
|
||||
$index = 0;
|
||||
|
@ -501,8 +497,9 @@ public function get($columns = array('*'))
|
|||
|
||||
$results = $this->connection->query($this->grammar->select($this), $this->bindings);
|
||||
|
||||
// Reset the SELECT clause so more queries can be performed using the same instance.
|
||||
// This is helpful for getting aggregates and then getting actual results.
|
||||
// Reset the SELECT clause so more queries can be performed using
|
||||
// the same instance. This is helpful for getting aggregates and
|
||||
// then getting actual results.
|
||||
$this->selects = null;
|
||||
|
||||
return $results;
|
||||
|
@ -521,8 +518,9 @@ private function aggregate($aggregator, $column)
|
|||
|
||||
$result = $this->connection->only($this->grammar->select($this), $this->bindings);
|
||||
|
||||
// Reset the aggregate so more queries can be performed using the same instance.
|
||||
// This is helpful for getting aggregates and then getting actual results.
|
||||
// Reset the aggregate so more queries can be performed using
|
||||
// the same instance. This is helpful for getting aggregates
|
||||
// and then getting actual results.
|
||||
$this->aggregate = null;
|
||||
|
||||
return $result;
|
||||
|
@ -537,8 +535,9 @@ private function aggregate($aggregator, $column)
|
|||
*/
|
||||
public function paginate($per_page = 20, $columns = array('*'))
|
||||
{
|
||||
// Calculate the current page for the request. The page number will be validated
|
||||
// and adjusted by the Paginator class, so we can assume it is valid.
|
||||
// Calculate the current page for the request. The page number
|
||||
// will be validated and adjusted by the Paginator class,
|
||||
// so we can assume it is valid.
|
||||
$page = Paginator::page($total = $this->count(), $per_page);
|
||||
|
||||
return Paginator::make($this->for_page($page, $per_page)->get($columns), $total, $per_page);
|
||||
|
@ -552,9 +551,9 @@ public function paginate($per_page = 20, $columns = array('*'))
|
|||
*/
|
||||
public function insert($values)
|
||||
{
|
||||
// Force every insert to be treated like a batch insert. This simply makes creating
|
||||
// the binding array easier. We will simply loop through each inserted row and merge
|
||||
// the values together to get one big binding array.
|
||||
// Force every insert to be treated like a batch insert to make creating
|
||||
// the binding array simpler since we can just spin through the inserted
|
||||
// rows as if there/ was more than one every time.
|
||||
if ( ! is_array(reset($values))) $values = array($values);
|
||||
|
||||
$bindings = array();
|
||||
|
@ -568,7 +567,8 @@ public function insert($values)
|
|||
}
|
||||
|
||||
/**
|
||||
* Insert an array of values into the database table and return the value of the ID column.
|
||||
* Insert an array of values into the database table and
|
||||
* return the value of the ID column.
|
||||
*
|
||||
* @param array $values
|
||||
* @param string $sequence
|
||||
|
@ -626,7 +626,9 @@ protected function adjust($column, $amount, $operator)
|
|||
*/
|
||||
public function update($values)
|
||||
{
|
||||
return $this->connection->query($this->grammar->update($this, $values), array_merge(array_values($values), $this->bindings));
|
||||
$bindings = array_merge(array_values($values), $this->bindings);
|
||||
|
||||
return $this->connection->query($this->grammar->update($this, $values), $bindings);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -647,8 +649,8 @@ public function delete($id = null)
|
|||
/**
|
||||
* Magic Method for handling dynamic functions.
|
||||
*
|
||||
* This method handles all calls to aggregate functions as well as the construction
|
||||
* of dynamic where clauses via the "dynamic_where" method.
|
||||
* This method handles all calls to aggregate functions as well
|
||||
* as the construction of dynamic where clauses.
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
|
@ -659,7 +661,14 @@ public function __call($method, $parameters)
|
|||
|
||||
if (in_array($method, array('abs', 'count', 'min', 'max', 'avg', 'sum')))
|
||||
{
|
||||
return ($method == 'count') ? $this->aggregate(strtoupper($method), '*') : $this->aggregate(strtoupper($method), $parameters[0]);
|
||||
if ($method == 'count')
|
||||
{
|
||||
return $this->aggregate(strtoupper($method), '*');
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->aggregate(strtoupper($method), $parameters[0]);
|
||||
}
|
||||
}
|
||||
|
||||
throw new \Exception("Method [$method] is not defined on the Query class.");
|
||||
|
|
|
@ -129,7 +129,7 @@
|
|||
{
|
||||
$flash = array(Input::old_input => Input::get());
|
||||
|
||||
Session\Manager::close($driver, $transporter, $flash);
|
||||
Session\Manager::close($flash);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -59,25 +59,18 @@ public static function call($destination, $parameters)
|
|||
$response = call_user_func_array(array($controller, $method), $parameters);
|
||||
}
|
||||
|
||||
$filters = array_merge($controller->filters('after'), array('after'));
|
||||
// The after filter and the framework expects all responses to
|
||||
// be instances of the Response class. If the route did not
|
||||
// return an instsance of Response, we will make on now.
|
||||
if ( ! $response instanceof Response) $response = new Response($response);
|
||||
|
||||
$filters = array_merge($this->filters('after'), array('after'));
|
||||
|
||||
Filter::run($filters, array($response));
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine if a given controller method is callable.
|
||||
*
|
||||
* @param string $method
|
||||
* @return bool
|
||||
*/
|
||||
protected static function hidden($method)
|
||||
{
|
||||
return $method == 'before' or $method == 'after' or strncmp($method, '_', 1) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a controller name to a controller instance.
|
||||
*
|
||||
|
@ -123,6 +116,17 @@ protected static function load($controller)
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a given controller method is callable.
|
||||
*
|
||||
* @param string $method
|
||||
* @return bool
|
||||
*/
|
||||
protected static function hidden($method)
|
||||
{
|
||||
return $method == 'before' or $method == 'after' or strncmp($method, '_', 1) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of filter names defined for the destination.
|
||||
*
|
||||
|
|
|
@ -50,25 +50,28 @@ public function load($uri)
|
|||
{
|
||||
$routes = (file_exists($path = $this->base.'routes'.EXT)) ? require $path : array();
|
||||
|
||||
return array_merge($this->nested(Arr::without(explode('/', $uri), array(''))), $routes);
|
||||
$segments = Arr::without(explode('/', $uri), '');
|
||||
|
||||
return array_merge($this->nested($segments), $routes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the appropriate routes from the routes directory for a given URI.
|
||||
*
|
||||
* This method works backwards through the URI segments until we find the
|
||||
* deepest possible matching route directory. Once the deepest directory
|
||||
* is found, all of the applicable routes will be returend.
|
||||
*
|
||||
* @param array $segments
|
||||
* @return array
|
||||
*/
|
||||
protected function nested($segments)
|
||||
{
|
||||
// Work backwards through the URI segments until we find the deepest possible
|
||||
// matching route directory. Once we find it, we will return those routes.
|
||||
foreach (array_reverse($segments, true) as $key => $value)
|
||||
{
|
||||
if (file_exists($path = $this->nest.implode('/', array_slice($segments, 0, $key + 1)).EXT))
|
||||
{
|
||||
return require $path;
|
||||
}
|
||||
$path = $this->nest.implode('/', array_slice($segments, 0, $key + 1)).EXT;
|
||||
|
||||
if (file_exists($path)) return require $path;
|
||||
}
|
||||
|
||||
return array();
|
||||
|
@ -77,6 +80,10 @@ protected function nested($segments)
|
|||
/**
|
||||
* Get every route defined for the application.
|
||||
*
|
||||
* The entire routes directory will be searched recursively to gather
|
||||
* every route for the application. Of course, the routes in the root
|
||||
* routes file will be returned as well.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function everything()
|
||||
|
@ -90,8 +97,8 @@ public function everything()
|
|||
$routes = array_merge($routes, require $path);
|
||||
}
|
||||
|
||||
// Since route files can be nested deep within the route directory,
|
||||
// we need to recursively spin through each directory
|
||||
if ( ! is_dir($this->nest)) return $routes;
|
||||
|
||||
$iterator = new Iterator(new DirectoryIterator($this->nest), Iterator::SELF_FIRST);
|
||||
|
||||
foreach ($iterator as $file)
|
||||
|
|
|
@ -104,19 +104,24 @@ public function call()
|
|||
{
|
||||
if ($response instanceof Delegate)
|
||||
{
|
||||
return Controller::call($response, $this->parameters);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The after filter and the framework expects all responses to
|
||||
// be instances of the Response class. If the route did not
|
||||
// return an instsance of Response, we will make on now.
|
||||
if ( ! $response instanceof Response) $response = new Response($response);
|
||||
|
||||
$filters = array_merge($this->filters('after'), array('after'));
|
||||
|
||||
Filter::run($filters, array($response));
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
$filters = array_merge($this->filters('after'), array('after'));
|
||||
|
||||
Filter::run($filters, array($response));
|
||||
|
||||
return $response;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Response::error('404');
|
||||
}
|
||||
|
||||
return Response::error('404');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -88,13 +88,8 @@ public function __construct(Loader $loader, $controllers)
|
|||
*/
|
||||
public function find($name)
|
||||
{
|
||||
// First we will check the cache of route names. If we have already found the given route,
|
||||
// we will simply return that route from the cache to improve performance.
|
||||
if (array_key_exists($name, $this->names)) return $this->names[$name];
|
||||
|
||||
// Spin through every route defined for the application searching for a route that has
|
||||
// a name matching the name passed to the method. If the route is found, it will be
|
||||
// cached in the array of named routes and returned.
|
||||
foreach ($this->loader->everything() as $key => $value)
|
||||
{
|
||||
if (is_array($value) and isset($value['name']) and $value['name'] === $name)
|
||||
|
@ -116,11 +111,10 @@ public function route($method, $uri)
|
|||
$routes = $this->loader->load($uri);
|
||||
|
||||
// Put the request method and URI in route form. Routes begin with
|
||||
// the request method and a forward slash.
|
||||
// the request method and a forward slash followed by the URI.
|
||||
$destination = $method.' /'.trim($uri, '/');
|
||||
|
||||
// Check for a literal route match first. If we find one, there is
|
||||
// no need to spin through all of the routes.
|
||||
// Check for a literal route match first...
|
||||
if (isset($routes[$destination]))
|
||||
{
|
||||
return Request::$route = new Route($destination, $routes[$destination], array());
|
||||
|
@ -130,22 +124,42 @@ public function route($method, $uri)
|
|||
{
|
||||
// Only check routes that have multiple URIs or wildcards since other
|
||||
// routes would have been caught by the check for literal matches.
|
||||
if (strpos($keys, '(') !== false or strpos($keys, ',') !== false )
|
||||
if (strpos($keys, '(') !== false or strpos($keys, ',') !== false)
|
||||
{
|
||||
foreach (explode(', ', $keys) as $key)
|
||||
if ( ! is_null($route = $this->match($destination, $keys, $callback)))
|
||||
{
|
||||
// Append the provided formats to the route as an optional regular expression.
|
||||
if ( ! is_null($formats = $this->provides($callback))) $key .= '(\.('.implode('|', $formats).'))?';
|
||||
|
||||
if (preg_match('#^'.$this->translate_wildcards($key).'$#', $destination))
|
||||
{
|
||||
return Request::$route = new Route($keys, $callback, $this->parameters($destination, $key));
|
||||
}
|
||||
return Request::$route = $route;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Request::$route = $this->route_to_controller($method, $uri, $destination);
|
||||
return Request::$route = $this->controller($method, $uri, $destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to match a given route destination to a given route.
|
||||
*
|
||||
* The destination's methods and URIs will be compared against the route's.
|
||||
* If there is a match, the Route instance will be returned, otherwise null
|
||||
* will be returned by the method.
|
||||
*
|
||||
* @param string $destination
|
||||
* @param array $keys
|
||||
* @param mixed $callback
|
||||
* @return mixed
|
||||
*/
|
||||
protected function match($destination, $keys, $callback)
|
||||
{
|
||||
foreach (explode(', ', $keys) as $key)
|
||||
{
|
||||
// Append the provided formats to the route as an optional regular expression.
|
||||
if ( ! is_null($formats = $this->provides($callback))) $key .= '(\.('.implode('|', $formats).'))?';
|
||||
|
||||
if (preg_match('#^'.$this->wildcards($key).'$#', $destination))
|
||||
{
|
||||
return new Route($keys, $callback, $this->parameters($destination, $key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -156,10 +170,11 @@ public function route($method, $uri)
|
|||
* @param string $destination
|
||||
* @return Route
|
||||
*/
|
||||
protected function route_to_controller($method, $uri, $destination)
|
||||
protected function controller($method, $uri, $destination)
|
||||
{
|
||||
// If the request is to the root of the application, an ad-hoc route will be generated
|
||||
// to the home controller's "index" method, making it the default controller method.
|
||||
// If the request is to the root of the application, an ad-hoc route
|
||||
// will be generated to the home controller's "index" method, making
|
||||
// it the default controller method.
|
||||
if ($uri === '/') return new Route($method.' /', 'home@index');
|
||||
|
||||
$segments = explode('/', trim($uri, '/'));
|
||||
|
@ -228,7 +243,7 @@ protected function provides($callback)
|
|||
* @param string $key
|
||||
* @return string
|
||||
*/
|
||||
protected function translate_wildcards($key)
|
||||
protected function wildcards($key)
|
||||
{
|
||||
$replacements = 0;
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ public static function check()
|
|||
* Get the current user of the application.
|
||||
*
|
||||
* This method will call the "user" closure in the authentication configuration file.
|
||||
* If the user is not authenticated, null will be returned.
|
||||
* If the user is not authenticated, null will be returned by the methd.
|
||||
*
|
||||
* If no user exists in the session, the method will check for a "remember me"
|
||||
* cookie and attempt to login the user based on the value of that cookie.
|
||||
|
@ -75,6 +75,10 @@ public static function user()
|
|||
/**
|
||||
* Attempt to login a user based on a long-lived "remember me" cookie.
|
||||
*
|
||||
* We should be able to trust the cookie is valid, since all cookies
|
||||
* set by Laravel include a fingerprint hash. So, the cookie should
|
||||
* be safe to use within this method.
|
||||
*
|
||||
* @param string $cookie
|
||||
* @return mixed
|
||||
*/
|
||||
|
@ -82,14 +86,7 @@ protected static function recall($cookie)
|
|||
{
|
||||
$cookie = explode('|', Crypter::decrypt($cookie));
|
||||
|
||||
// If there are not at least two elements in the array, the decrypted value
|
||||
// is not valid and we wil just bail out of the method since the cookie may
|
||||
// have been tampered with and should not be considered trustworthy.
|
||||
if (count($cookie) < 2) return;
|
||||
|
||||
list($id, $username, $config) = array($cookie[0], $cookie[1], Config::get('auth'));
|
||||
|
||||
if ( ! is_null($user = call_user_func($config['user'], $id)) and $user->{$config['username']} === $username)
|
||||
if ( ! is_null($user = call_user_func(Config::get('auth.user'), $cookie[0])))
|
||||
{
|
||||
static::login($user);
|
||||
|
||||
|
@ -100,14 +97,12 @@ protected static function recall($cookie)
|
|||
/**
|
||||
* Attempt to log a user into the application.
|
||||
*
|
||||
* If the given credentials are valid, the user will be logged into
|
||||
* the application and their user ID will be stored in the session
|
||||
* via the "login" method.
|
||||
* If the credentials are valid, the user will be logged into the application
|
||||
* and their user ID will be stored in the session via the "login" method.
|
||||
*
|
||||
* The user may also be "remembered". When this option is set, the user
|
||||
* will be automatically logged into the application for one year via
|
||||
* an encrypted cookie containing their ID. Of course, if the user logs
|
||||
* out of the application, they will no longer be remembered.
|
||||
* The user may also be "remembered", which will keep the user logged into the
|
||||
* application for one year or until they logout. The user is rememberd via
|
||||
* an encrypted cookie.
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
|
@ -139,7 +134,7 @@ public static function login($user, $remember = false)
|
|||
{
|
||||
static::$user = $user;
|
||||
|
||||
if ($remember) static::remember($user->id, $user->{Config::get('auth.username')});
|
||||
if ($remember) static::remember($user->id);
|
||||
|
||||
Session::put(Auth::user_key, $user->id);
|
||||
}
|
||||
|
@ -148,17 +143,16 @@ public static function login($user, $remember = false)
|
|||
* Set a cookie so that users are "remembered" and don't need to login.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $username
|
||||
* @return void
|
||||
*/
|
||||
protected static function remember($id, $username)
|
||||
protected static function remember($id)
|
||||
{
|
||||
$cookie = Crypter::encrypt($id.'|'.$username.'|'.Str::random(40));
|
||||
$cookie = Crypter::encrypt($id.'|'.Str::random(40));
|
||||
|
||||
// This method assumes the "remember me" cookie should have the
|
||||
// same configuration as the session cookie. Since this cookie,
|
||||
// like the session cookie, should be kept very secure, it's
|
||||
// probably safe to assume the settings are the same.
|
||||
// This method assumes the "remember me" cookie should have the same
|
||||
// configuration as the session cookie. Since this cookie, like the
|
||||
// session cookie, should be kept very secure, it's probably safe
|
||||
// to assume the settings are the same.
|
||||
$config = Config::get('session');
|
||||
|
||||
Cookie::forever(Auth::remember_key, $cookie, $config['path'], $config['domain'], $config['secure']);
|
||||
|
@ -167,9 +161,9 @@ protected static function remember($id, $username)
|
|||
/**
|
||||
* Log the current user out of the application.
|
||||
*
|
||||
* The "logout" closure in the authenciation configuration file
|
||||
* will be called. All authentication cookies will be deleted
|
||||
* and the user ID will be removed from the session.
|
||||
* The "logout" closure in the authenciation configuration file will be
|
||||
* called. All authentication cookies will be deleted and the user ID
|
||||
* will be removed from the session.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php namespace Laravel\Security; use Laravel\Config;
|
||||
|
||||
if (trim(Config::get('application.key')) === '')
|
||||
if (trim(Config::$items['application']['key']) === '')
|
||||
{
|
||||
throw new \Exception('The encryption class may not be used without an application key.');
|
||||
}
|
||||
|
@ -24,9 +24,8 @@ class Crypter {
|
|||
/**
|
||||
* Encrypt a string using Mcrypt.
|
||||
*
|
||||
* The string will be encrypted using the cipher and mode specified
|
||||
* when the crypter instance was created, and the final result will
|
||||
* be base64 encoded.
|
||||
* The string will be encrypted using the cipher and mode specified when the
|
||||
* crypter instance was created, and the final result will be base64 encoded.
|
||||
*
|
||||
* <code>
|
||||
* // Encrypt a string using the Mcrypt PHP extension
|
||||
|
@ -55,7 +54,9 @@ public static function encrypt($value)
|
|||
|
||||
$iv = mcrypt_create_iv(static::iv_size(), $randomizer);
|
||||
|
||||
return base64_encode($iv.mcrypt_encrypt(static::$cipher, Config::get('application.key'), $value, static::$mode, $iv));
|
||||
$key = Config::$items['application']['key'];
|
||||
|
||||
return base64_encode($iv.mcrypt_encrypt(static::$cipher, $key, $value, static::$mode, $iv));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -85,7 +86,9 @@ public static function decrypt($value)
|
|||
|
||||
$value = substr($value, static::iv_size());
|
||||
|
||||
return rtrim(mcrypt_decrypt(static::$cipher, Config::get('application.key'), $value, static::$mode, $iv), "\0");
|
||||
$key = Config::$items['application']['key'];
|
||||
|
||||
return rtrim(mcrypt_decrypt(static::$cipher, $key, $value, static::$mode, $iv), "\0");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,10 +5,11 @@ class Hasher {
|
|||
/**
|
||||
* Hash a password using the Bcrypt hashing scheme.
|
||||
*
|
||||
* Bcrypt provides a future-proof hashing algorithm by allowing the number
|
||||
* of "rounds" to be increased, thus increasing the time is takes to generate
|
||||
* the hashed value. The longer is takes to generate the hash, the more
|
||||
* impractical a rainbow table attack against the hashes becomes.
|
||||
* Bcrypt provides a future-proof hashing algorithm by allowing the
|
||||
* number of "rounds" to be increased, thus increasing the time it
|
||||
* takes to generate the hashed value. The longer it takes takes
|
||||
* to generate the hash, the more impractical a rainbow table
|
||||
* attack against the hashes becomes.
|
||||
*
|
||||
* <code>
|
||||
* // Create a Bcrypt hash of a value
|
||||
|
@ -42,14 +43,14 @@ public static function check($value, $hash)
|
|||
/**
|
||||
* Get a salt for use during Bcrypt hashing.
|
||||
*
|
||||
* Bcrypt expects salts to be 22 alpha-numeric characters including
|
||||
* dots and forward slashes. OpenSSL will be used if available and
|
||||
* the Str::random method will be used if it isn't.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function salt()
|
||||
{
|
||||
// If OpenSSL is installed, we will use it to gather random bytes for generating
|
||||
// the salt value. Otherwise, we will use the Str::random method. Bcrypt expects
|
||||
// the salt to be a 22 character alpha-numeric string. The salt may also contain
|
||||
// dots, plus signs, and forward slashes.
|
||||
if (function_exists('openssl_random_pseudo_bytes'))
|
||||
{
|
||||
return substr(strtr(base64_encode(openssl_random_pseudo_bytes(16)), '+', '.'), 0 , 22);
|
||||
|
|
|
@ -29,6 +29,20 @@ class Manager {
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -40,28 +54,30 @@ public static function start(Driver $driver, Transporter $transporter)
|
|||
{
|
||||
$config = Config::$items['session'];
|
||||
|
||||
static::$session = $driver->load($transporter->get($config));
|
||||
$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(static::$session) or (time() - static::$session['last_activity']) > ($config['lifetime'] * 60))
|
||||
if (is_null($session) or (time() - $session['last_activity']) > ($config['lifetime'] * 60))
|
||||
{
|
||||
static::$exists = false;
|
||||
|
||||
static::$session = array('id' => Str::random(40), 'data' => array());
|
||||
$session = array('id' => Str::random(40), 'data' => array());
|
||||
}
|
||||
|
||||
static::$session = $session;
|
||||
|
||||
// If a CSRF token is not present in the session, we will generate one.
|
||||
// These tokens are generated per session to protect against Cross-Site
|
||||
// Request Forgery attacks on the application. It is up to the developer
|
||||
// to take advantage of them using the token methods on the Form class
|
||||
// and the "csrf" route filter.
|
||||
// Request Forgery attacks on the application.
|
||||
if ( ! static::has('csrf_token'))
|
||||
{
|
||||
static::put('csrf_token', Str::random(16));
|
||||
}
|
||||
|
||||
list(static::$driver, static::$transporter) = array($driver, $transporter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -253,12 +269,10 @@ protected static function replace($search, $replace, $keys)
|
|||
/**
|
||||
* Close the session handling for the request.
|
||||
*
|
||||
* @param Drivers\Driver $driver
|
||||
* @param Transporters\Transporter $transporter
|
||||
* @param array $flash
|
||||
* @param array $flash
|
||||
* @return void
|
||||
*/
|
||||
public static function close(Driver $driver, Transporter $transporter, $flash = array())
|
||||
public static function close($flash = array())
|
||||
{
|
||||
$config = Config::$items['session'];
|
||||
|
||||
|
@ -267,17 +281,17 @@ public static function close(Driver $driver, Transporter $transporter, $flash =
|
|||
static::flash($key, $value);
|
||||
}
|
||||
|
||||
$driver->save(static::age(), $config, static::$exists);
|
||||
static::$driver->save(static::age(), $config, static::$exists);
|
||||
|
||||
$transporter->put(static::$session['id'], $config);
|
||||
static::$transporter->put(static::$session['id'], $config);
|
||||
|
||||
// Some session drivers may implement the Sweeper interface, meaning the
|
||||
// driver must do its garbage collection manually. Alternatively, some
|
||||
// drivers such as APC and Memcached are not required to manually
|
||||
// clean up their sessions.
|
||||
if (mt_rand(1, $config['sweepage'][1]) <= $config['sweepage'][0] and $driver instanceof Drivers\Sweeper)
|
||||
if (mt_rand(1, $config['sweepage'][1]) <= $config['sweepage'][0] and static::$driver instanceof Drivers\Sweeper)
|
||||
{
|
||||
$driver->sweep(time() - ($config['lifetime'] * 60));
|
||||
static::$driver->sweep(time() - ($config['lifetime'] * 60));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -99,12 +99,17 @@ public static function length($value)
|
|||
}
|
||||
|
||||
/**
|
||||
* Limit the number of chars in a string
|
||||
* Limit the number of characters in a string.
|
||||
*
|
||||
* Word integrity is preserved, so the number of characters in the
|
||||
* truncated string will be rounded to the nearest word ending.
|
||||
*
|
||||
* <code>
|
||||
* // Limit the characters
|
||||
* echo Str::limit_chars('taylor otwell', 3);
|
||||
* results in 'tay...'
|
||||
* // Returns "Taylor..."
|
||||
* echo Str::limit('Taylor Otwell', 3);
|
||||
*
|
||||
* // Limit the number of characters and append a custom ending
|
||||
* echo Str::limit('Taylor Otwell', 3, '---');
|
||||
* </code>
|
||||
*
|
||||
* @param string $value
|
||||
|
@ -112,25 +117,24 @@ public static function length($value)
|
|||
* @param string $end
|
||||
* @return string
|
||||
*/
|
||||
public static function limit($value, $length = 100, $end = '...')
|
||||
public static function limit($value, $limit = 100, $end = '...')
|
||||
{
|
||||
if (static::length($value) <= $length) return $value;
|
||||
if (static::length($value) < $limit) return $value;
|
||||
|
||||
if (function_exists('mb_substr'))
|
||||
{
|
||||
return mb_substr($value, 0, $length, Config::get('application.encoding')).$end;
|
||||
}
|
||||
$limit = preg_replace('/\s+?(\S+)?$/', '', substr($value, 0, $limit));
|
||||
|
||||
return substr($value, 0, $length).$end;
|
||||
return (static::length($limit) == static::length($value)) ? $value : $limit.$end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit the number of words in a string
|
||||
*
|
||||
* <code>
|
||||
* // Limit the words
|
||||
* echo Str::limit_chars('This is a sentence.', 3);
|
||||
* results in 'This is a...'
|
||||
* // Returns "This is a..."
|
||||
* echo Str::words('This is a sentence.', 3);
|
||||
*
|
||||
* // Limit the number of words and append a custom ending
|
||||
* echo Str::words('This is a sentence.', 3, '---');
|
||||
* </code>
|
||||
*
|
||||
* @param string $value
|
||||
|
@ -138,13 +142,13 @@ public static function limit($value, $length = 100, $end = '...')
|
|||
* @param string $end
|
||||
* @return string
|
||||
*/
|
||||
public static function limit_words($value, $length = 100, $end = '...')
|
||||
public static function words($value, $words = 100, $end = '...')
|
||||
{
|
||||
$count = str_word_count($value,1);
|
||||
$count = str_word_count($value, 1);
|
||||
|
||||
if ($count <= $length) return $value;
|
||||
if ($count <= $words) return $value;
|
||||
|
||||
return implode(' ',array_slice($count,0,$length)).$end;
|
||||
return implode(' ', array_slice($count, 0, $words)).$end;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -93,7 +93,12 @@ public function get($key = null, $format = ':message')
|
|||
{
|
||||
if (is_null($key)) return $this->all($format);
|
||||
|
||||
return (array_key_exists($key, $this->messages)) ? $this->format($this->messages[$key], $format) : array();
|
||||
if (array_key_exists($key, $this->messages))
|
||||
{
|
||||
return $this->format($this->messages[$key], $format);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,11 +10,25 @@
|
|||
class Validator {
|
||||
|
||||
/**
|
||||
* The registered custom validators.
|
||||
* The database connection that should be used by the validator.
|
||||
*
|
||||
* @var Database\Connection
|
||||
*/
|
||||
public $connection;
|
||||
|
||||
/**
|
||||
* The array being validated.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $validators = array();
|
||||
public $attributes;
|
||||
|
||||
/**
|
||||
* The post-validation error messages.
|
||||
*
|
||||
* @var Messages
|
||||
*/
|
||||
public $errors;
|
||||
|
||||
/**
|
||||
* The validation rules.
|
||||
|
@ -37,6 +51,13 @@ class Validator {
|
|||
*/
|
||||
protected $language;
|
||||
|
||||
/**
|
||||
* The registered custom validators.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $validators = array();
|
||||
|
||||
/**
|
||||
* The size related validation rules.
|
||||
*
|
||||
|
@ -51,27 +72,6 @@ class Validator {
|
|||
*/
|
||||
protected $numeric_rules = array('numeric', 'integer');
|
||||
|
||||
/**
|
||||
* The database connection that should be used by the validator.
|
||||
*
|
||||
* @var Database\Connection
|
||||
*/
|
||||
public $connection;
|
||||
|
||||
/**
|
||||
* The array being validated.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $attributes;
|
||||
|
||||
/**
|
||||
* The post-validation error messages.
|
||||
*
|
||||
* @var Messages
|
||||
*/
|
||||
public $errors;
|
||||
|
||||
/**
|
||||
* Create a new validator instance.
|
||||
*
|
||||
|
@ -163,29 +163,50 @@ protected function check($attribute, $rule)
|
|||
throw new \Exception("Validation rule [$rule] doesn't exist.");
|
||||
}
|
||||
|
||||
// No validation will be run for attributes that do not exist unless the rule being validated
|
||||
// is "required" or "accepted". No other rules have implicit "required" checks.
|
||||
// Extract the actual value for the attribute. We don't want every rule
|
||||
// to worry about obtaining the value from the array of attributes.
|
||||
$value = (isset($this->attributes[$attribute])) ? $this->attributes[$attribute] : null;
|
||||
|
||||
// No validation will be run for attributes that do not exist unless the
|
||||
// rule being validated is "required" or "accepted". No other rules have
|
||||
// implicit "required" checks for validation.
|
||||
if ( ! $this->validate_required($attribute) and ! in_array($rule, array('required', 'accepted'))) return;
|
||||
|
||||
if ( ! $this->$validator($attribute, $parameters, $this))
|
||||
if ( ! $this->$validator($attribute, $value, $parameters, $this))
|
||||
{
|
||||
$message = $this->format_message($this->get_message($attribute, $rule), $attribute, $rule, $parameters);
|
||||
|
||||
$this->errors->add($attribute, $message, $attribute, $rule, $parameters);
|
||||
$this->error($attribute, $rule, $parameters);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an error message to the validator's collection of messages.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string $rule
|
||||
* @param array $parameters
|
||||
* @return void
|
||||
*/
|
||||
protected function error($attribute, $rule, $parameters)
|
||||
{
|
||||
$message = $this->get_message($attribute, $rule);
|
||||
|
||||
$message = $this->format_message($message, $attribute, $rule, $parameters);
|
||||
|
||||
$this->errors->add($attribute, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that a required attribute exists in the attributes array.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_required($attribute)
|
||||
protected function validate_required($attribute, $value)
|
||||
{
|
||||
if ( ! array_key_exists($attribute, $this->attributes)) return false;
|
||||
if (is_null($value)) return false;
|
||||
|
||||
if (is_string($this->attributes[$attribute]) and trim($this->attributes[$attribute]) === '') return false;
|
||||
if (is_string($value) and trim($value) === '') return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -194,12 +215,11 @@ protected function validate_required($attribute)
|
|||
* Validate that an attribute has a matching confirmation attribute.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_confirmed($attribute)
|
||||
protected function validate_confirmed($attribute, $value)
|
||||
{
|
||||
$value = $this->attributes[$attribute];
|
||||
|
||||
$confirmation = $this->attributes[$attribute.'_confirmation'];
|
||||
|
||||
return array_key_exists($attribute.'_confirmation', $this->attributes) and $value == $confirmation;
|
||||
|
@ -211,12 +231,11 @@ protected function validate_confirmed($attribute)
|
|||
* This validation rule implies the attribute is "required".
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_accepted($attribute)
|
||||
protected function validate_accepted($attribute, $value)
|
||||
{
|
||||
$value = $this->attributes[$attribute];
|
||||
|
||||
return $this->validate_required($attribute) and ($value == 'yes' or $value == '1');
|
||||
}
|
||||
|
||||
|
@ -224,32 +243,35 @@ protected function validate_accepted($attribute)
|
|||
* Validate that an attribute is numeric.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_numeric($attribute)
|
||||
protected function validate_numeric($attribute, $value)
|
||||
{
|
||||
return is_numeric($this->attributes[$attribute]);
|
||||
return is_numeric($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute is an integer.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_integer($attribute)
|
||||
protected function validate_integer($attribute, $value)
|
||||
{
|
||||
return filter_var($this->attributes[$attribute], FILTER_VALIDATE_INT) !== false;
|
||||
return filter_var($value, FILTER_VALIDATE_INT) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the size of an attribute.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @param array $parameters
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_size($attribute, $parameters)
|
||||
protected function validate_size($attribute, $value, $parameters)
|
||||
{
|
||||
return $this->get_size($attribute) == $parameters[0];
|
||||
}
|
||||
|
@ -258,10 +280,11 @@ protected function validate_size($attribute, $parameters)
|
|||
* Validate the size of an attribute is between a set of values.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @param array $parameters
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_between($attribute, $parameters)
|
||||
protected function validate_between($attribute, $value, $parameters)
|
||||
{
|
||||
return $this->get_size($attribute) >= $parameters[0] and $this->get_size($attribute) <= $parameters[1];
|
||||
}
|
||||
|
@ -270,10 +293,11 @@ protected function validate_between($attribute, $parameters)
|
|||
* Validate the size of an attribute is greater than a minimum value.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @param array $parameters
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_min($attribute, $parameters)
|
||||
protected function validate_min($attribute, $value, $parameters)
|
||||
{
|
||||
return $this->get_size($attribute) >= $parameters[0];
|
||||
}
|
||||
|
@ -282,10 +306,11 @@ protected function validate_min($attribute, $parameters)
|
|||
* Validate the size of an attribute is less than a maximum value.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @param array $parameters
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_max($attribute, $parameters)
|
||||
protected function validate_max($attribute, $value, $parameters)
|
||||
{
|
||||
return $this->get_size($attribute) <= $parameters[0];
|
||||
}
|
||||
|
@ -305,31 +330,40 @@ protected function get_size($attribute)
|
|||
|
||||
$value = $this->attributes[$attribute];
|
||||
|
||||
return (array_key_exists($attribute, Input::file())) ? $value['size'] / 1024 : Str::length(trim($value));
|
||||
if (array_key_exists($attribute, Input::file()))
|
||||
{
|
||||
return $value['size'] / 1024;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Str::length(trim($value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an attribute is contained within a list of values.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @param array $parameters
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_in($attribute, $parameters)
|
||||
protected function validate_in($attribute, $value, $parameters)
|
||||
{
|
||||
return in_array($this->attributes[$attribute], $parameters);
|
||||
return in_array($value, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an attribute is not contained within a list of values.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @param array $parameters
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_not_in($attribute, $parameters)
|
||||
protected function validate_not_in($attribute, $value, $parameters)
|
||||
{
|
||||
return ! in_array($this->attributes[$attribute], $parameters);
|
||||
return ! in_array($value, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -338,49 +372,53 @@ protected function validate_not_in($attribute, $parameters)
|
|||
* If a database column is not specified, the attribute name will be used.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @param array $parameters
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_unique($attribute, $parameters)
|
||||
protected function validate_unique($attribute, $value, $parameters)
|
||||
{
|
||||
if ( ! isset($parameters[1])) $parameters[1] = $attribute;
|
||||
|
||||
if (is_null($this->connection)) $this->connection = DB::connection();
|
||||
|
||||
return $this->connection->table($parameters[0])->where($parameters[1], '=', $this->attributes[$attribute])->count() == 0;
|
||||
return $this->connection->table($parameters[0])->where($parameters[1], '=', $value)->count() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate than an attribute is a valid e-mail address.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_email($attribute)
|
||||
protected function validate_email($attribute, $value)
|
||||
{
|
||||
return filter_var($this->attributes[$attribute], FILTER_VALIDATE_EMAIL) !== false;
|
||||
return filter_var($value, FILTER_VALIDATE_EMAIL) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate than an attribute is a valid URL.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_url($attribute)
|
||||
protected function validate_url($attribute, $value)
|
||||
{
|
||||
return filter_var($this->attributes[$attribute], FILTER_VALIDATE_URL) !== false;
|
||||
return filter_var($value, FILTER_VALIDATE_URL) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute is an active URL.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_active_url($attribute)
|
||||
protected function validate_active_url($attribute, $value)
|
||||
{
|
||||
$url = str_replace(array('http://', 'https://', 'ftp://'), '', Str::lower($this->attributes[$attribute]));
|
||||
$url = str_replace(array('http://', 'https://', 'ftp://'), '', Str::lower($value));
|
||||
|
||||
return checkdnsrr($url);
|
||||
}
|
||||
|
@ -389,9 +427,10 @@ protected function validate_active_url($attribute)
|
|||
* Validate the MIME type of a file is an image MIME type.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_image($attribute)
|
||||
protected function validate_image($attribute, $value)
|
||||
{
|
||||
return $this->validate_mimes($attribute, array('jpg', 'png', 'gif', 'bmp'));
|
||||
}
|
||||
|
@ -400,33 +439,36 @@ protected function validate_image($attribute)
|
|||
* Validate than an attribute contains only alphabetic characters.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_alpha($attribute)
|
||||
protected function validate_alpha($attribute, $value)
|
||||
{
|
||||
return preg_match('/^([a-z])+$/i', $this->attributes[$attribute]);
|
||||
return preg_match('/^([a-z])+$/i', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate than an attribute contains only alpha-numeric characters.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_alpha_num($attribute)
|
||||
protected function validate_alpha_num($attribute, $value)
|
||||
{
|
||||
return preg_match('/^([a-z0-9])+$/i', $this->attributes[$attribute]);
|
||||
return preg_match('/^([a-z0-9])+$/i', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate than an attribute contains only alpha-numeric characters, dashes, and underscores.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate_alpha_dash($attribute)
|
||||
protected function validate_alpha_dash($attribute, $value)
|
||||
{
|
||||
return preg_match('/^([-a-z0-9_-])+$/i', $this->attributes[$attribute]);
|
||||
return preg_match('/^([-a-z0-9_-])+$/i', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -549,9 +591,9 @@ protected function has_rule($attribute, $rules)
|
|||
*/
|
||||
protected function parse($rule)
|
||||
{
|
||||
// The format for specifying validation rules and parameters follows a {rule}:{parameters}
|
||||
// convention. For instance, "max:3" specifies that the value may only be 3 characters in
|
||||
// length. And "unique:users" specifies that a value must be unique on the "users" table.
|
||||
// The format for specifying validation rules and parameters follows
|
||||
// a {rule}:{parameters} convention. For instance, "max:3" specifies
|
||||
// that the value may only be 3 characters in length.
|
||||
$parameters = (($colon = strpos($rule, ':')) !== false) ? explode(',', substr($rule, $colon + 1)) : array();
|
||||
|
||||
return array(is_numeric($colon) ? substr($rule, 0, $colon) : $rule, $parameters);
|
||||
|
@ -586,9 +628,9 @@ public function connection(\Laravel\Database\Connection $connection)
|
|||
*/
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
// First we will slice the "validate_" prefix off of the validator since custom
|
||||
// validators are not registered with such a prefix. We will then call the validator
|
||||
// and pass it the parameters we received.
|
||||
// First we will slice the "validate_" prefix off of the validator
|
||||
// since custom validators are not registered with such a prefix.
|
||||
// Then, if a custom validator exists, we will call it.
|
||||
if (isset(static::$validators[$method = substr($method, 9)]))
|
||||
{
|
||||
return call_user_func_array(static::$validators[$method], $parameters);
|
||||
|
|
|
@ -133,9 +133,10 @@ protected static function name($name)
|
|||
{
|
||||
if (is_null(static::$composers)) static::$composers = require APP_PATH.'composers'.EXT;
|
||||
|
||||
// The view's name may specified in several different ways in the composers file.
|
||||
// The composer may simple have a string value, which is the name. Or, the composer
|
||||
// could have an array value in which a "name" key exists.
|
||||
// The view's name may specified in several different ways in the
|
||||
// composers file. The composer may simple have a string value,
|
||||
// which is the name. Or, the composer could have an array
|
||||
// value in which a "name" key exists.
|
||||
foreach (static::$composers as $key => $value)
|
||||
{
|
||||
if ($name === $value or (is_array($value) and $name === Arr::get($value, 'name'))) return $key;
|
||||
|
@ -170,17 +171,15 @@ public function render()
|
|||
{
|
||||
static::compose($this);
|
||||
|
||||
// All nested views and responses are evaluated before the main view. This allows
|
||||
// the assets used by these views to be added to the asset container before the
|
||||
// All nested views and responses are evaluated before the main view.
|
||||
// This allows the assets used by these views to be added to the asset
|
||||
// container before the
|
||||
// main view is evaluated and dumps the links to the assets.
|
||||
foreach ($this->data as &$data)
|
||||
{
|
||||
if ($data instanceof View or $data instanceof Response) $data = $data->render();
|
||||
}
|
||||
|
||||
// We don't want the view's contents to be rendered immediately, so we will fire
|
||||
// up an output buffer to catch the view output. The output of the view will be
|
||||
// rendered automatically later in the request lifecycle.
|
||||
ob_start() and extract($this->data, EXTR_SKIP);
|
||||
|
||||
// If the view is a "Blade" view, we need to check the view for modifications
|
||||
|
@ -200,14 +199,15 @@ public function render()
|
|||
*/
|
||||
protected function compile()
|
||||
{
|
||||
// For simplicity, compiled views are stored in a single directory by the MD5 hash of
|
||||
// their name. This allows us to avoid recreating the entire view directory structure
|
||||
// within the compiled views directory.
|
||||
// For simplicity, compiled views are stored in a single directory by
|
||||
// the MD5 hash of their name. This allows us to avoid recreating the
|
||||
// entire view directory structure within the compiled views directory.
|
||||
$compiled = STORAGE_PATH.'views/'.md5($this->view);
|
||||
|
||||
// The view will only be re-compiled if the view has been modified since the last compiled
|
||||
// version of the view was created or no compiled view exists. Otherwise, the path will
|
||||
// be returned without re-compiling.
|
||||
// The view will only be re-compiled if the view has been modified
|
||||
// since the last compiled version of the view was created or no
|
||||
// compiled view exists. Otherwise, the path will be returned
|
||||
// without re-compiling.
|
||||
if ((file_exists($compiled) and filemtime($this->path) > filemtime($compiled)) or ! file_exists($compiled))
|
||||
{
|
||||
file_put_contents($compiled, Blade::parse($this->path));
|
||||
|
|
Loading…
Reference in New Issue