Commit cd310efd by Taylor Otwell

revised method of declaring filters on controllers.

parent 1d8dcd12
...@@ -7,18 +7,11 @@ use Laravel\Response; ...@@ -7,18 +7,11 @@ use Laravel\Response;
abstract class Controller { abstract class Controller {
/** /**
* The "before" filters defined for the controller. * The filters assigned to the controller.
* *
* @var array * @var array
*/ */
public $before = array(); protected $filters = array();
/**
* The "after" filters defined for the controller.
*
* @var array
*/
public $after = array();
/** /**
* Handle the delegation of a route to a controller method. * Handle the delegation of a route to a controller method.
...@@ -115,13 +108,11 @@ abstract class Controller { ...@@ -115,13 +108,11 @@ abstract class Controller {
// "before" filters return a response, it will be considered the // "before" filters return a response, it will be considered the
// response to the request and the controller method will not be // response to the request and the controller method will not be
// used to handle the request to the application. // used to handle the request to the application.
$response = Filter::run($this->filters('before'), array(), true); $response = Filter::run($this->filters('before', $method), array(), true);
if (is_null($response)) if (is_null($response))
{ {
$verb = strtolower(Request::method()); $response = call_user_func_array(array($this, "action_{$method}"), $parameters);
$response = call_user_func_array(array($this, "{$verb}_{$method}"), $parameters);
} }
// The after filter and the framework expects all responses to // The after filter and the framework expects all responses to
...@@ -129,7 +120,7 @@ abstract class Controller { ...@@ -129,7 +120,7 @@ abstract class Controller {
// return an instsance of Response, we will make on now. // return an instsance of Response, we will make on now.
if ( ! $response instanceof Response) $response = new Response($response); if ( ! $response instanceof Response) $response = new Response($response);
Filter::run($this->filters('after'), array($response)); Filter::run($this->filters('after', $method), array($response));
return $response; return $response;
} }
...@@ -146,14 +137,49 @@ abstract class Controller { ...@@ -146,14 +137,49 @@ abstract class Controller {
} }
/** /**
* Set filters on the controller's methods.
*
* Generally, this method will be used in the controller's constructor.
*
* <code>
* // Set an "auth" before filter on the controller
* $this->filter('before', 'auth');
*
* // Set several filters on an explicit group of methods
* $this->filter('before', 'auth|csrf')->only(array('user', 'profile'));
* </code>
*
* @param string $name
* @param string|array $filters
* @return Filter_Collection
*/
public function filter($name, $filters)
{
$this->filters[] = new Filter_Collection($name, $filters);
return $this->filters[count($this->filters) - 1];
}
/**
* Get an array of filter names defined for the destination. * Get an array of filter names defined for the destination.
* *
* @param string $name * @param string $name
* @param string $method
* @return array * @return array
*/ */
protected function filters($name) protected function filters($name, $method)
{ {
return (array) $this->$name; $filters = array();
foreach ($this->filters as $filter)
{
if ($filter->name === $name and $filter->applies($method))
{
$filters = array_merge($filters, $filter->filters);
}
}
return array_unique($filters);
} }
/** /**
......
...@@ -30,9 +30,7 @@ class Filter { ...@@ -30,9 +30,7 @@ class Filter {
*/ */
public static function run($filters, $parameters = array(), $override = false) public static function run($filters, $parameters = array(), $override = false)
{ {
if (is_string($filters)) $filters = explode('|', $filters); foreach (static::parse($filters) as $filter)
foreach ((array) $filters as $filter)
{ {
// Parameters may be passed into routes by specifying the list of // Parameters may be passed into routes by specifying the list of
// parameters after a colon. If parameters are present, we will // parameters after a colon. If parameters are present, we will
...@@ -57,4 +55,127 @@ class Filter { ...@@ -57,4 +55,127 @@ class Filter {
} }
} }
/**
* Parse a string of filters into an array.
*
* @param string|array $filters
* @return array
*/
public static function parse($filters)
{
return (is_string($filters)) ? explode('|', $filters) : (array) $filters;
}
}
class Filter_Collection {
/**
* The event being filtered.
*
* @var string
*/
public $name;
/**
* The included controller methods.
*
* @var array
*/
public $only = array();
/**
* The excluded controller methods.
*
* @var array
*/
public $except = array();
/**
* The filters contained by the collection.
*
* @var string|array
*/
public $filters = array();
/**
* Create a new filter collection instance.
*
* @param string $name
* @param string|array $filters
*/
public function __construct($name, $filters)
{
$this->name = $name;
$this->filters = Filter::parse($filters);
}
/**
* Determine if this collection's filters apply to a given method.
*
* @param string $method
* @return bool
*/
public function applies($method)
{
if (count($this->only) > 0 and ! in_array($method, $this->only))
{
return false;
}
if (count($this->except) > 0 and in_array($method, $this->except))
{
return false;
}
return true;
}
/**
* Set the excluded controller methods.
*
* When methods are excluded, the collection's filters will be run for each
* controller method except those explicitly specified via this method.
*
* <code>
* // Specify a filter for all methods except "index"
* $this->filter('before', 'auth')->except('index');
*
* // Specify a filter for all methods except "index" and "home"
* $this->filter('before', 'auth')->except(array('index', 'home'));
* </code>
*
* @param array $methods
* @return Filter_Collection
*/
public function except($methods)
{
$this->except = (array) $methods;
return $this;
}
/**
* Set the included controller methods.
*
* This method is the inverse of the "except" methods. The methods specified
* via this method are the only controller methods on which the collection's
* filters will be run.
*
* <code>
* // Specify a filter for only the "index" method
* $this->filter('before', 'auth')->only('index');
*
* // Specify a filter for only the "index" and "home" methods
* $this->filter('before', 'auth')->only(array('index', 'home'));
* </code>
*
* @param array $methods
* @return Filter_Collection
*/
public function only($methods)
{
$this->only = (array) $methods;
return $this;
}
} }
\ No newline at end of file
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