Commit 0af326b6 authored by Taylor Otwell's avatar Taylor Otwell

working on routing architecture.

parent 344f49e1
...@@ -135,6 +135,11 @@ if (System\Config::get('session.driver') != '') ...@@ -135,6 +135,11 @@ if (System\Config::get('session.driver') != '')
System\Session::load(System\Cookie::get('laravel_session')); System\Session::load(System\Cookie::get('laravel_session'));
} }
// --------------------------------------------------------------
// Register the route filters.
// --------------------------------------------------------------
System\Routing\Filter::register(require APP_PATH.'filters'.EXT);
// -------------------------------------------------------------- // --------------------------------------------------------------
// Execute the global "before" filter. // Execute the global "before" filter.
// -------------------------------------------------------------- // --------------------------------------------------------------
...@@ -145,7 +150,7 @@ $response = System\Routing\Filter::call('before', array(), true); ...@@ -145,7 +150,7 @@ $response = System\Routing\Filter::call('before', array(), true);
// ---------------------------------------------------------- // ----------------------------------------------------------
if (is_null($response)) if (is_null($response))
{ {
$route = System\Routing\Router::make(Request::method(), Request::uri())->route(); $route = System\Routing\Router::make(Request::method(), Request::uri(), new System\Routing\Loader)->route();
$response = (is_null($route)) ? System\Response::make(System\View::make('error/404'), 404) : $route->call(); $response = (is_null($route)) ? System\Response::make(System\View::make('error/404'), 404) : $route->call();
} }
......
...@@ -7,7 +7,28 @@ class Filter { ...@@ -7,7 +7,28 @@ class Filter {
* *
* @var array * @var array
*/ */
public static $filters; private static $filters = array();
/**
* Register a set of route filters.
*
* @param array $filters
* @return void
*/
public static function register($filters)
{
static::$filters = array_merge(static::$filters, $filters);
}
/**
* Clear all of the registered route filters.
*
* @return void
*/
public static function clear()
{
static::$filters = array();
}
/** /**
* Call a set of route filters. * Call a set of route filters.
...@@ -19,11 +40,6 @@ class Filter { ...@@ -19,11 +40,6 @@ class Filter {
*/ */
public static function call($filters, $parameters = array(), $override = false) public static function call($filters, $parameters = array(), $override = false)
{ {
if (is_null(static::$filters))
{
static::$filters = require APP_PATH.'filters'.EXT;
}
foreach (explode(', ', $filters) as $filter) foreach (explode(', ', $filters) as $filter)
{ {
if ( ! isset(static::$filters[$filter])) if ( ! isset(static::$filters[$filter]))
...@@ -33,6 +49,9 @@ class Filter { ...@@ -33,6 +49,9 @@ class Filter {
$response = call_user_func_array(static::$filters[$filter], $parameters); $response = call_user_func_array(static::$filters[$filter], $parameters);
// "Before" filters may override the request cycle. For example, an authentication
// filter may redirect a user to a login view if they are not logged in. Because of
// this, we will return the first filter response if overriding is enabled.
if ( ! is_null($response) and $override) if ( ! is_null($response) and $override)
{ {
return $response; return $response;
......
...@@ -8,28 +8,35 @@ class Loader { ...@@ -8,28 +8,35 @@ class Loader {
* @param string * @param string
* @return array * @return array
*/ */
public static function load($uri) public function load($uri)
{ {
$base = require APP_PATH.'routes'.EXT; $base = require APP_PATH.'routes'.EXT;
if ( ! is_dir(APP_PATH.'routes') or $uri == '') return (is_dir(APP_PATH.'routes') and $uri != '') ? array_merge($this->load_nested_routes($uri), $base) : $base;
{
return $base;
} }
list($routes, $segments) = array(array(), explode('/', $uri)); /**
* Load the appropriate routes from the routes directory.
*
* This is done by working down the URI until we find the deepest
* possible matching route file.
*
* @param string $uri
* @return array
*/
private function load_nested_routes($uri)
{
$segments = explode('/', $uri);
foreach (array_reverse($segments, true) as $key => $value) foreach (array_reverse($segments, true) as $key => $value)
{ {
if (file_exists($path = ROUTE_PATH.implode('/', array_slice($segments, 0, $key + 1)).EXT)) if (file_exists($path = ROUTE_PATH.implode('/', array_slice($segments, 0, $key + 1)).EXT))
{ {
$routes = require $path; return require $path;
break;
} }
} }
return array_merge($routes, $base); return array();
} }
} }
\ No newline at end of file
...@@ -51,6 +51,10 @@ class Route { ...@@ -51,6 +51,10 @@ class Route {
{ {
$response = null; $response = null;
// The callback may be in array form, meaning it has attached filters or is named.
// However, the callback may also simply be a closure. If it is just a closure,
// we can execute it here. Otherwise, we will need to evaluate the route for any
// filters that need to be called.
if (is_callable($this->callback)) if (is_callable($this->callback))
{ {
$response = call_user_func_array($this->callback, $this->parameters); $response = call_user_func_array($this->callback, $this->parameters);
......
...@@ -23,16 +23,16 @@ class Router { ...@@ -23,16 +23,16 @@ class Router {
* *
* @param string $method * @param string $method
* @param string $uri * @param string $uri
* @param array $routes * @param Loader $loader
* @return void * @return void
*/ */
public function __construct($method, $uri, $routes = null) public function __construct($method, $uri, $loader)
{ {
// Put the request method and URI in route form. Routes begin with // 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.
$this->request = $method.' /'.trim($uri, '/'); $this->request = $method.' /'.trim($uri, '/');
$this->routes = (is_null($routes)) ? Loader::load($uri) : $routes; $this->routes = $loader->load($uri);
} }
/** /**
...@@ -55,6 +55,8 @@ class Router { ...@@ -55,6 +55,8 @@ class Router {
*/ */
public function route() public function route()
{ {
// Check for a literal route match first. If we find one, there is
// no need to spin through all of the routes.
if (isset($this->routes[$this->request])) if (isset($this->routes[$this->request]))
{ {
return Request::$route = new Route($this->request, $this->routes[$this->request]); return Request::$route = new Route($this->request, $this->routes[$this->request]);
......
...@@ -71,7 +71,7 @@ class URL { ...@@ -71,7 +71,7 @@ class URL {
*/ */
public static function to_route($name, $parameters = array(), $https = false) public static function to_route($name, $parameters = array(), $https = false)
{ {
if ( ! is_null($route = Route_Finder::find($name))) if ( ! is_null($route = Routing\Finder::find($name)))
{ {
$uris = explode(', ', key($route)); $uris = explode(', ', key($route));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment