add DispatcherFilter Settings

This commit is contained in:
Saleh Souzanchi 2013-12-18 06:54:27 +03:30
parent 54a65f98da
commit 4639d3597c
4 changed files with 77 additions and 4 deletions

View file

@ -80,6 +80,7 @@ Cache::config('default', array('engine' => 'File'));
*
* Configure::write('Dispatcher.filters', array(
* 'MyCacheFilter', // will use MyCacheFilter class from the Routing/Filter package in your app.
* 'MyCacheFilter' => array('prefix' => 'my_cache_'), // will use MyCacheFilter class from the Routing/Filter package in your app with settings array.
* 'MyPlugin.MyFilter', // will use MyFilter class from the Routing/Filter package in MyPlugin plugin.
* array('callable' => $aFunction, 'on' => 'before', 'priority' => 9), // A valid PHP callback type to be called on beforeDispatch
* array('callable' => $anotherMethod, 'on' => 'after'), // A valid PHP callback type to be called on afterDispatch

View file

@ -95,7 +95,12 @@ class Dispatcher implements CakeEventListener {
return;
}
foreach ($filters as $filter) {
foreach ($filters as $index => $filter) {
$settings = array();
if (is_array($filter) && !is_int($index)) {
$settings = $filter;
$filter = $index;
}
if (is_string($filter)) {
$filter = array('callable' => $filter);
}
@ -105,7 +110,7 @@ class Dispatcher implements CakeEventListener {
if (!class_exists($callable)) {
throw new MissingDispatcherFilterException($callable);
}
$manager->attach(new $callable);
$manager->attach(new $callable($settings));
} else {
$on = strtolower($filter['on']);
$options = array();

View file

@ -34,6 +34,22 @@ abstract class DispatcherFilter implements CakeEventListener {
*/
public $priority = 10;
/**
* Settings for this filter
*
* @var array
*/
public $settings = array();
/**
* Constructor.
*
* @param string $setting Configuration settings for the filter.
*/
public function __construct($settings = array()) {
$this->settings = Hash::merge($this->settings, $settings);
}
/**
* Returns the list of events this filter listens to.
* Dispatcher notifies 2 different events `Dispatcher.before` and `Dispatcher.after`.

View file

@ -17,6 +17,7 @@
*/
App::uses('Dispatcher', 'Routing');
App::uses('DispatcherFilter', 'Routing');
if (!class_exists('AppController', false)) {
require_once CAKE . 'Test' . DS . 'test_app' . DS . 'Controller' . DS . 'AppController.php';
@ -496,6 +497,39 @@ class TimesheetsController extends Controller {
}
/**
* TestFilterDispatcher class
*
* @package Cake.Test.Case.Routing
*/
class TestFilterDispatcher extends DispatcherFilter {
public $priority = 10;
/**
* TestFilterDispatcher::beforeDispatch()
*
* @param mixed $event
* @return CakeResponse|boolean
*/
public function beforeDispatch(CakeEvent $event) {
$event->stopPropagation();
$response = $event->data['request'];
$response->addParams(array('settings' => $this->settings));
return null;
}
/**
* TestFilterDispatcher::afterDispatch()
*
* @param mixed $event
* @return mixed boolean to stop the event dispatching or null to continue
*/
public function afterDispatch(CakeEvent $event) {
}
}
/**
* DispatcherTest class
*
@ -1225,6 +1259,23 @@ class DispatcherTest extends CakeTestCase {
$this->assertNull($dispatcher->controller);
}
/**
* Tests that it is possible to attach filter with config classes to the dispatch cycle
*
* @return void
*/
public function testDispatcherFilterSettings() {
Configure::write('Dispatcher.filters', array(
'TestFilterDispatcher' => array('service' => 'google.com')
));
$Dispatcher = new Dispatcher();
$url = new CakeRequest('some_pages/index');
$response = $this->getMock('CakeResponse');
$Dispatcher->dispatch($url, $response, array('return' => 1));
$settings = $url->param('settings');
$this->assertEquals($settings, array('service' => 'google.com'));
}
/**
* Tests that attaching an inexistent class as filter will throw an exception
*