Browse Source

Deprecate request/response on Component.

Start deprecating the request/response properties on components. By not
storing references to PSR7 objects all over the place, we can migrate to
using immutable methods more easily in the future. I don't think it will
be easy to start using the immutable methods _now_ as user-land
components could easily be referencing old public properties.
Mark Story 9 years ago
parent
commit
e6d4ea5561

+ 14 - 0
src/Controller/Component.php

@@ -66,6 +66,8 @@ class Component implements EventListenerInterface
      * Request object
      *
      * @var \Cake\Http\ServerRequest
+     * @deprecated 3.4.0 Storing references to the request is deprecated. Use Component::getController()
+     *   or callback $event->subject() to access the controller & request instead.
      */
     public $request;
 
@@ -73,6 +75,8 @@ class Component implements EventListenerInterface
      * Response object
      *
      * @var \Cake\Network\Response
+     * @deprecated 3.4.0 Storing references to the response is deprecated. Use Component::getController()
+     *   or callback $event->subject() to access the controller & response instead.
      */
     public $response;
 
@@ -130,6 +134,16 @@ class Component implements EventListenerInterface
     }
 
     /**
+     * Get the controller this component is bound to.
+     *
+     * @return \Cake\Controller\Controller The bound controller.
+     */
+    public function getController()
+    {
+        return $this->_registry->getController();
+    }
+
+    /**
      * Constructor hook method.
      *
      * Implement this method to avoid having to overwrite

+ 33 - 29
src/Controller/Component/RequestHandlerComponent.php

@@ -41,9 +41,8 @@ class RequestHandlerComponent extends Component
 {
 
     /**
-     * Determines whether or not callbacks will be fired on this component
-     *
      * @var bool
+     * @deprecated 3.4.0 Unused. Will be removed in 4.0.0
      */
     public $enabled = true;
 
@@ -51,6 +50,7 @@ class RequestHandlerComponent extends Component
      * Holds the reference to Controller::$response
      *
      * @var \Cake\Network\Response
+     * @deprecated 3.4.0 Will be removed in 4.0.0
      */
     public $response;
 
@@ -128,20 +128,12 @@ class RequestHandlerComponent extends Component
     }
 
     /**
-     * Checks to see if a specific content type has been requested and sets RequestHandler::$ext
-     * accordingly. Checks the following in order: 1. The '_ext' value parsed by the Router. 2. A specific
-     * AJAX type request indicated by the presence of a header. 3. The Accept header. With the exception
-     * of an AJAX request indicated using the second header based method above, the type must have
-     * been configured in {@link Cake\Routing\Router}.
-     *
      * @param array $config The config data.
      * @return void
-     * @see \Cake\Routing\Router::extensions()
+     * @deprecated 3.4.0 Unused. To be removed in 4.0.0
      */
     public function initialize(array $config)
     {
-        $controller = $this->_registry->getController();
-        $this->response =& $controller->response;
     }
 
     /**
@@ -198,12 +190,13 @@ class RequestHandlerComponent extends Component
     {
         $controller = $event->subject();
         $request = $controller->request;
+        $response = $controller->response;
 
         if ($request->param('_ext')) {
             $this->ext = $request->param('_ext');
         }
         if (!$this->ext || in_array($this->ext, ['html', 'htm'])) {
-            $this->_setExtension($request, $this->response);
+            $this->_setExtension($request, $response);
         }
 
         $request->params['isAjax'] = $request->is('ajax');
@@ -278,6 +271,7 @@ class RequestHandlerComponent extends Component
             list($url, $querystr) = explode('?', $url, 2);
             parse_str($querystr, $query);
         }
+        /* @var \Cake\Controller\Controller $controller */
         $controller = $event->subject();
         $response->body($controller->requestAction($url, [
             'return',
@@ -286,7 +280,7 @@ class RequestHandlerComponent extends Component
                 'REQUEST_METHOD' => 'GET'
             ],
             'query' => $query,
-            'cookies' => $request->cookies
+            'cookies' => $request->getCookieParams()
         ]));
 
         return $response->withStatus(200);
