In Lithium itself, when creating a method that can be filtered, a method is implemented as a
closure and is passed to either
Object::_filter() or StaticObject::_filter(). Each object internally maintains its own list
of filters, which are applied in these methods and passed to Filters::run().
When implementing a custom filter system outside of Lithium, you can create your own list of
filters, and pass it to $options['data'] in the run() method.
When creating a filter to apply to a method, you need the name of the method you want to call,
along with a **closure**, that defines what you want the filter to do. All filters take the same
3 parameters: $self,$params, and $chain.
- $self: If the filter is applied on an object instance, then $self will be that instance. If
applied to a static class, then $self will be a string containing the fully-namespaced class
name.
- $params: Contains an associative array of the parameters that are passed into the method. You
can modify or inspect these parameters before allowing the method to continue.
- $chain: Finally, $chain contains the list of filters in line to be executed (as an
instance of the Filters class). At the bottom of $chain is the method itself. This is why
most filters contain a line that looks like this:
{{{return $chain->next($self, $params, $chain);}}}
This passes control to the next filter in the chain, and finally, to the method itself. This
allows you to interact with the return value as well as the parameters.
Within the framework, you can call applyFilter() on any object (static or instantiated) and
pass the name of the method you would like to filter, along with the filter itself. For example:
{{{use \lithium\action\Dispatcher;
Dispatcher::applyFilter('run', function($self, $params, $chain) {
Custom pre-dispatch logic goes here
$response = $chain->next($self, $params, $chain);
$response now contains a Response object with the result of the dispatched request,
and can be modified as appropriate
...
return $response;
});}}}
The logic in the closure will now be executed on every call to Dispatcher::run(), and
$response will always be modified by any custom logic present before being returned from
run().