more refactoring for 2.0
This commit is contained in:
@@ -4,6 +4,28 @@ use Closure;
|
||||
use Laravel\Response;
|
||||
use Laravel\Container;
|
||||
|
||||
class Delegate {
|
||||
|
||||
/**
|
||||
* The destination of the route delegate.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $destination;
|
||||
|
||||
/**
|
||||
* Create a new route delegate instance.
|
||||
*
|
||||
* @param string $destination
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($destination)
|
||||
{
|
||||
$this->destination = $destination;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Caller {
|
||||
|
||||
/**
|
||||
@@ -60,10 +82,10 @@ class Caller {
|
||||
|
||||
if ( ! is_null($response = $route->call()))
|
||||
{
|
||||
// If a route returns a string, 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 (is_string($response)) $response = $this->delegate($route, $response);
|
||||
// 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) $response = $this->delegate($route, $response->destination);
|
||||
|
||||
return $this->finish($route, $response);
|
||||
}
|
||||
@@ -98,6 +120,11 @@ class Caller {
|
||||
*/
|
||||
protected function delegate(Route $route, $delegate)
|
||||
{
|
||||
if (strpos($delegate, '@') === false)
|
||||
{
|
||||
throw new \Exception("Route delegate [$delegate] has an invalid format.");
|
||||
}
|
||||
|
||||
list($controller, $method) = explode('@', $delegate);
|
||||
|
||||
$controller = $this->resolve($controller);
|
||||
|
||||
107
laravel/routing/loader.php
Normal file
107
laravel/routing/loader.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php namespace Laravel\Routing;
|
||||
|
||||
use Laravel\Arr;
|
||||
|
||||
class Loader {
|
||||
|
||||
/**
|
||||
* The location of the base routes file.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $base;
|
||||
|
||||
/**
|
||||
* The directory containing nested route files.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $nest;
|
||||
|
||||
/**
|
||||
* A cache for all of the routes defined for the entire application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $everything;
|
||||
|
||||
/**
|
||||
* Create a new route loader instance.
|
||||
*
|
||||
* @param string $base
|
||||
* @param string $nest
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($base, $nest)
|
||||
{
|
||||
$this->base = $base;
|
||||
$this->nest = $nest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the applicable routes for a given URI.
|
||||
*
|
||||
* @param string $uri
|
||||
* @return array
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the appropriate routes from the routes directory for a given URI.
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
elseif (file_exists($path = str_replace('.php', '/routes.php', $path)))
|
||||
{
|
||||
return require $path;
|
||||
}
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get every route defined for the application.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function everything()
|
||||
{
|
||||
if ( ! is_null($this->everything)) return $this->everything;
|
||||
|
||||
$routes = array();
|
||||
|
||||
// Since route files can be nested deep within the route directory, we need to
|
||||
// recursively spin through the directory to find every file.
|
||||
$directoryIterator = new \RecursiveDirectoryIterator($this->nest);
|
||||
|
||||
$recursiveIterator = new \RecursiveIteratorIterator($directoryIterator, \RecursiveIteratorIterator::SELF_FIRST);
|
||||
|
||||
foreach ($recursiveIterator as $file)
|
||||
{
|
||||
if (filetype($file) === 'file')
|
||||
{
|
||||
$routes = array_merge(require $file, $routes);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->everything = $routes;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -95,11 +95,13 @@ class Route {
|
||||
}
|
||||
|
||||
// Otherwise, we will assume the route is an array and will return the first value with
|
||||
// a key of "do", or the first instance of a Closure. If the value is a string, the route
|
||||
// is delegating the responsibility for handling the request to a controller.
|
||||
// a key of "delegate", or the first instance of a Closure. If the value is a string, the
|
||||
// route is delegating the responsibility for handling the request to a controller.
|
||||
elseif (is_array($this->callback))
|
||||
{
|
||||
return Arr::first($this->callback, function($key, $value) {return $key == 'do' or $value instanceof Closure;});
|
||||
$callback = Arr::first($this->callback, function($key, $value) {return $key == 'delegate' or $value instanceof Closure;});
|
||||
|
||||
return ($callback instanceof Closure) ? call_user_func_array($callback, $this->parameters) : new Delegate($callback);
|
||||
}
|
||||
|
||||
// If a value defined for a route is a string, it means the route is delegating control
|
||||
@@ -107,7 +109,7 @@ class Route {
|
||||
// for the route caller to parse and delegate.
|
||||
elseif (is_string($this->callback))
|
||||
{
|
||||
return $this->callback;
|
||||
return new Delegate($this->callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ use Laravel\Request;
|
||||
class Router {
|
||||
|
||||
/**
|
||||
* All of the routes available to the router.
|
||||
* The route loader instance.
|
||||
*
|
||||
* @var array
|
||||
* @var Loader
|
||||
*/
|
||||
public $routes;
|
||||
public $loader;
|
||||
|
||||
/**
|
||||
* The named routes that have been found so far.
|
||||
@@ -28,13 +28,13 @@ class Router {
|
||||
/**
|
||||
* Create a new router for a request method and URI.
|
||||
*
|
||||
* @param array $routes
|
||||
* @param Loader $loader
|
||||
* @param string $controllers
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($routes, $controllers)
|
||||
public function __construct(Loader $loader, $controllers)
|
||||
{
|
||||
$this->routes = $routes;
|
||||
$this->loader = $loader;
|
||||
$this->controllers = $controllers;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ class Router {
|
||||
{
|
||||
if (array_key_exists($name, $this->names)) return $this->names[$name];
|
||||
|
||||
$arrayIterator = new \RecursiveArrayIterator($this->routes);
|
||||
$arrayIterator = new \RecursiveArrayIterator($this->loader->everything());
|
||||
|
||||
$recursiveIterator = new \RecursiveIteratorIterator($arrayIterator);
|
||||
|
||||
@@ -75,18 +75,20 @@ class Router {
|
||||
*/
|
||||
public function route(Request $request)
|
||||
{
|
||||
$routes = $this->loader->load($request->uri());
|
||||
|
||||
// Put the request method and URI in route form. Routes begin with
|
||||
// the request method and a forward slash.
|
||||
$destination = $request->method().' /'.trim($request->uri(), '/');
|
||||
|
||||
// Check for a literal route match first. If we find one, there is
|
||||
// no need to spin through all of the routes.
|
||||
if (isset($this->routes[$destination]))
|
||||
if (isset($routes[$destination]))
|
||||
{
|
||||
return $request->route = new Route($destination, $this->routes[$destination], array());
|
||||
return $request->route = new Route($destination, $routes[$destination], array());
|
||||
}
|
||||
|
||||
foreach ($this->routes as $keys => $callback)
|
||||
foreach ($routes as $keys => $callback)
|
||||
{
|
||||
// Only check routes that have multiple URIs or wildcards.
|
||||
// Other routes would have been caught by the check for literal matches.
|
||||
|
||||
Reference in New Issue
Block a user