Commit eb956cc8 authored by Taylor Otwell's avatar Taylor Otwell

some routing enhancements - still a work in progress.

parent 7be960fb
<?php namespace Laravel; <?php namespace Laravel; use Laravel\Routing\Destination;
abstract class Controller { abstract class Controller implements Destination {
/** /**
* A stub method that will be called before every request to the controller. * The "before" filters defined for the controller.
* *
* If a value is returned by the method, it will be halt the request cycle * @var array
* and will be considered the response to the request. */
public $before = array();
/**
* The "after" filters defined for the controller.
* *
* @return mixed * @var array
*/ */
public function before() {} public $after = array();
/**
* Get an array of filter names defined for the destination.
*
* @param string $name
* @return array
*/
public function filters($name)
{
return $this->$name;
}
/** /**
* Magic Method to handle calls to undefined functions on the controller. * Magic Method to handle calls to undefined functions on the controller.
......
...@@ -39,8 +39,8 @@ if (Config::get('session.driver') !== '') ...@@ -39,8 +39,8 @@ if (Config::get('session.driver') !== '')
* be returned to the browser. * be returned to the browser.
*/ */
require SYS_PATH.'request'.EXT; require SYS_PATH.'request'.EXT;
require SYS_PATH.'routing/route'.EXT;
require SYS_PATH.'routing/router'.EXT; require SYS_PATH.'routing/router'.EXT;
require SYS_PATH.'routing/route'.EXT;
require SYS_PATH.'routing/loader'.EXT; require SYS_PATH.'routing/loader'.EXT;
require SYS_PATH.'routing/caller'.EXT; require SYS_PATH.'routing/caller'.EXT;
......
...@@ -4,28 +4,6 @@ use Closure; ...@@ -4,28 +4,6 @@ use Closure;
use Laravel\Response; use Laravel\Response;
use Laravel\Container; 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 { class Caller {
/** /**
...@@ -85,30 +63,14 @@ class Caller { ...@@ -85,30 +63,14 @@ class Caller {
// If a route returns a Delegate, it also means the route is delegating the // 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 // handling of the request to a controller method. So, we will pass the string
// to the route delegator, exploding on "@". // to the route delegator, exploding on "@".
if ($response instanceof Delegate) $response = $this->delegate($route, $response->destination); if ($response instanceof Delegate) return $this->delegate($route, $response->destination);
return $this->finish($route, $response); return $this->finish($route, $response);
} }
// If we get to this point, no response was returned from the filters or the route. // 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. // The 404 response will be returned to the browser instead of a blank screen.
return $this->finish($route, $this->container->resolve('laravel.response')->error('404')); return $this->finish($route, Response::error('404'));
}
/**
* Run the "before" filters for the route.
*
* 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(Route $route)
{
$before = array_merge(array('before'), $route->filters('before'));
return $this->filter($before, array(), true);
} }
/** /**
...@@ -139,12 +101,17 @@ class Caller { ...@@ -139,12 +101,17 @@ class Caller {
$controller->container = $this->container; $controller->container = $this->container;
// Again, as was the case with route closures, if the controller "before" method returns // 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 // 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. // will not be used to handle the request to the application.
$response = $controller->before(); $response = $this->before($controller);
if (is_null($response))
{
$response = call_user_func_array(array($controller, $method), $route->parameters);
}
return (is_null($response)) ? call_user_func_array(array($controller, $method), $route->parameters) : $response; return $this->finish($controller, $response);
} }
/** /**
...@@ -197,29 +164,47 @@ class Caller { ...@@ -197,29 +164,47 @@ class Caller {
* *
* The route response will be converted to a Response instance and the "after" filters will be run. * The route response will be converted to a Response instance and the "after" filters will be run.
* *
* @param Route $route * @param Destination $route
* @param mixed $response * @param mixed $response
* @return Response * @return Response
*/ */
protected function finish(Route $route, $response) protected function finish(Destination $destination, $response)
{ {
if ( ! $response instanceof Response) $response = new Response($response); if ( ! $response instanceof Response) $response = new Response($response);
$this->filter(array_merge($route->filters('after'), array('after')), array($response)); $this->filter(array_merge($destination->filters('after'), array('after')), array($response));
return $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. * Call a filter or set of filters.
* *
* @param array $filters * @param array|string $filters
* @param array $parameters * @param array $parameters
* @param bool $override * @param bool $override
* @return mixed * @return mixed
*/ */
protected function filter($filters, $parameters = array(), $override = false) protected function filter($filters, $parameters = array(), $override = false)
{ {
if (is_string($filters)) $filters = explode('|', $filters);
foreach ((array) $filters as $filter) foreach ((array) $filters as $filter)
{ {
// Parameters may be passed into routes by specifying the list of parameters after // Parameters may be passed into routes by specifying the list of parameters after
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
use Closure; use Closure;
use Laravel\Arr; use Laravel\Arr;
class Route { class Route implements Destination {
/** /**
* The route key, including request method and URI. * The route key, including request method and URI.
...@@ -126,9 +126,7 @@ class Route { ...@@ -126,9 +126,7 @@ class Route {
{ {
if (is_array($this->callback) and isset($this->callback[$name])) if (is_array($this->callback) and isset($this->callback[$name]))
{ {
$filters = $this->callback[$name]; return $this->callback[$name];
return (is_string($filters)) ? explode('|', $filters) : $filters;
} }
return array(); return array();
......
...@@ -2,6 +2,40 @@ ...@@ -2,6 +2,40 @@
use Laravel\Request; use Laravel\Request;
interface Destination {
/**
* Get an array of filter names defined for the destination.
*
* @param string $name
* @return array
*/
public function filters($name);
}
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 Router { class Router {
/** /**
......
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