Browse Source

Migrating the beforeRedirect callback to the CakeEventManager, reorganizing how events are triggered in controller

Jose Lorenzo Rodriguez 14 years ago
parent
commit
7fdc1cc8d4

+ 1 - 1
lib/Cake/Controller/ComponentCollection.php

@@ -121,7 +121,7 @@ class ComponentCollection extends ObjectCollection implements CakeEventListener
 			'Controller.startup' => array('callable' => 'trigger'),
 			'Controller.beforeRender' => array('callable' => 'trigger'),
 			'Controller.beforeRedirect' => array('callable' => 'trigger'),
-			'Controller.shutdown' => array('callable' => 'trigger', 'priority' => 9),
+			'Controller.shutdown' => array('callable' => 'trigger'),
 		);
 	}
 }

+ 14 - 16
lib/Cake/Controller/Controller.php

@@ -589,8 +589,9 @@ class Controller extends Object implements CakeEventListener {
  */
 	public function implementedEvents() {
 		return array(
-			'Controller.startup' => 'beforeFilter',
+			'Controller.initialize' => 'beforeFilter',
 			'Controller.beforeRender' => 'beforeRender',
+			'Controller.beforeRedirect' => array('callable' => 'beforeRedirect', 'passParams' => true),
 			'Controller.shutdown' => 'afterFilter'
 		);
 	}
@@ -625,8 +626,8 @@ class Controller extends Object implements CakeEventListener {
 	public function getEventManager() {
 		if (empty($this->_eventManager)) {
 			$this->_eventManager = new CakeEventManager();
-			$this->_eventManager->attach($this);
 			$this->_eventManager->attach($this->Components);
+			$this->_eventManager->attach($this);
 		}
 		return $this->_eventManager;
 	}
@@ -730,21 +731,16 @@ class Controller extends Object implements CakeEventListener {
 		if (is_array($status)) {
 			extract($status, EXTR_OVERWRITE);
 		}
-		$response = $this->Components->trigger(
-			'beforeRedirect',
-			array(&$this, $url, $status, $exit),
-			array('break' => true, 'breakOn' => false, 'collectReturn' => true)
-		);
+		$event = new CakeEvent('Controller.beforeRedirect', $this, array($url, $status, $exit));
+		//TODO: Remove the following two lines when the events are fully migrated to the CakeEventManager
+		$event->breakOn = false;
+		$event->collectReturn = true;
+		$this->getEventManager()->dispatch($event);
 
-		if ($response === false) {
-			return;
-		}
-		extract($this->_parseBeforeRedirect($response, $url, $status, $exit), EXTR_OVERWRITE);
-
-		$response = $this->beforeRedirect($url, $status, $exit);
-		if ($response === false) {
+		if ($event->isStopped()) {
 			return;
 		}
+		$response = $event->result;
 		extract($this->_parseBeforeRedirect($response, $url, $status, $exit), EXTR_OVERWRITE);
 
 		if (function_exists('session_write_close')) {
@@ -1094,11 +1090,13 @@ class Controller extends Object implements CakeEventListener {
  *     or an absolute URL
  * @param integer $status Optional HTTP status code (eg: 404)
  * @param boolean $exit If true, exit() will be called after the redirect
- * @return boolean
+ * @return mixed
+ *   false to stop redirection event,
+ *   string controllers a new redirection url or
+ *   array with the keys url, status and exit to be used by the redirect method.
  * @link http://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
  */
 	public function beforeRedirect($url, $status = null, $exit = true) {
-		return true;
 	}
 
 /**

+ 7 - 7
lib/Cake/Test/Case/Controller/ControllerTest.php

@@ -712,7 +712,7 @@ class ControllerTest extends CakeTestCase {
 		$Controller = new Controller(null);
 		$Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
 
-		$Controller->Components = $this->getMock('ComponentCollection');
+		$Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
 
 		$Controller->response->expects($this->once())->method('statusCode')
 			->with($code);
@@ -733,7 +733,7 @@ class ControllerTest extends CakeTestCase {
 		$Controller = new Controller(null);
 		$Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
 
-		$Controller->Components = $this->getMock('ComponentCollection');
+		$Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
 
 		$Controller->response->expects($this->once())->method('statusCode')
 			->with($code);
@@ -753,7 +753,7 @@ class ControllerTest extends CakeTestCase {
 	public function testRedirectTriggeringComponentsReturnNull() {
 		$Controller = new Controller(null);
 		$Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
-		$Controller->Components = $this->getMock('ComponentCollection');
+		$Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
 
 		$Controller->Components->expects($this->once())->method('trigger')
 			->will($this->returnValue(null));
@@ -775,7 +775,7 @@ class ControllerTest extends CakeTestCase {
 	public function testRedirectBeforeRedirectModifyingParams() {
 		$Controller = new Controller(null);
 		$Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
-		$Controller->Components = $this->getMock('ComponentCollection');
+		$Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
 
 		$Controller->Components->expects($this->once())->method('trigger')
 			->will($this->returnValue(array('http://book.cakephp.org')));
@@ -797,7 +797,7 @@ class ControllerTest extends CakeTestCase {
 	public function testRedirectBeforeRedirectModifyingParamsArrayReturn() {
 		$Controller = $this->getMock('Controller', array('header', '_stop'));
 		$Controller->response = $this->getMock('CakeResponse');
-		$Controller->Components = $this->getMock('ComponentCollection');
+		$Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
 
 		$return = array(
 			array(
@@ -812,7 +812,7 @@ class ControllerTest extends CakeTestCase {
 		$Controller->Components->expects($this->once())->method('trigger')
 			->will($this->returnValue($return));
 
-		$Controller->response->expects($this->at(0))->method('header')
+		$Controller->response->expects($this->once())->method('header')
 			->with('Location', 'http://example.com/test/2');
 
 		$Controller->response->expects($this->at(1))->method('statusCode')
@@ -830,7 +830,7 @@ class ControllerTest extends CakeTestCase {
 	public function testRedirectBeforeRedirectInController() {
 		$Controller = $this->getMock('Controller', array('_stop', 'beforeRedirect'));
 		$Controller->response = $this->getMock('CakeResponse', array('header'));
-		$Controller->Components = $this->getMock('ComponentCollection');
+		$Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
 
 		$Controller->expects($this->once())->method('beforeRedirect')
 			->will($this->returnValue(false));

+ 4 - 2
lib/Cake/Utility/ObjectCollection.php

@@ -103,8 +103,10 @@ abstract class ObjectCollection {
 				$params = array($event->subject());
 			}
 			//TODO: Temporary BC check, while we move all the triggers system into the CakeEventManager
-			if (isset($event->modParams)) {
-				$options['modParams'] = $event->modParams;
+			foreach (array('breakOn', 'collectReturn', 'modParams') as $opt) {
+				if (isset($event->{$opt})) {
+					$options[$opt] = $event->{$opt};
+				}
 			}
 			$callback = array_pop(explode('.', $event->name()));
 		}