diff --git a/application/config/application.php b/application/config/application.php index 8dadc03a..7503048d 100644 --- a/application/config/application.php +++ b/application/config/application.php @@ -39,18 +39,6 @@ 'language' => 'en', - /* - |-------------------------------------------------------------------------- - | Application Character Encoding - |-------------------------------------------------------------------------- - | - | The default character encoding used by your application. This is the - | character encoding that will be used by the Str, Text, and Form classes. - | - */ - - 'encoding' => 'UTF-8', - /* |-------------------------------------------------------------------------- | Application Timezone @@ -65,22 +53,15 @@ /* |-------------------------------------------------------------------------- - | Auto-Loaded Packages + | Application Character Encoding |-------------------------------------------------------------------------- | - | The packages that should be auto-loaded each time Laravel handles - | a request. These should generally be packages that you use on almost - | every request to your application. - | - | Each package specified here will be bootstrapped and can be conveniently - | used by your application's routes, models, and libraries. - | - | Note: The package names in this array should correspond to a package - | directory in application/packages. + | The default character encoding used by your application. This is the + | character encoding that will be used by the Str, Text, and Form classes. | */ - 'packages' => array(), + 'encoding' => 'UTF-8', /* |-------------------------------------------------------------------------- @@ -95,4 +76,40 @@ 'key' => '', + /* + |-------------------------------------------------------------------------- + | SSL Link Generation + |-------------------------------------------------------------------------- + | + | Many sites use SSL to protect their users data. However, you may not + | always be able to use SSL on your development machine, meaning all HTTPS + | will be broken during development. + | + | For this reason, you may wish to disable the generation of HTTPS links + | throughout your application. This option does just that. All attempts to + | generate HTTPS links will generate regular HTTP links instead. + | + */ + + 'ssl' => true, + + /* + |-------------------------------------------------------------------------- + | Auto-Loaded Packages + |-------------------------------------------------------------------------- + | + | The packages that should be auto-loaded each time Laravel handles a + | request. These should generally be packages that you use on almost every + | request to your application. + | + | Each package specified here will be bootstrapped and can be conveniently + | used by your application's routes, models, and libraries. + | + | Note: The package names in this array should correspond to a package + | directory in application/packages. + | + */ + + 'packages' => array(), + ); \ No newline at end of file diff --git a/laravel/controller.php b/laravel/controller.php index 97baf2cf..8f966a68 100644 --- a/laravel/controller.php +++ b/laravel/controller.php @@ -1,6 +1,6 @@ -$name; } + /** + * Resolve a controller name to a controller instance. + * + * @param Container $container + * @param string $controller + * @param string $path + * @return Controller + */ + public static function resolve(Container $container, $controller, $path) + { + if ( ! static::load($controller, $path)) return; + + // If the controller is registered in the IoC container, we will resolve it out + // of the container. Using constructor injection on controllers via the container + // allows more flexible and testable development of applications. + if ($container->registered('controllers.'.$controller)) + { + return $container->resolve('controllers.'.$controller); + } + + // If the controller was not registered in the container, we will instantiate + // an instance of the controller manually. All controllers are suffixed with + // "_Controller" to avoid namespacing. Allowing controllers to exist in the + // global namespace gives the developer a convenient API for using the framework. + $controller = str_replace(' ', '_', ucwords(str_replace('.', ' ', $controller))).'_Controller'; + + return new $controller; + } + + /** + * Load the file for a given controller. + * + * @param string $controller + * @param string $path + * @return bool + */ + protected static function load($controller, $path) + { + if (file_exists($path = $path.strtolower(str_replace('.', '/', $controller)).EXT)) + { + require $path; + + return true; + } + + return false; + } + /** * Magic Method to handle calls to undefined functions on the controller. * diff --git a/laravel/database/query.php b/laravel/database/query.php index b98d9d0f..36dab41a 100644 --- a/laravel/database/query.php +++ b/laravel/database/query.php @@ -1,4 +1,4 @@ -skip(($page - 1) * $per_page)->take($per_page); } @@ -522,6 +518,22 @@ private function aggregate($aggregator, $column) return $result; } + /** + * Get the paginated query results as a Paginator instance. + * + * @param int $per_page + * @param array $columns + * @return Paginator + */ + public function paginate($per_page, $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. + $page = Paginator::page($total = $this->count(), $per_page); + + return Paginator::make($this->for_page($page, $per_page)->get($columns), $total, $per_page); + } + /** * Insert an array of values into the database table. * diff --git a/laravel/lang.php b/laravel/lang.php index b1e9c3f1..73bd95aa 100644 --- a/laravel/lang.php +++ b/laravel/lang.php @@ -77,6 +77,8 @@ public static function line($key, $replacements = array(), $language = null, $pa { if (count($paths) == 0) $paths = array(SYS_LANG_PATH, LANG_PATH); + if (is_null($language)) $language = Config::get('application.language'); + return new static($key, $replacements, $language, $paths); } @@ -147,7 +149,7 @@ protected function parse($key) */ protected function load($file) { - if (isset(static::$lines[$this->language.$file])) return; + if (isset(static::$lines[$this->language.$file])) return true; $language = array(); diff --git a/laravel/language/en/pagination.php b/laravel/language/en/pagination.php new file mode 100644 index 00000000..5696eaa6 --- /dev/null +++ b/laravel/language/en/pagination.php @@ -0,0 +1,9 @@ + '← Previous', + 'first' => 'First', + 'next' => 'Next →', + 'last' => 'Last', + 'status' => 'Page :current of :last', + +); \ No newline at end of file diff --git a/laravel/language/en/validation.php b/laravel/language/en/validation.php index ea7e1047..6092bc0f 100644 --- a/laravel/language/en/validation.php +++ b/laravel/language/en/validation.php @@ -2,15 +2,19 @@ return array( - /** - * The validation error messages. - * - * These error messages will be used by the Validator class if no - * other messages are provided by the developer. - */ + /* + |-------------------------------------------------------------------------- + | Validation Error Messages + |-------------------------------------------------------------------------- + | + | These error messages will be used by the Validator class if no other + | messages are provided by the developer. They may be overriden by the + | developer in the application language directory. + | + */ "accepted" => "The :attribute must be accepted.", - "active_url" => "The :attribute does not exist.", + "active_url" => "The :attribute is not an active URL.", "alpha" => "The :attribute may only contain letters.", "alpha_dash" => "The :attribute may only contain letters, numbers, dashes, and underscores.", "alpha_num" => "The :attribute may only contain letters and numbers.", @@ -30,11 +34,15 @@ "unique" => "The :attribute has already been taken.", "url" => "The :attribute format is invalid.", - /** - * The following words are appended to the "size" messages when - * applicable, such as when validating string lengths or the - * size of file uploads. - */ + /* + |-------------------------------------------------------------------------- + | Validation Units + |-------------------------------------------------------------------------- + | + | The following words are appended to the "size" messages when applicable, + | such as when validating string lengths or the size of file uploads. + | + */ "characters" => "characters", "kilobytes" => "kilobytes", diff --git a/laravel/laravel.php b/laravel/laravel.php index 85f28c94..a7e0bd03 100644 --- a/laravel/laravel.php +++ b/laravel/laravel.php @@ -39,8 +39,8 @@ * be returned to the browser. */ require SYS_PATH.'request'.EXT; -require SYS_PATH.'routing/router'.EXT; require SYS_PATH.'routing/route'.EXT; +require SYS_PATH.'routing/router'.EXT; require SYS_PATH.'routing/loader'.EXT; require SYS_PATH.'routing/caller'.EXT; diff --git a/laravel/paginator.php b/laravel/paginator.php index 9847804d..b4727cc7 100644 --- a/laravel/paginator.php +++ b/laravel/paginator.php @@ -9,72 +9,85 @@ class Paginator { */ public $results; - /** - * The total number of results. - * - * @var int - */ - public $total; - /** * The current page. * * @var int */ - public $page; - - /** - * The number of items per page. - * - * @var int - */ - public $per_page; + protected $page; /** * The last page available for the result set. * * @var int */ - public $last_page; + protected $last; /** - * The language that should be used when generating page links. + * The total number of results. * - * @var string + * @var int */ - public $language; + protected $total; + + /** + * The number of items per page. + * + * @var int + */ + protected $per_page; /** * The values that should be appended to the end of the link query strings. * * @var array */ - public $append = array(); + protected $appends; /** - * The format that will be used to wrap the entire pagination string. + * The compiled appendage that will be appended to the links. + * + * This consists of a sprintf format with a page place-holder and query string. * * @var string */ - protected $wrapper = '
* // Create a response with the "layout" named view
- * return Response::with('layout');
+ * return Response::of('layout');
*
* // Create a response with the "layout" named view and data
- * return Response::with('layout', array('name' => 'Taylor'));
+ * return Response::of('layout', array('name' => 'Taylor'));
*
*
* @param string $name
* @param array $data
* @return Response
*/
- public static function with($name, $data = array())
+ public static function of($name, $data = array())
{
return new static(IoC::container()->core('view')->of($name, $data));
}
@@ -296,17 +296,17 @@ public function status($status)
*
*
* // Create a response instance with the "layout" named view
- * return Response::with_layout();
+ * return Response::of_layout();
*
* // Create a response instance with a named view and data
- * return Response::with_layout(array('name' => 'Taylor'));
+ * return Response::of_layout(array('name' => 'Taylor'));
*
*/
public static function __callStatic($method, $parameters)
{
- if (strpos($method, 'with_') === 0)
+ if (strpos($method, 'of_') === 0)
{
- return static::with(substr($method, 5), Arr::get($parameters, 0, array()));
+ return static::with(substr($method, 3), Arr::get($parameters, 0, array()));
}
}
diff --git a/laravel/routing/caller.php b/laravel/routing/caller.php
index 28061ca8..2b52da38 100644
--- a/laravel/routing/caller.php
+++ b/laravel/routing/caller.php
@@ -3,6 +3,7 @@
use Closure;
use Laravel\Response;
use Laravel\Container;
+use Laravel\Controller;
class Caller {
@@ -45,7 +46,7 @@ public function __construct(Container $container, $filters, $path)
/**
* Call a given route and return the route's response.
*
- * @param Route $route
+ * @param Route $route
* @return Response
*/
public function call(Route $route)
@@ -53,58 +54,70 @@ public function call(Route $route)
// Since "before" filters can halt the request cycle, we will return any response
// from the before filters. Allowing the filters to halt the request cycle makes
// common tasks like authorization convenient to implement.
- if ( ! is_null($response = $this->before($route)))
+ $before = array_merge(array('before'), $route->filters('before'));
+
+ if ( ! is_null($response = $this->filter($before, array(), true)))
{
return $this->finish($route, $response);
}
- if ( ! is_null($response = $route->call()))
+ // If a route returns a Delegate, it means the route is delegating the handling
+ // of the request to a controller method. We will pass the Delegate instance
+ // to the "delegate" method which will call the controller.
+ if ($route->delegates())
+ {
+ return $this->delegate($route, $route->call());
+ }
+ // If no before filters returned a response and the route is not delegating
+ // execution to a controller, we will call the route like normal and return
+ // the response. If the no response is given by the route, we will return
+ // the 404 error view.
+ elseif ( ! is_null($response = $route->call()))
{
- // If a route returns a Delegate, it also means the route is delegating the
- // handling of the request to a controller method. So, we will pass the string
- // to the route delegator, exploding on "@".
- if ($response instanceof Delegate) return $this->delegate($route, $response->destination);
-
return $this->finish($route, $response);
}
-
- // If we get to this point, no response was returned from the filters or the route.
- // The 404 response will be returned to the browser instead of a blank screen.
- return $this->finish($route, Response::error('404'));
+ else
+ {
+ return $this->finish($route, Response::error('404'));
+ }
}
/**
* Handle the delegation of a route to a controller method.
*
- * @param Route $route
- * @param string $delegate
+ * @param Route $route
+ * @param Delegate $delegate
* @return mixed
*/
- protected function delegate(Route $route, $delegate)
+ protected function delegate(Route $route, Delegate $delegate)
{
- if (strpos($delegate, '@') === false)
+ // Route delegates follow a {controller}@{method} naming convention. For example,
+ // to delegate to the "home" controller's "index" method, the delegate should be
+ // formatted like "home@index". Nested controllers may be delegated to using dot
+ // syntax, like so: "user.profile@show".
+ if (strpos($delegate->destination, '@') === false)
{
- throw new \Exception("Route delegate [$delegate] has an invalid format.");
+ throw new \Exception("Route delegate [{$delegate->destination}] has an invalid format.");
}
- list($controller, $method) = explode('@', $delegate);
+ list($controller, $method) = explode('@', $delegate->destination);
- $controller = $this->resolve($controller);
+ $controller = Controller::resolve($this->container, $controller, $this->path);
// If the controller doesn't exist or the request is to an invalid method, we will
// return the 404 error response. The "before" method and any method beginning with
// an underscore are not publicly available.
- if (is_null($controller) or ($method == 'before' or strncmp($method, '_', 1) === 0))
+ if (is_null($controller) or ! $this->callable($method))
{
return Response::error('404');
}
$controller->container = $this->container;
- // Again, as was the case with route closures, if the controller "before" filters return
- // a response, it will be considered the response to the request and the controller method
- // will not be used to handle the request to the application.
- $response = $this->before($controller);
+ // Again, as was the case with route closures, if the controller "before" filters
+ // return a response, it will be considered the response to the request and the
+ // controller method will not be used to handle the request to the application.
+ $response = $this->filter($controller->filters('before'), array(), true);
if (is_null($response))
{
@@ -115,48 +128,14 @@ protected function delegate(Route $route, $delegate)
}
/**
- * Resolve a controller name to a controller instance.
+ * Determine if a given controller method is callable.
*
- * @param string $controller
- * @return Controller
- */
- protected function resolve($controller)
- {
- if ( ! $this->load($controller)) return;
-
- // If the controller is registered in the IoC container, we will resolve it out
- // of the container. Using constructor injection on controllers via the container
- // allows more flexible and testable development of applications.
- if ($this->container->registered('controllers.'.$controller))
- {
- return $this->container->resolve('controllers.'.$controller);
- }
-
- // If the controller was not registered in the container, we will instantiate
- // an instance of the controller manually. All controllers are suffixed with
- // "_Controller" to avoid namespacing. Allowing controllers to exist in the
- // global namespace gives the developer a convenient API for using the framework.
- $controller = str_replace(' ', '_', ucwords(str_replace('.', ' ', $controller))).'_Controller';
-
- return new $controller;
- }
-
- /**
- * Load the file for a given controller.
- *
- * @param string $controller
+ * @param string $method
* @return bool
*/
- protected function load($controller)
+ protected function callable($method)
{
- if (file_exists($path = $this->path.strtolower(str_replace('.', '/', $controller)).EXT))
- {
- require $path;
-
- return true;
- }
-
- return false;
+ return $method == 'before' or $method == 'after' or strncmp($method, '_', 1) === 0;
}
/**
@@ -164,11 +143,11 @@ protected function load($controller)
*
* The route response will be converted to a Response instance and the "after" filters will be run.
*
- * @param Destination $route
- * @param mixed $response
+ * @param Route|Controller $destination
+ * @param mixed $response
* @return Response
*/
- protected function finish(Destination $destination, $response)
+ protected function finish($destination, $response)
{
if ( ! $response instanceof Response) $response = new Response($response);
@@ -177,22 +156,6 @@ protected function finish(Destination $destination, $response)
return $response;
}
- /**
- * Run the "before" filters for the routing destination.
- *
- * If a before filter returns a value, that value will be considered the response to the
- * request and the route function / controller will not be used to handle the request.
- *
- * @param Route $route
- * @return mixed
- */
- protected function before(Destination $destination)
- {
- $before = array_merge(array('before'), $destination->filters('before'));
-
- return $this->filter($before, array(), true);
- }
-
/**
* Call a filter or set of filters.
*
diff --git a/laravel/routing/destination.php b/laravel/routing/destination.php
deleted file mode 100644
index 69338180..00000000
--- a/laravel/routing/destination.php
+++ /dev/null
@@ -1,13 +0,0 @@
-callback) and isset($this->callback['delegate']);
+ }
+
/**
* Determine if the route has a given name.
*
diff --git a/laravel/routing/router.php b/laravel/routing/router.php
index 557276b3..c9ec23d9 100644
--- a/laravel/routing/router.php
+++ b/laravel/routing/router.php
@@ -1,18 +1,4 @@
-
+ * // Get the current user of the application
+ * $user = Auth::user();
+ *
+ * // Access a property on the current user of the application
+ * $email = Auth::user()->email;
+ *
*
* @return object
*/
@@ -64,8 +73,8 @@ public function user()
/**
* Attempt to log a user into the application.
*
- * If the given credentials are valid, the user will be considered logged into the
- * application and their user ID will be stored in the session data.
+ * If the given credentials are valid, the user will be considered logged into
+ * the application and their user ID will be stored in the session data.
*
* @param string $username
* @param string $password
@@ -101,6 +110,8 @@ public function remember($user)
/**
* Log the current user out of the application.
*
+ * The "logout" closure in the authenciation configuration file will be called.
+ *
* @return void
*/
public function logout()
diff --git a/laravel/security/hashing/bcrypt.php b/laravel/security/hashing/bcrypt.php
index b2e61157..0e89af31 100644
--- a/laravel/security/hashing/bcrypt.php
+++ b/laravel/security/hashing/bcrypt.php
@@ -1,30 +1,30 @@
in 2004-2006 and placed in
-# the public domain. Revised in subsequent years, still public domain.
-#
-# There's absolutely no warranty.
-#
-# The homepage URL for this framework is:
-#
-# http://www.openwall.com/phpass/
-#
-# Please be sure to update the Version line if you edit this file in any way.
-# It is suggested that you leave the main version number intact, but indicate
-# your project name (after the slash) and add your own revision information.
-#
-# Please do not change the "private" password hashing method implemented in
-# here, thereby making your hashes incompatible. However, if you must, please
-# change the hash type identifier (the "$P$") to something different.
-#
-# Obviously, since this code is in the public domain, the above are not
-# requirements (there can be none), but merely suggestions.
-#
+//
+// Portable PHP password hashing framework.
+//
+// Version 0.3 / genuine.
+//
+// Written by Solar Designer
+ * // Get an item from the session
+ * $name = Session::get('name');
+ *
+ * // Return a default value if the item doesn't exist
+ * $name = Session::get('name', 'Taylor');
+ *
+ *
* @param string $key
* @param mixed $default
* @return mixed
@@ -66,6 +74,11 @@ public function get($key, $default = null)
/**
* Write an item to the session.
*
+ *
+ * // Write an item to the session
+ * Session::put('name', 'Taylor');
+ *
+ *
* @param string $key
* @param mixed $value
* @return Driver
@@ -83,6 +96,11 @@ public function put($key, $value)
* Flash data only exists for the next request. After that, it will be removed from
* the session. Flash data is useful for temporary status or welcome messages.
*
+ *
+ * // Flash an item to the session
+ * Session::flash('name', 'Taylor');
+ *
+ *
* @param string $key
* @param mixed $value
* @return Driver
@@ -110,6 +128,11 @@ public function reflash()
* If a string is passed to the method, only that item will be kept. An array may also
* be passed to the method, in which case all items in the array will be kept.
*
+ *
+ * // Keep a session flash item from expiring
+ * Session::keep('name');
+ *
+ *
* @param string|array $key
* @return void
*/
diff --git a/laravel/session/transporters/cookie.php b/laravel/session/transporters/cookie.php
index 82fe14cb..73790a0e 100644
--- a/laravel/session/transporters/cookie.php
+++ b/laravel/session/transporters/cookie.php
@@ -9,6 +9,13 @@ class Cookie implements Transporter {
*/
protected $cookies;
+ /**
+ * The name of the cookie used to store the session ID.
+ *
+ * @var string
+ */
+ const key = 'laravel_session';
+
/**
* Create a new cookie session transporter instance.
*
@@ -28,7 +35,7 @@ public function __construct(\Laravel\Cookie $cookies)
*/
public function get($config)
{
- return $this->cookies->get('laravel_session');
+ return $this->cookies->get(Cookie::key);
}
/**
@@ -40,9 +47,12 @@ public function get($config)
*/
public function put($id, $config)
{
- $minutes = ($config['expire_on_close']) ? 0 : $config['lifetime'];
+ // Session cookies may be set to expire on close, which means we will need to
+ // pass "0" into the cookie manager. This will cause the cookie to not be
+ // deleted until the user closes their browser.
+ $minutes = ( ! $config['expire_on_close']) ? $config['lifetime'] : 0;
- $this->cookies->put('laravel_session', $id, $minutes, $config['path'], $config['domain']);
+ $this->cookies->put(Cookie::key, $id, $minutes, $config['path'], $config['domain']);
}
}
\ No newline at end of file
diff --git a/laravel/session/transporters/transporter.php b/laravel/session/transporters/transporter.php
index b1c464ab..dbed1b6d 100644
--- a/laravel/session/transporters/transporter.php
+++ b/laravel/session/transporters/transporter.php
@@ -1,5 +1,9 @@
rules = $rules;
+ $this->messages = $messages;
$this->attributes = $attributes;
- $this->messages = array_merge($this->messages, $messages);
}
/**
* Create a new validator instance.
*
- * @param array $attributes
- * @param array $rules
- * @param array $messages
+ * @param array $attributes
+ * @param array $rules
+ * @param array $messages
* @return Validator
*/
public static function make($attributes, $rules, $messages = array())
@@ -97,6 +104,18 @@ public static function make($attributes, $rules, $messages = array())
return new static($attributes, $rules, $messages);
}
+ /**
+ * Register a custom validator.
+ *
+ * @param string $name
+ * @param Closure $validator
+ * @return void
+ */
+ public static function register($name, $validator)
+ {
+ static::$validators[$name] = $validator;
+ }
+
/**
* Validate the target array using the specified validation rules.
*
@@ -138,7 +157,7 @@ protected function check($attribute, $rule)
{
list($rule, $parameters) = $this->parse($rule);
- if ( ! method_exists($this, $validator = 'validate_'.$rule))
+ if ( ! method_exists($this, $validator = 'validate_'.$rule) and ! isset(static::$validators[$rule]))
{
throw new \Exception("Validation rule [$rule] doesn't exist.");
}
@@ -327,7 +346,7 @@ protected function validate_unique($attribute, $parameters)
{
if ( ! isset($parameters[1])) $parameters[1] = $attribute;
- if (is_null($this->connection)) $this->connection = Database::connection();
+ if (is_null($this->connection)) $this->connection = DB::connection();
return $this->connection->table($parameters[0])->where($parameters[1], '=', $this->attributes[$attribute])->count() == 0;
}
@@ -434,8 +453,8 @@ protected function validate_mimes($attribute, $parameters)
* Developer specified attribute specific rules take first priority.
* Developer specified error rules take second priority.
*
- * If the message has not been specified by the developer, the default will be used
- * from the validation language file.
+ * If the message has not been specified by the developer, the default
+ * will be used from the validation language file.
*
* @param string $attribute
* @param string $rule
@@ -479,16 +498,23 @@ protected function get_message($attribute, $rule)
*/
protected function format_message($message, $attribute, $rule, $parameters)
{
- $display = Lang::line('attributes.'.$attribute)->get($this->language, str_replace('_', ' ', $attribute));
+ // First we will get the language line for the attribute being validated.
+ // Storing attribute names in a validation file allows the easily replacement
+ // of attribute names (email) with more reader friendly versions (E-Mail).
+ $display = Lang::line('validation.attributes.'.$attribute)->get($this->language, str_replace('_', ' ', $attribute));
$message = str_replace(':attribute', $display, $message);
+ // The "size" family of rules all have place-holders for the values applicable
+ // to their function. For example, the "max" rule has a ":max" place-holder.
if (in_array($rule, $this->size_rules))
{
$max = ($rule == 'between') ? $parameters[1] : $parameters[0];
$message = str_replace(array(':size', ':min', ':max'), array($parameters[0], $parameters[0], $max), $message);
}
+ // The "inclusion" rules, which are rules that check if a value is within
+ // a list of values, all have a place-holder to display the allowed values.
elseif (in_array($rule, array('in', 'not_in', 'mimes')))
{
$message = str_replace(':values', implode(', ', $parameters), $message);
@@ -524,6 +550,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.
$parameters = (($colon = strpos($rule, ':')) !== false) ? explode(',', substr($rule, $colon + 1)) : array();
return array(is_numeric($colon) ? substr($rule, 0, $colon) : $rule, $parameters);
@@ -553,4 +582,20 @@ public function connection(\Laravel\Database\Connection $connection)
return $this;
}
+ /**
+ * Dynamically handle calls to custom registered validators.
+ */
+ 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.
+ if (isset(static::$validators[$method = substr($method, 9)]))
+ {
+ return call_user_func_array(static::$validators[$method], $parameters);
+ }
+
+ throw new \Exception("Call to undefined method [$method] on Validator instance.");
+ }
+
}
\ No newline at end of file