Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implemented the beforeRedirect callback in controller.
  • Loading branch information
jrbasso committed Jan 20, 2011
1 parent 6002f10 commit e64e299
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 8 deletions.
53 changes: 45 additions & 8 deletions cake/libs/controller/controller.php
Expand Up @@ -644,15 +644,13 @@ public function redirect($url, $status = null, $exit = true) {
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();
Expand All @@ -679,6 +677,28 @@ public function redirect($url, $status = null, $exit = true) {
}
}

/**
* 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().
*
Expand Down Expand Up @@ -990,6 +1010,23 @@ public function beforeFilter() {
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.
*
Expand Down
17 changes: 17 additions & 0 deletions cake/tests/cases/libs/controller/controller.test.php
Expand Up @@ -850,6 +850,23 @@ function testRedirectBeforeRedirectModifyingParamsArrayReturn() {
$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
*
Expand Down

0 comments on commit e64e299

Please sign in to comment.