Browse Source

add DispatcherFilter Settings

Saleh Souzanchi 12 years ago
parent
commit
4639d3597c

+ 2 - 1
app/Config/bootstrap.php

@@ -80,8 +80,9 @@ 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' => $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
  *
  * ));

+ 7 - 2
lib/Cake/Routing/Dispatcher.php

@@ -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();

+ 16 - 0
lib/Cake/Routing/DispatcherFilter.php

@@ -35,6 +35,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`.
  * By default this class will attach `preDispatch` and `postDispatch` method respectively.

+ 52 - 1
lib/Cake/Test/Case/Routing/DispatcherTest.php

@@ -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';
@@ -497,6 +498,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
  *
  * @package       Cake.Test.Case.Routing
@@ -1226,6 +1260,23 @@ class DispatcherTest extends CakeTestCase {
 	}
 
 /**
+ * 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
  *
  * @expectedException MissingDispatcherFilterException
@@ -1673,4 +1724,4 @@ class DispatcherTest extends CakeTestCase {
 		}
 		return $filename;
 	}
-}
+}