updated routing to fix several issues.
This commit is contained in:
@@ -2,23 +2,24 @@
|
||||
|
||||
use Closure;
|
||||
use Laravel\Bundle;
|
||||
use Laravel\Request;
|
||||
use Laravel\Response;
|
||||
|
||||
class Route {
|
||||
|
||||
/**
|
||||
* The route key, including request method and URI.
|
||||
* The URI the route response to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $key;
|
||||
public $uri;
|
||||
|
||||
/**
|
||||
* The URI the route responds to.
|
||||
* The request method the route responds to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $uris;
|
||||
public $method;
|
||||
|
||||
/**
|
||||
* The bundle in which the route was registered.
|
||||
@@ -44,65 +45,72 @@ class Route {
|
||||
/**
|
||||
* Create a new Route instance.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $method
|
||||
* @param string $uri
|
||||
* @param array $action
|
||||
* @param array $parameters
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($key, $action, $parameters = array())
|
||||
public function __construct($method, $uri, $action, $parameters = array())
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->uri = $uri;
|
||||
$this->method = $method;
|
||||
$this->action = $action;
|
||||
|
||||
// Extract each URI from the route key. Since the route key has the request
|
||||
// method, we will extract that from the string. If the URI points to the
|
||||
// root of the application, a single forward slash is returned.
|
||||
$uris = array_get($action, 'handles', array($key));
|
||||
|
||||
$this->uris = array_map(array($this, 'destination'), $uris);
|
||||
|
||||
// Determine the bundle in which the route was registered. We will know
|
||||
// the bundle by using the bundle::handles method, which will return
|
||||
// the bundle assigned to that URI.
|
||||
$this->bundle = Bundle::handles($this->uris[0]);
|
||||
$this->bundle = Bundle::handles($uri);
|
||||
|
||||
$defaults = array_get($action, 'defaults', array());
|
||||
|
||||
$this->parameters = array_merge($parameters, $defaults);
|
||||
|
||||
// Once we have set the parameters and URIs, we'll transpose the route
|
||||
// parameters onto the URIs so that the routes response naturally to
|
||||
// the handles without the wildcards messing them up.
|
||||
foreach ($this->uris as &$uri)
|
||||
{
|
||||
$uri = $this->transpose($uri, $this->parameters);
|
||||
}
|
||||
// We'll set the parameters based on the number of parameters passed
|
||||
// compared to the parameters that were needed. If more parameters
|
||||
// are needed, we'll merge in defaults.
|
||||
$this->parameters($uri, $action, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitute the parameters in a given URI.
|
||||
* Set the parameters array to the correct value.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param array $action
|
||||
* @param array $parameters
|
||||
* @return string
|
||||
* @return void
|
||||
*/
|
||||
public static function transpose($uri, $parameters)
|
||||
protected function parameters($uri, $action, $parameters)
|
||||
{
|
||||
// Spin through each route parameter and replace the route wildcard segment
|
||||
// with the corresponding parameter passed to the method. Afterwards, we'll
|
||||
// replace all of the remaining optional URI segments.
|
||||
foreach ((array) $parameters as $parameter)
|
||||
$wildcards = 0;
|
||||
|
||||
$defaults = (array) array_get($action, 'defaults');
|
||||
|
||||
// We need to determine how many of the default paramters should be merged
|
||||
// into the parameter array. First, we will count the number of wildcards
|
||||
// in the route URI and then merge the defaults.
|
||||
foreach (array_keys(Router::patterns()) as $wildcard)
|
||||
{
|
||||
if ( ! is_null($parameter))
|
||||
{
|
||||
$uri = preg_replace('/\(.+?\)/', $parameter, $uri, 1);
|
||||
}
|
||||
$wildcards += substr_count($uri, $wildcard);
|
||||
}
|
||||
|
||||
// If there are any remaining optional place-holders, we'll just replace
|
||||
// them with empty strings since not every optional parameter has to be
|
||||
// in the array of parameters that were passed.
|
||||
return str_replace(array_keys(Router::$optional), '', $uri);
|
||||
$needed = $wildcards - count($parameters);
|
||||
|
||||
// If there are less parameters than wildcards, we will figure out how
|
||||
// many parameters we need to inject from the array of defaults and
|
||||
// merge them in into the main array for the route.
|
||||
if ($needed > 0)
|
||||
{
|
||||
$defaults = array_slice($defaults, count($defaults) - $needed);
|
||||
|
||||
$parameters = array_merge($parameters, $defaults);
|
||||
}
|
||||
|
||||
// If the final number of parameters doesn't match the count of the
|
||||
// wildcards, we'll pad parameter array with null to cover any of
|
||||
// the default values that were forgotten.
|
||||
if (count($parameters) !== $wildcards)
|
||||
{
|
||||
$parameters = array_pad($parameters, $wildcards, null);
|
||||
}
|
||||
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,19 +149,22 @@ class Route {
|
||||
*/
|
||||
public function response()
|
||||
{
|
||||
// If the action is a string, it is simply pointing the route to a
|
||||
// controller action, and we can just call the action and return
|
||||
// its response. This is the most basic form of route, and is
|
||||
// the simplest to handle.
|
||||
if ( ! is_null($delegate = $this->delegate()))
|
||||
// If the action is a string, it is pointing the route to a controller
|
||||
// action, and we can just call the action and return its response.
|
||||
// We'll just pass the action off to the Controller class.
|
||||
$delegate = $this->delegate();
|
||||
|
||||
if ( ! is_null($delegate))
|
||||
{
|
||||
return Controller::call($delegate, $this->parameters);
|
||||
}
|
||||
|
||||
// If the route does not have a delegate, it should either be a
|
||||
// Closure instance or have a Closure in its action array, so
|
||||
// we will attempt to get the Closure and call it.
|
||||
elseif ( ! is_null($handler = $this->handler()))
|
||||
// If the route does not have a delegate, then it must be a Closure
|
||||
// instance or have a Closure in its action array, so we will try
|
||||
// to locate the Closure and call it directly.
|
||||
$handler = $this->handler();
|
||||
|
||||
if ( ! is_null($handler))
|
||||
{
|
||||
return call_user_func_array($handler, $this->parameters);
|
||||
}
|
||||
@@ -162,21 +173,23 @@ class Route {
|
||||
/**
|
||||
* Get the filters that are attached to the route for a given event.
|
||||
*
|
||||
* If the route belongs to a bundle, the bundle's global filters are returned too.
|
||||
*
|
||||
* @param string $event
|
||||
* @return array
|
||||
*/
|
||||
protected function filters($event)
|
||||
{
|
||||
$filters = array_unique(array($event, Bundle::prefix($this->bundle).$event));
|
||||
$global = Bundle::prefix($this->bundle).$event;
|
||||
|
||||
// Next wee will check to see if there are any filters attached
|
||||
// for the given event. If there are, we'll merge them in with
|
||||
// the global filters for the application event.
|
||||
$filters = array_unique(array($event, $global));
|
||||
|
||||
// Next we will check to see if there are any filters attached to
|
||||
// the route for the given event. If there are, we'll merge them
|
||||
// in with the global filters for the event.
|
||||
if (isset($this->action[$event]))
|
||||
{
|
||||
$filters = array_merge($filters, Filter::parse($this->action[$event]));
|
||||
$assigned = Filter::parse($this->action[$event]);
|
||||
|
||||
$filters = array_merge($filters, $assigned);
|
||||
}
|
||||
|
||||
return array(new Filter_Collection($filters));
|
||||
@@ -197,8 +210,6 @@ class Route {
|
||||
/**
|
||||
* Get the anonymous function assigned to handle the route.
|
||||
*
|
||||
* If no anonymous function is assigned, null will be returned by the method.
|
||||
*
|
||||
* @return Closure
|
||||
*/
|
||||
protected function handler()
|
||||
@@ -222,72 +233,116 @@ class Route {
|
||||
*/
|
||||
public function is($name)
|
||||
{
|
||||
return is_array($this->action) and array_get($this->action, 'name') === $name;
|
||||
return array_get($this->action, 'name') === $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the route handles a given URI.
|
||||
* Register a controller with the router.
|
||||
*
|
||||
* @param string $uri
|
||||
* @return bool
|
||||
* @param string|array $controller
|
||||
* @param string|array $defaults
|
||||
* @return void
|
||||
*/
|
||||
public function handles($uri)
|
||||
public static function controller($controllers, $defaults = 'index')
|
||||
{
|
||||
$pattern = ($uri !== '/') ? str_replace('*', '(.*)', $uri).'\z' : '^/$';
|
||||
|
||||
return ! is_null(array_first($this->uris, function($key, $uri) use ($pattern)
|
||||
{
|
||||
return preg_match('#'.$pattern.'#', $uri);
|
||||
}));
|
||||
Router::controller($controllers, $defaults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a route with the router.
|
||||
* Register a secure controller with the router.
|
||||
*
|
||||
* <code>
|
||||
* // Register a route with the router
|
||||
* Router::register('GET /', function() {return 'Home!';});
|
||||
*
|
||||
* // Register a route that handles multiple URIs with the router
|
||||
* Router::register(array('GET /', 'GET /home'), function() {return 'Home!';});
|
||||
* </code>
|
||||
* @param string|array $controllers
|
||||
* @param string|array $defaults
|
||||
* @return void
|
||||
*/
|
||||
public static function secure_controller($controllers, $defaults = 'index')
|
||||
{
|
||||
Router::controller($controllers, $defaults, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a GET route with the router.
|
||||
*
|
||||
* @param string|array $route
|
||||
* @param mixed $action
|
||||
* @param bool $https
|
||||
* @return void
|
||||
*/
|
||||
public static function to($route, $action)
|
||||
public static function get($route, $action)
|
||||
{
|
||||
Router::register($route, $action);
|
||||
Router::register('GET', $route, $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a POST route with the router.
|
||||
*
|
||||
* @param string|array $route
|
||||
* @param mixed $action
|
||||
* @return void
|
||||
*/
|
||||
public static function post($route, $action)
|
||||
{
|
||||
Router::register('POST', $route, $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a PUT route with the router.
|
||||
*
|
||||
* @param string|array $route
|
||||
* @param mixed $action
|
||||
* @return void
|
||||
*/
|
||||
public static function put($route, $action)
|
||||
{
|
||||
Router::register('PUT', $route, $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a DELETE route with the router.
|
||||
*
|
||||
* @param string|array $route
|
||||
* @param mixed $action
|
||||
* @return void
|
||||
*/
|
||||
public static function delete($route, $action)
|
||||
{
|
||||
Router::register('DELETE', $route, $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a route that handles any request method.
|
||||
*
|
||||
* @param string|array $route
|
||||
* @param mixed $action
|
||||
* @return void
|
||||
*/
|
||||
public static function any($route, $action)
|
||||
{
|
||||
Router::register('*', $route, $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a group of routes that share attributes.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param Closure $callback
|
||||
* @return void
|
||||
*/
|
||||
public static function group($attributes, Closure $callback)
|
||||
{
|
||||
Router::group($attributes, $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a HTTPS route with the router.
|
||||
*
|
||||
* @param string $method
|
||||
* @param string|array $route
|
||||
* @param mixed $action
|
||||
* @return void
|
||||
*/
|
||||
public static function secure($route, $action)
|
||||
public static function secure($method, $route, $action)
|
||||
{
|
||||
Router::secure($route, $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the URI string from a route destination.
|
||||
*
|
||||
* <code>
|
||||
* // Returns "home/index" as the destination's URI
|
||||
* $uri = Route::uri('GET /home/index');
|
||||
* </code>
|
||||
*
|
||||
* @param string $destination
|
||||
* @return string
|
||||
*/
|
||||
public static function destination($destination)
|
||||
{
|
||||
return trim(substr($destination, strpos($destination, '/')), '/') ?: '/';
|
||||
Router::secure($method, $route, $action);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user