Implemented the beforeRedirect callback in controller.

This commit is contained in:
Juan Basso 2011-01-19 22:46:31 -02:00
parent 6002f10b3b
commit e64e29964d
2 changed files with 62 additions and 8 deletions

View file

@ -644,15 +644,13 @@ class Controller extends Object {
if ($response === false) {
return;
}
if (is_array($response)) {
foreach ($response as $resp) {
if (is_array($resp) && isset($resp['url'])) {
extract($resp, EXTR_OVERWRITE);
} elseif ($resp !== null) {
$url = $resp;
}
}
extract($this->_parseBeforeRedirect($response, $url, $status, $exit), EXTR_OVERWRITE);
$response = $this->beforeRedirect($url, $status, $exit);
if ($response === false) {
return;
}
extract($this->_parseBeforeRedirect($response, $url, $status, $exit), EXTR_OVERWRITE);
if (function_exists('session_write_close')) {
session_write_close();
@ -679,6 +677,28 @@ class Controller extends Object {
}
}
/**
* Parse beforeRedirect Response
*
* @param mixed $response Response from beforeRedirect callback
* @param mixed $url The same value of beforeRedirect
* @param integer $status The same value of beforeRedirect
* @param boolean $exit The same value of beforeRedirect
* @return array Array with keys url, status and exit
*/
protected function _parseBeforeRedirect($response, $url, $status, $exit) {
if (is_array($response)) {
foreach ($response as $resp) {
if (is_array($resp) && isset($resp['url'])) {
extract($resp, EXTR_OVERWRITE);
} elseif ($resp !== null) {
$url = $resp;
}
}
}
return compact('url', 'status', 'exit');
}
/**
* Convenience and object wrapper method for CakeResponse::header().
*
@ -990,6 +1010,23 @@ class Controller extends Object {
public function beforeRender() {
}
/**
* The beforeRedirect method is invoked when the controller's redirect method is called but before any
* further action. If this method returns false the controller will not continue on to redirect the request.
* The $url, $status and $exit variables have same meaning as for the controller's method. You can also
* return a string which will be interpreted as the url to redirect to or return associative array with
* key 'url' and optionally 'status' and 'exit'.
*
* @param mixed $url A string or array-based URL pointing to another location within the app,
* 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
*/
public function beforeRedirect($url, $status = null, $exit = true) {
return true;
}
/**
* Called after the controller action is run and rendered.
*

View file

@ -850,6 +850,23 @@ class ControllerTest extends CakeTestCase {
$Controller->redirect('http://cakephp.org', 301);
}
/**
* test that beforeRedirect callback returnning false in controller
*
* @return void
*/
function testRedirectBeforeRedirectInController() {
$Controller = $this->getMock('Controller', array('_stop', 'beforeRedirect'));
$Controller->response = $this->getMock('CakeResponse', array('header'));
$Controller->Components = $this->getMock('ComponentCollection');
$Controller->expects($this->once())->method('beforeRedirect')
->will($this->returnValue(false));
$Controller->response->expects($this->never())->method('header');
$Controller->expects($this->never())->method('_stop');
$Controller->redirect('http://cakephp.org');
}
/**
* testMergeVars method
*