diff --git a/src/Controller/Component/AuthComponent.php b/src/Controller/Component/AuthComponent.php index fec0e948c1d..91b4532e55f 100644 --- a/src/Controller/Component/AuthComponent.php +++ b/src/Controller/Component/AuthComponent.php @@ -349,7 +349,7 @@ protected function _unauthenticated(Controller $controller) } if (!empty($this->_config['ajaxLogin'])) { - $controller->viewPath = 'Element'; + $controller->getview()->viewPath = 'Element'; $response = $controller->render( $this->_config['ajaxLogin'], $this->RequestHandler->ajaxLayout diff --git a/src/Controller/Component/RequestHandlerComponent.php b/src/Controller/Component/RequestHandlerComponent.php index 93560c1135c..432a56e8b59 100644 --- a/src/Controller/Component/RequestHandlerComponent.php +++ b/src/Controller/Component/RequestHandlerComponent.php @@ -194,19 +194,8 @@ protected function _setExtension($request, $response) * The startup method of the RequestHandler enables several automatic behaviors * related to the detection of certain properties of the HTTP request, including: * - * - If Router::extensions() is enabled, the layout and template type are - * switched based on the parsed extension or Accept-Type header. For example, if `controller/action.xml` - * is requested, the view path becomes `app/View/Controller/xml/action.ctp`. Also if - * `controller/action` is requested with `Accept-Type: application/xml` in the headers - * the view path will become `app/View/Controller/xml/action.ctp`. Layout and template - * types will only switch to mime-types recognized by Cake\Network\Response. If you need to declare - * additional mime-types, you can do so using Cake\Network\Response::type() in your controller's beforeFilter() - * method. - * - If a helper with the same name as the extension exists, it is added to the controller. - * - If the extension is of a type that RequestHandler understands, it will set that - * Content-type in the response header. - * - If the XML data is POSTed, the data is parsed into an XML object, which is assigned - * to the $data property of the controller, which can then be saved to a model object. + * If the XML data is POSTed, the data is parsed into an XML object, which is assigned + * to the $data property of the controller, which can then be saved to a model object. * * @param Event $event The startup event that was fired. * @return void @@ -227,16 +216,6 @@ public function startup(Event $event) } $request->params['isAjax'] = $this->request->is('ajax'); - $isRecognized = ( - !in_array($this->ext, ['html', 'htm']) && - $this->response->getMimeType($this->ext) - ); - - if (!empty($this->ext) && $isRecognized) { - $this->renderAs($controller, $this->ext); - } elseif (empty($this->ext) || in_array($this->ext, ['html', 'htm'])) { - $this->respondAs('html', ['charset' => Configure::read('App.encoding')]); - } foreach ($this->_inputTypeMap as $type => $handler) { if ($this->requestedWith($type)) { @@ -304,14 +283,39 @@ public function beforeRedirect(Event $event, $url, Response $response) * render process is skipped. And the client will get a blank response with a * "304 Not Modified" header. * + * - If Router::extensions() is enabled, the layout and template type are + * switched based on the parsed extension or Accept-Type header. For example, + * if `controller/action.xml` is requested, the view path becomes + * `app/View/Controller/xml/action.ctp`. Also if `controller/action` is + * requested with `Accept-Type: application/xml` in the headers the view + * path will become `app/View/Controller/xml/action.ctp`. Layout and template + * types will only switch to mime-types recognized by Cake\Network\Response. + * If you need to declare additional mime-types, you can do so using + * Cake\Network\Response::type() in your controller's beforeFilter() method. + * - If a helper with the same name as the extension exists, it is added to + * the controller. + * - If the extension is of a type that RequestHandler understands, it will + * set that Content-type in the response header. + * * @param Event $event The Controller.beforeRender event. * @return bool false if the render process should be aborted */ public function beforeRender(Event $event) { - $response = $this->response; - $request = $this->request; - if ($this->_config['checkHttpCache'] && $response->checkNotModified($request)) { + $isRecognized = ( + !in_array($this->ext, ['html', 'htm']) && + $this->response->getMimeType($this->ext) + ); + + if (!empty($this->ext) && $isRecognized) { + $this->renderAs($event->subject(), $this->ext); + } elseif (empty($this->ext) || in_array($this->ext, ['html', 'htm'])) { + $this->respondAs('html', ['charset' => Configure::read('App.encoding')]); + } + + if ($this->_config['checkHttpCache'] && + $this->response->checkNotModified($this->request) + ) { return false; } } @@ -554,17 +558,17 @@ public function renderAs(Controller $controller, $type, array $options = []) $controller->viewClass = $viewClass; } else { if (empty($this->_renderType)) { - $controller->viewPath .= DS . $type; + $controller->getView()->viewPath .= DS . $type; } else { - $controller->viewPath = preg_replace( + $controller->getView()->viewPath = preg_replace( "/([\/\\\\]{$this->_renderType})$/", DS . $type, - $controller->viewPath + $controller->getView()->viewPath ); } $this->_renderType = $type; - $controller->layoutPath = $type; + $controller->getView()->layoutPath = $type; } $response = $this->response; diff --git a/tests/TestCase/Controller/Component/RequestHandlerComponentTest.php b/tests/TestCase/Controller/Component/RequestHandlerComponentTest.php index dbbf4e0ddcc..8cae7efc25b 100644 --- a/tests/TestCase/Controller/Component/RequestHandlerComponentTest.php +++ b/tests/TestCase/Controller/Component/RequestHandlerComponentTest.php @@ -71,7 +71,7 @@ protected function _init() $request = new Request('controller_posts/index'); $response = $this->getMock('Cake\Network\Response', ['_sendHeader', 'stop']); $this->Controller = new RequestHandlerTestController($request, $response); - $this->RequestHandler = new RequestHandlerComponent($this->Controller->components()); + $this->RequestHandler = $this->Controller->components()->load('RequestHandler'); $this->request = $request; Router::scope('/', function ($routes) { @@ -355,6 +355,8 @@ public function testAutoAjaxLayout() $this->request->env('HTTP_X_REQUESTED_WITH', 'XMLHttpRequest'); $this->RequestHandler->initialize([]); $this->RequestHandler->startup($event); + $event = new Event('Controller.beforeRender', $this->Controller); + $this->RequestHandler->beforeRender($event); $this->assertEquals($this->Controller->viewClass, 'Cake\View\AjaxView'); $view = $this->Controller->createView(); $this->assertEquals('ajax', $view->layout); @@ -379,6 +381,8 @@ public function testJsonViewLoaded() $event = new Event('Controller.startup', $this->Controller); $this->RequestHandler->initialize([]); $this->RequestHandler->startup($event); + $event = new Event('Controller.beforeRender', $this->Controller); + $this->RequestHandler->beforeRender($event); $this->assertEquals('Cake\View\JsonView', $this->Controller->viewClass); $view = $this->Controller->createView(); $this->assertEquals('json', $view->layoutPath); @@ -398,6 +402,8 @@ public function testXmlViewLoaded() $event = new Event('Controller.startup', $this->Controller); $this->RequestHandler->initialize([]); $this->RequestHandler->startup($event); + $event = new Event('Controller.beforeRender', $this->Controller); + $this->RequestHandler->beforeRender($event); $this->assertEquals('Cake\View\XmlView', $this->Controller->viewClass); $view = $this->Controller->createView(); $this->assertEquals('xml', $view->layoutPath); @@ -417,6 +423,8 @@ public function testAjaxViewLoaded() $event = new Event('Controller.startup', $this->Controller); $this->RequestHandler->initialize([]); $this->RequestHandler->startup($event); + $event = new Event('Controller.beforeRender', $this->Controller); + $this->RequestHandler->beforeRender($event); $this->assertEquals('Cake\View\AjaxView', $this->Controller->viewClass); $view = $this->Controller->createView(); $this->assertEquals('ajax', $view->layout); @@ -426,7 +434,7 @@ public function testAjaxViewLoaded() * test configured extension but no view class set. * * @return void - * @triggers Controller.startup $this->Controller + * @triggers Controller.beforeRender $this->Controller */ public function testNoViewClassExtension() { @@ -435,23 +443,27 @@ public function testNoViewClassExtension() $event = new Event('Controller.startup', $this->Controller); $this->RequestHandler->initialize([]); $this->RequestHandler->startup($event); - $this->assertEquals('RequestHandlerTest' . DS . 'csv', $this->Controller->viewPath); - $this->assertEquals('csv', $this->Controller->layoutPath); + $this->Controller->eventManager()->on('Controller.beforeRender', function() { + return $this->Controller->response; + }); + $this->Controller->render(); + $this->assertEquals('RequestHandlerTest' . DS . 'csv', $this->Controller->getView()->viewPath); + $this->assertEquals('csv', $this->Controller->getView()->layoutPath); } /** * testStartupCallback method * * @return void - * @triggers Controller.startup $this->Controller + * @triggers Controller.beforeRender $this->Controller */ public function testStartupCallback() { - $event = new Event('Controller.startup', $this->Controller); + $event = new Event('Controller.beforeRender', $this->Controller); $_SERVER['REQUEST_METHOD'] = 'PUT'; $_SERVER['CONTENT_TYPE'] = 'application/xml'; $this->Controller->request = $this->getMock('Cake\Network\Request', ['_readInput']); - $this->RequestHandler->startup($event); + $this->RequestHandler->beforeRender($event); $this->assertTrue(is_array($this->Controller->request->data)); $this->assertFalse(is_object($this->Controller->request->data)); } @@ -598,9 +610,9 @@ public function testRenderAs() $this->RequestHandler->renderAs($this->Controller, 'rss'); $this->assertTrue(in_array('Rss', $this->Controller->helpers)); - $this->Controller->viewPath = 'request_handler_test\\rss'; + $this->Controller->getView()->viewPath = 'request_handler_test\\rss'; $this->RequestHandler->renderAs($this->Controller, 'js'); - $this->assertEquals('request_handler_test' . DS . 'js', $this->Controller->viewPath); + $this->assertEquals('request_handler_test' . DS . 'js', $this->Controller->getView()->viewPath); } /** @@ -686,13 +698,18 @@ public function testRespondAsWithAttachment() */ public function testRenderAsCalledTwice() { + $this->Controller->eventManager()->on('Controller.beforeRender', function(\Cake\Event\Event $e) { + return $e->subject()->response; + }); + $this->Controller->render(); + $this->RequestHandler->renderAs($this->Controller, 'print'); - $this->assertEquals('RequestHandlerTest' . DS . 'print', $this->Controller->viewPath); - $this->assertEquals('print', $this->Controller->layoutPath); + $this->assertEquals('RequestHandlerTest' . DS . 'print', $this->Controller->getView()->viewPath); + $this->assertEquals('print', $this->Controller->getView()->layoutPath); $this->RequestHandler->renderAs($this->Controller, 'js'); - $this->assertEquals('RequestHandlerTest' . DS . 'js', $this->Controller->viewPath); - $this->assertEquals('js', $this->Controller->layoutPath); + $this->assertEquals('RequestHandlerTest' . DS . 'js', $this->Controller->getView()->viewPath); + $this->assertEquals('js', $this->Controller->getView()->layoutPath); } /**