Loading core/modules/views/src/Plugin/views/display/Feed.php +38 −0 Original line number Diff line number Diff line Loading @@ -116,9 +116,47 @@ public static function buildResponse($view_id, $display_id, array $args = []) { $cache_metadata = CacheableMetadata::createFromRenderArray($build); $response->addCacheableDependency($cache_metadata); // Set the HTTP headers and status code on the response if any bubbled. if (!empty($build['#attached']['http_header'])) { static::setHeaders($response, $build['#attached']['http_header']); } return $response; } /** * Sets headers on a response object. * * @param \Drupal\Core\Cache\CacheableResponse $response * The HTML response to update. * @param array $headers * The headers to set, as an array. The items in this array should be as * follows: * - The header name. * - The header value. * - (optional) Whether to replace a current value with the new one, or add * it to the others. If the value is not replaced, it will be appended, * resulting in a header like this: 'Header: value1,value2'. * * @see \Drupal\Core\Render\HtmlResponseAttachmentsProcessor::setHeaders() */ protected static function setHeaders(CacheableResponse $response, array $headers): void { foreach ($headers as $values) { $name = $values[0]; $value = $values[1]; $replace = !empty($values[2]); // Drupal treats the HTTP response status code like a header, even though // it really is not. if (strtolower($name) === 'status') { $response->setStatusCode($value); } else { $response->headers->set($name, $value, $replace); } } } /** * {@inheritdoc} */ Loading core/modules/views/src/Plugin/views/style/Opml.php +5 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,11 @@ public function render() { '#view' => $this->view, '#options' => $this->options, '#rows' => $rows, '#attached' => [ 'http_header' => [ ['Content-Type', 'text/xml; charset=utf-8'], ], ], ]; unset($this->view->row_index); return $build; Loading core/modules/views/src/Plugin/views/style/Rss.php +5 −0 Original line number Diff line number Diff line Loading @@ -132,6 +132,11 @@ public function render() { '#view' => $this->view, '#options' => $this->options, '#rows' => $rows, '#attached' => [ 'http_header' => [ ['Content-Type', 'application/rss+xml; charset=utf-8'], ], ], ]; unset($this->view->row_index); return $build; Loading core/modules/views/tests/src/Functional/Plugin/DisplayFeedTest.php +34 −0 Original line number Diff line number Diff line Loading @@ -204,4 +204,38 @@ public function testDisabledLinkedDisplay() { $this->assertSession()->statusCodeEquals(200); } /** * Tests the cacheability of the feed display. */ public function testFeedCacheability(): void { // Test as an anonymous user. $this->drupalLogout(); // Set the page cache max age to a value greater than zero. $config = $this->config('system.performance'); $config->set('cache.page.max_age', 300); $config->save(); // Uninstall all page cache modules that could cache the HTTP response // headers. \Drupal::service('module_installer')->uninstall([ 'page_cache', 'dynamic_page_cache', ]); // Reset all so that the config and module changes are active. $this->resetAll(); $url = 'test-feed-display.xml'; $this->drupalGet($url); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->responseHeaderEquals('Cache-Control', 'max-age=300, public'); $this->assertSession()->responseHeaderEquals('Content-Type', 'application/rss+xml; charset=utf-8'); // Visit the page again to get the cached response. $this->drupalGet($url); $this->assertSession()->responseHeaderEquals('Cache-Control', 'max-age=300, public'); $this->assertSession()->responseHeaderEquals('Content-Type', 'application/rss+xml; charset=utf-8'); } } core/modules/views/views.theme.inc +0 −12 Original line number Diff line number Diff line Loading @@ -928,12 +928,6 @@ function template_preprocess_views_view_rss(&$variables) { $variables['namespaces'] = new Attribute($style->namespaces); $variables['items'] = $items; $variables['channel_elements'] = $style->channel_elements; // During live preview we don't want to output the header since the contents // of the feed are being displayed inside a normal HTML page. if (empty($variables['view']->live_preview)) { $variables['view']->getResponse()->headers->set('Content-Type', 'application/rss+xml; charset=utf-8'); } } /** Loading Loading @@ -995,12 +989,6 @@ function template_preprocess_views_view_opml(&$variables) { $variables['title'] = $title; $variables['items'] = $items; $variables['updated'] = gmdate(DATE_RFC2822, \Drupal::time()->getRequestTime()); // During live preview we don't want to output the header since the contents // of the feed are being displayed inside a normal HTML page. if (empty($variables['view']->live_preview)) { $variables['view']->getResponse()->headers->set('Content-Type', 'text/xml; charset=utf-8'); } } /** Loading Loading
core/modules/views/src/Plugin/views/display/Feed.php +38 −0 Original line number Diff line number Diff line Loading @@ -116,9 +116,47 @@ public static function buildResponse($view_id, $display_id, array $args = []) { $cache_metadata = CacheableMetadata::createFromRenderArray($build); $response->addCacheableDependency($cache_metadata); // Set the HTTP headers and status code on the response if any bubbled. if (!empty($build['#attached']['http_header'])) { static::setHeaders($response, $build['#attached']['http_header']); } return $response; } /** * Sets headers on a response object. * * @param \Drupal\Core\Cache\CacheableResponse $response * The HTML response to update. * @param array $headers * The headers to set, as an array. The items in this array should be as * follows: * - The header name. * - The header value. * - (optional) Whether to replace a current value with the new one, or add * it to the others. If the value is not replaced, it will be appended, * resulting in a header like this: 'Header: value1,value2'. * * @see \Drupal\Core\Render\HtmlResponseAttachmentsProcessor::setHeaders() */ protected static function setHeaders(CacheableResponse $response, array $headers): void { foreach ($headers as $values) { $name = $values[0]; $value = $values[1]; $replace = !empty($values[2]); // Drupal treats the HTTP response status code like a header, even though // it really is not. if (strtolower($name) === 'status') { $response->setStatusCode($value); } else { $response->headers->set($name, $value, $replace); } } } /** * {@inheritdoc} */ Loading
core/modules/views/src/Plugin/views/style/Opml.php +5 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,11 @@ public function render() { '#view' => $this->view, '#options' => $this->options, '#rows' => $rows, '#attached' => [ 'http_header' => [ ['Content-Type', 'text/xml; charset=utf-8'], ], ], ]; unset($this->view->row_index); return $build; Loading
core/modules/views/src/Plugin/views/style/Rss.php +5 −0 Original line number Diff line number Diff line Loading @@ -132,6 +132,11 @@ public function render() { '#view' => $this->view, '#options' => $this->options, '#rows' => $rows, '#attached' => [ 'http_header' => [ ['Content-Type', 'application/rss+xml; charset=utf-8'], ], ], ]; unset($this->view->row_index); return $build; Loading
core/modules/views/tests/src/Functional/Plugin/DisplayFeedTest.php +34 −0 Original line number Diff line number Diff line Loading @@ -204,4 +204,38 @@ public function testDisabledLinkedDisplay() { $this->assertSession()->statusCodeEquals(200); } /** * Tests the cacheability of the feed display. */ public function testFeedCacheability(): void { // Test as an anonymous user. $this->drupalLogout(); // Set the page cache max age to a value greater than zero. $config = $this->config('system.performance'); $config->set('cache.page.max_age', 300); $config->save(); // Uninstall all page cache modules that could cache the HTTP response // headers. \Drupal::service('module_installer')->uninstall([ 'page_cache', 'dynamic_page_cache', ]); // Reset all so that the config and module changes are active. $this->resetAll(); $url = 'test-feed-display.xml'; $this->drupalGet($url); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->responseHeaderEquals('Cache-Control', 'max-age=300, public'); $this->assertSession()->responseHeaderEquals('Content-Type', 'application/rss+xml; charset=utf-8'); // Visit the page again to get the cached response. $this->drupalGet($url); $this->assertSession()->responseHeaderEquals('Cache-Control', 'max-age=300, public'); $this->assertSession()->responseHeaderEquals('Content-Type', 'application/rss+xml; charset=utf-8'); } }
core/modules/views/views.theme.inc +0 −12 Original line number Diff line number Diff line Loading @@ -928,12 +928,6 @@ function template_preprocess_views_view_rss(&$variables) { $variables['namespaces'] = new Attribute($style->namespaces); $variables['items'] = $items; $variables['channel_elements'] = $style->channel_elements; // During live preview we don't want to output the header since the contents // of the feed are being displayed inside a normal HTML page. if (empty($variables['view']->live_preview)) { $variables['view']->getResponse()->headers->set('Content-Type', 'application/rss+xml; charset=utf-8'); } } /** Loading Loading @@ -995,12 +989,6 @@ function template_preprocess_views_view_opml(&$variables) { $variables['title'] = $title; $variables['items'] = $items; $variables['updated'] = gmdate(DATE_RFC2822, \Drupal::time()->getRequestTime()); // During live preview we don't want to output the header since the contents // of the feed are being displayed inside a normal HTML page. if (empty($variables['view']->live_preview)) { $variables['view']->getResponse()->headers->set('Content-Type', 'text/xml; charset=utf-8'); } } /** Loading