Commit cd310efd authored by Taylor Otwell's avatar Taylor Otwell

revised method of declaring filters on controllers.

parent 1d8dcd12
......@@ -7,18 +7,11 @@ use Laravel\Response;
abstract class Controller {
/**
* The "before" filters defined for the controller.
* The filters assigned to the controller.
*
* @var array
*/
public $before = array();
/**
* The "after" filters defined for the controller.
*
* @var array
*/
public $after = array();
protected $filters = array();
/**
* Handle the delegation of a route to a controller method.
......@@ -115,13 +108,11 @@ abstract class Controller {
// "before" filters return 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.
$response = Filter::run($this->filters('before'), array(), true);
$response = Filter::run($this->filters('before', $method), array(), true);
if (is_null($response))
{
$verb = strtolower(Request::method());
$response = call_user_func_array(array($this, "{$verb}_{$method}"), $parameters);
$response = call_user_func_array(array($this, "action_{$method}"), $parameters);
}
// The after filter and the framework expects all responses to
......@@ -129,7 +120,7 @@ abstract class Controller {
// return an instsance of Response, we will make on now.
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;
}
......@@ -145,15 +136,50 @@ abstract class Controller {
return $method == 'before' or $method == 'after' or strncmp($method, '_', 1) == 0;
}
/**
* 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.
*
* @param string $name
* @param string $method
* @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 {
*/
public static function run($filters, $parameters = array(), $override = false)
{
if (is_string($filters)) $filters = explode('|', $filters);
foreach ((array) $filters as $filter)
foreach (static::parse($filters) as $filter)
{
// Parameters may be passed into routes by specifying the list of
// parameters after a colon. If parameters are present, we will
......@@ -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