@@ -317,21 +311,24 @@ class RequestHandlerComponent extends Component
      */
     public function beforeRender(Event $event)
     {
+        /* @var \Cake\Controller\Controller $controller */
+        $controller = $event->subject();
+        $response = $controller->response;
+        $request = $controller->request;
+
         $isRecognized = (
             !in_array($this->ext, ['html', 'htm']) &&
-            $this->response->getMimeType($this->ext)
+            $response->getMimeType($this->ext)
         );
 
         if ($this->ext && $isRecognized) {
-            /* @var \Cake\Controller\Controller $controller */
-            $controller = $event->subject();
             $this->renderAs($controller, $this->ext);
         } else {
-            $this->response->charset(Configure::read('App.encoding'));
+            $response->charset(Configure::read('App.encoding'));
         }
 
         if ($this->_config['checkHttpCache'] &&
-            $this->response->checkNotModified($this->request)
+            $response->checkNotModified($request)
         ) {
             return false;
         }
@@ -418,8 +415,9 @@ class RequestHandlerComponent extends Component
      */
     public function accepts($type = null)
     {
-        $request = $this->request;
-        $response = $this->response;
+        $controller = $this->getController();
+        $request = $controller->request;
+        $response = $controller->response;
         $accepted = $request->accepts();
 
         if (!$type) {
@@ -452,7 +450,10 @@ class RequestHandlerComponent extends Component
      */
     public function requestedWith($type = null)
     {
-        $request = $this->request;
+        $controller = $this->getController();
+        $request = $controller->request;
+        $response = $controller->response;
+
         if (!$request->is('post') &&
             !$request->is('put') &&
             !$request->is('patch') &&
@@ -471,7 +472,6 @@ class RequestHandlerComponent extends Component
         }
 
         list($contentType) = explode(';', $request->contentType());
-        $response = $this->response;
         if ($type === null) {
             return $response->mapType($contentType);
         }
@@ -498,8 +498,9 @@ class RequestHandlerComponent extends Component
      */
     public function prefers($type = null)
     {
-        $request = $this->request;
-        $response = $this->response;
+        $controller = $this->getController();
+        $request = $controller->request;
+        $response = $controller->response;
         $acceptRaw = $request->parseAccept();
 
         if (empty($acceptRaw)) {
@@ -597,7 +598,7 @@ class RequestHandlerComponent extends Component
             $builder->layoutPath($type);
         }
 
-        $response = $this->response;
+        $response = $controller->response;
         if ($response->getMimeType($type)) {
             $this->respondAs($type, $options);
         }
@@ -630,7 +631,10 @@ class RequestHandlerComponent extends Component
         $options += $defaults;
 
         $cType = $type;
-        $response = $this->response;
+        $controller = $this->getController();
+        $response = $controller->response;
+        $request = $controller->request;
+
         if (strpos($type, '/') === false) {
             $cType = $response->getMimeType($type);
         }
@@ -649,7 +653,7 @@ class RequestHandlerComponent extends Component
         if (!$type) {
             return false;
         }
-        if (!$this->request->param('requested')) {
+        if (!$request->param('requested')) {
             $response->type($cType);
         }
         if (!empty($options['charset'])) {
@@ -670,7 +674,7 @@ class RequestHandlerComponent extends Component
      */
     public function responseType()
     {
-        $response = $this->response;
+        $response = $this->getController()->response;
 
         return $response->mapType($response->type());
     }
@@ -688,7 +692,7 @@ class RequestHandlerComponent extends Component
         if (is_array($alias)) {
             return array_map([$this, 'mapAlias'], $alias);
         }
-        $response = $this->response;
+        $response = $this->getController()->response;
         $type = $response->getMimeType($alias);
         if ($type) {
             if (is_array($type)) {

+ 61 - 62
tests/TestCase/Controller/Component/RequestHandlerComponentTest.php

@@ -650,16 +650,16 @@ class RequestHandlerComponentTest extends TestCase
             ->method('parseAccept')
             ->will($this->returnValue(['1.0' => ['application/xml']]));
 
-        $this->RequestHandler->response = $this->getMockBuilder('Cake\Network\Response')
+        $this->Controller->response = $this->getMockBuilder('Cake\Network\Response')
             ->setMethods(['type', 'download', 'charset'])
             ->getMock();
-        $this->RequestHandler->response->expects($this->at(0))
+        $this->Controller->response->expects($this->at(0))
             ->method('type')
             ->with('application/xml');
-        $this->RequestHandler->response->expects($this->at(1))
+        $this->Controller->response->expects($this->at(1))
             ->method('charset')
             ->with('UTF-8');
-        $this->RequestHandler->response->expects($this->at(2))
+        $this->Controller->response->expects($this->at(2))
             ->method('download')
             ->with('myfile.xml');
 
@@ -675,12 +675,12 @@ class RequestHandlerComponentTest extends TestCase
      */
     public function testRespondAs()
     {
-        $this->RequestHandler->response = $this->getMockBuilder('Cake\Network\Response')
+        $this->Controller->response = $this->getMockBuilder('Cake\Network\Response')
             ->setMethods(['type'])
             ->getMock();
-        $this->RequestHandler->response->expects($this->at(0))->method('type')
+        $this->Controller->response->expects($this->at(0))->method('type')
             ->with('application/json');
-        $this->RequestHandler->response->expects($this->at(1))->method('type')
+        $this->Controller->response->expects($this->at(1))->method('type')
             ->with('text/xml');
 
         $result = $this->RequestHandler->respondAs('json');
@@ -700,20 +700,20 @@ class RequestHandlerComponentTest extends TestCase
             ->setMethods(['_header'])
             ->setConstructorArgs([$this->Controller->components()])
             ->getMock();
-        $this->RequestHandler->response = $this->getMockBuilder('Cake\Network\Response')
+        $this->Controller->response = $this->getMockBuilder('Cake\Network\Response')
             ->setMethods(['type', 'download'])
             ->getMock();
-        $this->RequestHandler->request = $this->getMockBuilder('Cake\Network\Request')
+        $this->Controller->request = $this->getMockBuilder('Cake\Network\Request')
             ->setMethods(['parseAccept'])
             ->getMock();
 
-        $this->RequestHandler->request->expects($this->once())
+        $this->Controller->request->expects($this->once())
             ->method('parseAccept')
             ->will($this->returnValue(['1.0' => ['application/xml']]));
 
-        $this->RequestHandler->response->expects($this->once())->method('download')
+        $this->Controller->response->expects($this->once())->method('download')
             ->with('myfile.xml');
-        $this->RequestHandler->response->expects($this->once())->method('type')
+        $this->Controller->response->expects($this->once())->method('type')
             ->with('application/xml');
 
         $result = $this->RequestHandler->respondAs('xml', ['attachment' => 'myfile.xml']);
@@ -821,7 +821,7 @@ class RequestHandlerComponentTest extends TestCase
             ->with('mobile')
             ->will($this->returnValue(true));
 
-        $this->RequestHandler->request = $request;
+        $this->Controller->request = $request;
         $this->assertTrue($this->RequestHandler->isMobile());
     }
 
@@ -906,18 +906,18 @@ class RequestHandlerComponentTest extends TestCase
         Router::connect('/:controller/:action');
         $event = new Event('Controller.beforeRedirect', $this->Controller);
 
-        $this->Controller->RequestHandler = new RequestHandlerComponent($this->Controller->components());
+        $this->RequestHandler = new RequestHandlerComponent($this->Controller->components());
         $this->Controller->request = $this->getMockBuilder('Cake\Network\Request')
             ->setMethods(['is'])
             ->getMock();
         $this->Controller->response = $this->getMockBuilder('Cake\Network\Response')
             ->setMethods(['_sendHeader', 'stop'])
             ->getMock();
-        $this->Controller->RequestHandler->request = $this->Controller->request;
-        $this->Controller->RequestHandler->response = $this->Controller->response;
-        $this->Controller->request->expects($this->any())->method('is')->will($this->returnValue(true));
+        $this->Controller->request->expects($this->any())
+            ->method('is')
+            ->will($this->returnValue(true));
 
-        $response = $this->Controller->RequestHandler->beforeRedirect(
+        $response = $this->RequestHandler->beforeRedirect(
             $event,
             ['controller' => 'RequestHandlerTest', 'action' => 'destination'],
             $this->Controller->response
@@ -935,23 +935,21 @@ class RequestHandlerComponentTest extends TestCase
     {
         Configure::write('App.namespace', 'TestApp');
         Router::connect('/:controller/:action');
-        $event = new Event('Controller.beforeRedirect', $this->Controller);
 
-        $this->Controller->RequestHandler = new RequestHandlerComponent($this->Controller->components());
+        $this->RequestHandler = new RequestHandlerComponent($this->Controller->components());
         $this->Controller->request = $this->getMockBuilder('Cake\Network\Request')
             ->setMethods(['is'])
             ->getMock();
         $this->Controller->response = $this->getMockBuilder('Cake\Network\Response')
             ->setMethods(['_sendHeader', 'stop'])
             ->getMock();
-        $this->Controller->RequestHandler->request = $this->Controller->request;
-        $this->Controller->RequestHandler->response = $this->Controller->response;
         $this->Controller->request->expects($this->any())
             ->method('is')
             ->with('ajax')
             ->will($this->returnValue(true));
+        $event = new Event('Controller.beforeRedirect', $this->Controller);
 
-        $response = $this->Controller->RequestHandler->beforeRedirect(
+        $response = $this->RequestHandler->beforeRedirect(
             $event,
             '/request_action/params_pass?a=b&x=y?ish',
             $this->Controller->response
@@ -959,7 +957,7 @@ class RequestHandlerComponentTest extends TestCase
         $data = json_decode($response, true);
         $this->assertEquals('/request_action/params_pass', $data['here']);
 
-        $response = $this->Controller->RequestHandler->beforeRedirect(
+        $response = $this->RequestHandler->beforeRedirect(
             $event,
             '/request_action/query_pass?a=b&x=y?ish',
             $this->Controller->response
@@ -980,15 +978,13 @@ class RequestHandlerComponentTest extends TestCase
         Router::connect('/:controller/:action');
         $event = new Event('Controller.beforeRedirect', $this->Controller);
 
-        $this->Controller->RequestHandler = new RequestHandlerComponent($this->Controller->components());
+        $this->RequestHandler = new RequestHandlerComponent($this->Controller->components());
         $this->Controller->request = $this->getMockBuilder('Cake\Network\Request')
             ->setMethods(['is'])
             ->getMock();
         $this->Controller->response = $this->getMockBuilder('Cake\Network\Response')
             ->setMethods(['_sendHeader', 'stop'])
             ->getMock();
-        $this->Controller->RequestHandler->request = $this->Controller->request;
-        $this->Controller->RequestHandler->response = $this->Controller->response;
         $this->Controller->request->expects($this->any())->method('is')->will($this->returnValue(true));
 
         $cookies = [
@@ -996,7 +992,7 @@ class RequestHandlerComponentTest extends TestCase
         ];
         $this->Controller->request->cookies = $cookies;
 
-        $response = $this->Controller->RequestHandler->beforeRedirect(
+        $response = $this->RequestHandler->beforeRedirect(
             $event,
             '/request_action/cookie_pass',
             $this->Controller->response
@@ -1017,7 +1013,7 @@ class RequestHandlerComponentTest extends TestCase
         Router::connect('/:controller/:action');
         $event = new Event('Controller.beforeRedirect', $this->Controller);
 
-        $this->Controller->RequestHandler = new RequestHandlerComponent($this->Controller->components());
+        $this->RequestHandler = new RequestHandlerComponent($this->Controller->components());
         $this->Controller->request = $this->getMockBuilder('Cake\Network\Request')
             ->setMethods(['is'])
             ->getMock();
@@ -1025,11 +1021,9 @@ class RequestHandlerComponentTest extends TestCase
             ->setMethods(['_sendHeader', 'stop'])
             ->getMock();
         $this->Controller->response->statusCode(302);
-        $this->Controller->RequestHandler->request = $this->Controller->request;
-        $this->Controller->RequestHandler->response = $this->Controller->response;
         $this->Controller->request->expects($this->any())->method('is')->will($this->returnValue(true));
 
-        $response = $this->Controller->RequestHandler->beforeRedirect(
+        $response = $this->RequestHandler->beforeRedirect(
             $event,
             ['controller' => 'RequestHandlerTest', 'action' => 'destination'],
             $this->Controller->response
@@ -1051,18 +1045,16 @@ class RequestHandlerComponentTest extends TestCase
         Router::connect('/:controller/:action');
         $event = new Event('Controller.beforeRedirect', $this->Controller);
 
-        $this->Controller->RequestHandler = new RequestHandlerComponent($this->Controller->components());
+        $this->RequestHandler = new RequestHandlerComponent($this->Controller->components());
         $this->Controller->request = $this->getMockBuilder('Cake\Network\Request')
             ->setMethods(['is'])
             ->getMock();
         $this->Controller->response = $this->getMockBuilder('Cake\Network\Response')
             ->setMethods(['_sendHeader', 'stop'])
             ->getMock();
-        $this->Controller->RequestHandler->request = $this->Controller->request;
-        $this->Controller->RequestHandler->response = $this->Controller->response;
         $this->Controller->request->expects($this->any())->method('is')->will($this->returnValue(true));
 
-        $response = $this->Controller->RequestHandler->beforeRedirect(
+        $response = $this->RequestHandler->beforeRedirect(
             $event,
             ['controller' => 'RequestHandlerTest', 'action' => 'ajax2_layout'],
             $this->Controller->response
@@ -1092,8 +1084,7 @@ class RequestHandlerComponentTest extends TestCase
         ]);
 
         $RequestHandler = new RequestHandlerComponent($this->Controller->components());
-        $RequestHandler->request = new Request('posts/index');
-        $RequestHandler->response = $this->Controller->response;
+        $this->Controller->request = new Request('posts/index');
 
         ob_start();
         $RequestHandler->beforeRedirect(
@@ -1127,14 +1118,16 @@ class RequestHandlerComponentTest extends TestCase
     public function testCheckNotModifiedByEtagStar()
     {
         $_SERVER['HTTP_IF_NONE_MATCH'] = '*';
-        $event = new Event('Controller.beforeRender', $this->Controller);
-        $RequestHandler = new RequestHandlerComponent($this->Controller->components());
-        $RequestHandler->response = $this->getMockBuilder('Cake\Network\Response')
+        $response = $this->getMockBuilder('Cake\Network\Response')
             ->setMethods(['notModified', 'stop'])
             ->getMock();
-        $RequestHandler->response->etag('something');
-        $RequestHandler->response->expects($this->once())->method('notModified');
-        $this->assertFalse($RequestHandler->beforeRender($event));
+        $response->etag('something');
+        $response->expects($this->once())->method('notModified');
+        $this->Controller->response = $response;
+
+        $event = new Event('Controller.beforeRender', $this->Controller);
+        $requestHandler = new RequestHandlerComponent($this->Controller->components());
+        $this->assertFalse($requestHandler->beforeRender($event));
     }
 
     /**
@@ -1146,14 +1139,16 @@ class RequestHandlerComponentTest extends TestCase
     public function testCheckNotModifiedByEtagExact()
     {
         $_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
-        $event = new Event('Controller.beforeRender');
-        $RequestHandler = new RequestHandlerComponent($this->Controller->components());
-        $RequestHandler->response = $this->getMockBuilder('Cake\Network\Response')
+        $response = $this->getMockBuilder('Cake\Network\Response')
             ->setMethods(['notModified', 'stop'])
             ->getMock();
-        $RequestHandler->response->etag('something', true);
-        $RequestHandler->response->expects($this->once())->method('notModified');
-        $this->assertFalse($RequestHandler->beforeRender($event));
+        $response->etag('something', true);
+        $response->expects($this->once())->method('notModified');
+        $this->Controller->response = $response;
+        $event = new Event('Controller.beforeRender', $this->Controller);
+
+        $requestHandler = new RequestHandlerComponent($this->Controller->components());
+        $this->assertFalse($requestHandler->beforeRender($event));
     }
 
     /**
@@ -1166,15 +1161,17 @@ class RequestHandlerComponentTest extends TestCase
     {
         $_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
         $_SERVER['HTTP_IF_MODIFIED_SINCE'] = '2012-01-01 00:00:00';
-        $event = new Event('Controller.beforeRender', $this->Controller);
-        $RequestHandler = new RequestHandlerComponent($this->Controller->components());
-        $RequestHandler->response = $this->getMockBuilder('Cake\Network\Response')
+        $response = $this->getMockBuilder('Cake\Network\Response')
             ->setMethods(['notModified', 'stop'])
             ->getMock();
-        $RequestHandler->response->etag('something', true);
-        $RequestHandler->response->modified('2012-01-01 00:00:00');
-        $RequestHandler->response->expects($this->once())->method('notModified');
-        $this->assertFalse($RequestHandler->beforeRender($event));
+        $response->etag('something', true);
+        $response->modified('2012-01-01 00:00:00');
+        $response->expects($this->once())->method('notModified');
+        $this->Controller->response = $response;
+
+        $event = new Event('Controller.beforeRender', $this->Controller);
+        $requestHandler = new RequestHandlerComponent($this->Controller->components());
+        $this->assertFalse($requestHandler->beforeRender($event));
     }
 
     /**
@@ -1185,13 +1182,15 @@ class RequestHandlerComponentTest extends TestCase
      */
     public function testCheckNotModifiedNoInfo()
     {
-        $event = new Event('Controller.beforeRender', $this->Controller);
-        $RequestHandler = new RequestHandlerComponent($this->Controller->components());
-        $RequestHandler->response = $this->getMockBuilder('Cake\Network\Response')
+        $response = $this->getMockBuilder('Cake\Network\Response')
             ->setMethods(['notModified', 'stop'])
             ->getMock();
-        $RequestHandler->response->expects($this->never())->method('notModified');
-        $this->assertNull($RequestHandler->beforeRender($event));
+        $response->expects($this->never())->method('notModified');
+        $this->Controller->response = $response;
+
+        $event = new Event('Controller.beforeRender', $this->Controller);
+        $requestHandler = new RequestHandlerComponent($this->Controller->components());
+        $this->assertNull($requestHandler->beforeRender($event));
     }
 
     /**