Browse Source

Move content type definition to view

* Remove `get` prefix from View::contentType() as there is no set.
* Add content-type setting to View::initialize() in a protected method
  that can be redefined by sub-classes if necessary.
* Update core views to use new methods and logic.
Mark Story 4 years ago
parent
commit
fa906ce703

+ 1 - 9
src/Controller/Controller.php

@@ -764,12 +764,6 @@ class Controller implements EventListenerInterface, EventDispatcherInterface
         $contents = $view->render();
         $response = $view->getResponse()->withStringBody($contents);
 
-        $viewContentType = $view->getContentType();
-        $responseType = $response->getHeaderLine('Content-Type');
-        if ($viewContentType && ($responseType === '' || substr($responseType, 0, 9) === 'text/html')) {
-            $response = $response->withHeader('Content-Type', $viewContentType);
-        }
-
         return $this->setResponse($response)->response;
     }
 
@@ -791,8 +785,6 @@ class Controller implements EventListenerInterface, EventDispatcherInterface
      * Use the view classes defined on this controller to view
      * selection based on content-type negotiation.
      *
-     * TODO: Should this also consider $request->getParam('_ext') as well?
-     *
      * @return string|null The chosen view class or null for no decision.
      */
     protected function chooseViewClass(): ?string
@@ -807,7 +799,7 @@ class Controller implements EventListenerInterface, EventDispatcherInterface
 
         $typeMap = [];
         foreach ($possibleViewClasses as $class) {
-            $viewContentType = $class::getContentType();
+            $viewContentType = $class::contentType();
             if ($viewContentType && !isset($typeMap[$viewContentType])) {
                 $typeMap[$viewContentType] = $class;
             }

+ 1 - 1
src/View/AjaxView.php

@@ -33,7 +33,7 @@ class AjaxView extends View
      *
      * @return string
      */
-    public static function getContentType(): string
+    public static function contentType(): string
     {
         return 'text/html';
     }

+ 1 - 1
src/View/JsonView.php

@@ -100,7 +100,7 @@ class JsonView extends SerializedView
      *
      * @return string The JSON content type.
      */
-    public static function getContentType(): string
+    public static function contentType(): string
     {
         return 'application/json';
     }

+ 4 - 8
src/View/SerializedView.php

@@ -29,7 +29,7 @@ abstract class SerializedView extends View
      * Response type.
      *
      * @var string
-     * @deprecated 4.4.0 Implement ``public static getContentType(): string`` instead.
+     * @deprecated 4.4.0 Implement ``public static contentType(): string`` instead.
      */
     protected $_responseType;
 
@@ -55,14 +55,10 @@ abstract class SerializedView extends View
     public function initialize(): void
     {
         parent::initialize();
-        $response = $this->getResponse();
-        $contentType = static::getContentType();
-        if ($contentType) {
-            $response = $response->withType($contentType);
-        } else {
-            $response = $response->withType($this->_responseType);
+        if ($this->_responseType) {
+            $response = $this->getResponse()->withType($this->_responseType);
+            $this->setResponse($response);
         }
-        $this->setResponse($response);
     }
 
     /**

+ 21 - 1
src/View/View.php

@@ -363,6 +363,26 @@ class View implements EventDispatcherInterface
      */
     public function initialize(): void
     {
+        $this->setContentType();
+    }
+
+    /**
+     * Set the response content-type based on the view's contentType()
+     *
+     * @return void
+     */
+    protected function setContentType(): void
+    {
+        $viewContentType = $this->contentType();
+        if (!$viewContentType) {
+            return;
+        }
+        $response = $this->getResponse();
+        $responseType = $response->getHeaderLine('Content-Type');
+        if ($responseType === '' || substr($responseType, 0, 9) === 'text/html') {
+            $response = $response->withType($viewContentType);
+        }
+        $this->setResponse($response);
     }
 
     /**
@@ -370,7 +390,7 @@ class View implements EventDispatcherInterface
      *
      * @return string Either the content type or '' which means no type.
      */
-    public static function getContentType(): string
+    public static function contentType(): string
     {
         return '';
     }

+ 1 - 1
src/View/XmlView.php

@@ -100,7 +100,7 @@ class XmlView extends SerializedView
      *
      * @return string The JSON content type.
      */
-    public static function getContentType(): string
+    public static function contentType(): string
     {
         return 'application/xml';
     }

+ 1 - 1
tests/TestCase/Controller/ControllerTest.php

@@ -346,7 +346,7 @@ class ControllerTest extends TestCase
         $controller = new ContentTypesController($request, new Response());
         $controller->plain();
         $response = $controller->render();
-        $this->assertSame('text/plain', $response->getHeaderLine('Content-Type'));
+        $this->assertSame('text/plain; charset=UTF-8', $response->getHeaderLine('Content-Type'));
         $this->assertStringContainsString('hello world', $response->getBody() . '');
     }
 

+ 2 - 2
tests/TestCase/View/ViewTest.php

@@ -1810,9 +1810,9 @@ TEXT;
     /**
      * Somewhat pointless, but helps ensure BC for defaults.
      */
-    public function testGetContentType()
+    public function testContentType()
     {
-        $this->assertSame('', $this->View->getContentType());
+        $this->assertSame('', $this->View->contentType());
     }
 
     protected function checkException(string $message): void

+ 4 - 1
tests/test_app/TestApp/View/PlainTextView.php

@@ -22,7 +22,10 @@ use Cake\View\View;
  */
 class PlainTextView extends View
 {
-    public static function getContentType(): string
+    /**
+     * @inheritDoc
+     */
+    public static function contentType(): string
     {
         return 'text/plain';
     }