Skip to content
Permalink
Browse files

Drastially change how beforeRedirect callbacks work.

Instead of relying on removed event system features, the beforeRedirect
callback now works differently. Each callback will receive the original
URL that the redirect was for and the response object. Any listener can
directly set the location header, statusCode or any other headers they
desire. The exit parameter cannot be altered and will most likely be
removed in the future as exiting from the controller makes a variety of
testing situations harder. This change also simplifies the testing
& behavior of the beforeRedirect callback.

If a beforeRedirect callback is stopped no redirection occurs as in the
past.
  • Loading branch information...
markstory committed Jul 16, 2013
1 parent cab1a39 commit 2eafc1fa202402c9c20550d63e318b771f4a19db
@@ -21,6 +21,7 @@
use Cake\Core\Configure;
use Cake\Error;
use Cake\Event\Event;
use Cake\Network\Response;
use Cake\Routing\Router;
use Cake\Utility\Inflector;
use Cake\Utility\Xml;
@@ -246,11 +247,10 @@ public function convertXml($xml) {
*
* @param Event $event The Controller.beforeRedirect event.
* @param string|array $url A string or array containing the redirect location
* @param integer|array $status HTTP Status for redirect
* @param boolean $exit
* @param Cake\Network\Response $response The response object.
* @return void
*/
public function beforeRedirect(Event $event, $url, $status = null, $exit = true) {
public function beforeRedirect(Event $event, $url, $response) {
if (!$this->request->is('ajax')) {
return;
}
@@ -265,13 +265,13 @@ public function beforeRedirect(Event $event, $url, $status = null, $exit = true)
$url = Router::url($url + array('base' => false));
}
if (!empty($status)) {
$statusCode = $this->response->httpCodes($status);
$statusCode = $response->httpCodes($status);
$code = key($statusCode);
$this->response->statusCode($code);
$response->statusCode($code);
}
$controller = $event->subject();
$this->response->body($controller->requestAction($url, array('return', 'bare' => false)));
$this->response->send();
$response->body($controller->requestAction($url, array('return', 'bare' => false)));
$response->send();
$this->_stop();
}
@@ -310,7 +310,7 @@ public function isAjax() {
public function isFlash() {
return $this->request->is('flash');
}
;
/**
* Returns true if the current request is over HTTPS, false otherwise.
*
@@ -738,32 +738,31 @@ public function redirect($url, $status = null, $exit = true) {
if (is_array($status)) {
extract($status, EXTR_OVERWRITE);
}
$event = new Event('Controller.beforeRedirect', $this, array($url, $status, $exit));
$response = $this->response;
$event = new Event('Controller.beforeRedirect', $this, [$response, $url, $status]);
$this->getEventManager()->dispatch($event);
if ($event->isStopped()) {
return;
}
$response = $event->result;
extract($this->_parseBeforeRedirect($response, $url, $status, $exit), EXTR_OVERWRITE);
if ($url !== null) {
$this->response->header('Location', Router::url($url, true));
$headers = $response->header();
if ($url !== null && empty($headers['Location'])) {
$response->header('Location', Router::url($url, true));
}
if (is_string($status)) {
$codes = array_flip($this->response->httpCodes());
$codes = array_flip($response->httpCodes());
if (isset($codes[$status])) {
$status = $codes[$status];
}
}
if ($status) {
$this->response->statusCode($status);
if ($status && $response->statusCode() === 200) {
$response->statusCode($status);
}
if ($exit) {
$this->response->send();
$response->send();
$this->_stop();
}
}
Oops, something went wrong.

0 comments on commit 2eafc1f

Please sign in to comment.
You can’t perform that action at this time.