diff --git a/core/includes/common.inc b/core/includes/common.inc index 175267f..019a528 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -532,32 +532,11 @@ function drupal_merge_attached(array $a, array $b) { */ function drupal_process_attached(array $elements) { // Asset attachments are handled by \Drupal\Core\Asset\AssetResolver. + // Unsetting these parts preserved as a side-effect even though this function + // is deprecated. foreach (array('library', 'drupalSettings') as $type) { unset($elements['#attached'][$type]); } - - // Add additional types of attachments specified in the render() structure. - foreach ($elements['#attached'] as $callback => $options) { - foreach ($elements['#attached'][$callback] as $args) { - // Limit the amount allowed entries. - switch ($callback) { - case 'html_head': - // @todo Removed in https://www.drupal.org/node/2477223 - break; - case 'feed': - // @todo Removed in https://www.drupal.org/node/2477223 - break; - case 'html_head_link': - // @todo Removed in https://www.drupal.org/node/2477223 - break; - case 'http_header': - // @todo Removed in https://www.drupal.org/node/2467759 - break; - default: - throw new \LogicException(sprintf('You are not allowed to use %s in #attached', $callback)); - } - } - } } /** diff --git a/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php b/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php index d6392e4..b47ff0c 100644 --- a/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php +++ b/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php @@ -11,6 +11,7 @@ use Drupal\Core\Asset\AttachedAssets; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Render\BubbleableMetadata; use Drupal\Component\Utility\SafeMarkup; use Symfony\Component\HttpFoundation\RequestStack; @@ -18,8 +19,7 @@ * Processes attachments of HTML responses. * * This class is used by the rendering service to process the #attached part of - * the render array, for HTML responses. It replaces drupal_process_attached() - * and drupal_get_html_head() from Drupal 7. + * the render array, for HTML responses. * * To render attachments to HTML for testing without a controller, use the * 'bare_html_page_renderer' service to generate a @@ -120,16 +120,23 @@ public function processAttachments(AttachmentsInterface $response) { throw new \InvalidArgumentException('\Drupal\Core\Render\HtmlResponse instance expected.'); } - // Since mergeBubbleableMetadata() needs full render arrays, we must set one - // up here. - $attached = []; - $attached['#attached'] = $response->getAttachments(); + // Get a reference to the attachments. + $attached = $response->getAttachments(); + + // Send a message back if the render array has unsupported #attached types. + $unsupported_types = array_diff( + array_keys($attached), + ['html_head', 'feed', 'html_head_link', 'http_header', 'library', 'html_response_placeholders', 'placeholders', 'drupalSettings'] + ); + if (!empty($unsupported_types)) { + throw new \LogicException(sprintf('You are not allowed to use %s in #attached', implode(', ', $unsupported_types))); + } // Get the placeholders from attached and then remove them. - $placeholders = $attached['#attached']['html_response_placeholders']; - unset($attached['#attached']['html_response_placeholders']); + $placeholders = $attached['html_response_placeholders']; + unset($attached['html_response_placeholders']); - $variables = $this->processAssetLibraries($attached['#attached'], $placeholders); + $variables = $this->processAssetLibraries($attached, $placeholders); // Since we can only replace content in the HTML head section if there's a // placeholder for it, we can safely avoid processing the render array if @@ -137,12 +144,12 @@ public function processAttachments(AttachmentsInterface $response) { if (!empty($placeholders['head'])) { // 'feed' is a special case of 'html_head_link'. We create an // 'html_head_link' for the RSS feed and merge it. - if (!empty($attached['#attached']['feed'])) { + if (!empty($attached['feed'])) { // Since mergeBubbleableMetadata() requires a complete render array, we // have to add the '#attached' key. - $attached = $this->renderer->mergeBubbleableMetadata( + $attached = BubbleableMetadata::mergeAttachments( $attached, - ['#attached' => $this->processFeed($attached['#attached']['feed'])] + $this->processFeed($attached['feed']) ); } // 'html_head_link' is a special case of 'html_head' which can be present @@ -150,21 +157,21 @@ public function processAttachments(AttachmentsInterface $response) { // settings in the render array. Processing it can add to both the // 'html_head' and 'http_header' keys of '#attached', so we must address // it before 'html_head'. - if (!empty($attached['#attached']['html_head_link'])) { + if (!empty($attached['html_head_link'])) { // Merge the processed 'html_head_link' into $attached so that its // 'html_head' and 'http_header' values are present for further // processing. The merge requires a full render array, so we have to add // '#attached' keys. - $attached = $this->renderer->mergeBubbleableMetadata( + $attached = BubbleableMetadata::mergeAttachments( $attached, - ['#attached' => $this->processHtmlHeadLink($attached['#attached']['html_head_link'])] + $this->processHtmlHeadLink($attached['html_head_link']) ); } // Now we can process 'html_head', which contains both 'feed' and // 'html_head_link'. - if (!empty($attached['#attached']['html_head'])) { - $html_head = $this->processHtmlHead($attached['#attached']['html_head']); + if (!empty($attached['html_head'])) { + $html_head = $this->processHtmlHead($attached['html_head']); // Invoke hook_html_head_alter(). $this->moduleHandler->alter('html_head', $html_head); // Store the result in $variables so it can be inserted into the @@ -177,8 +184,8 @@ public function processAttachments(AttachmentsInterface $response) { $this->renderPlaceholders($response, $placeholders, $variables); // Set the HTTP headers on the response if any bubbled. - if (!empty($attached['#attached']['http_header'])) { - $this->setHeaders($response, $attached['#attached']['http_header']); + if (!empty($attached['http_header'])) { + $this->setHeaders($response, $attached['http_header']); } return $response; @@ -277,7 +284,7 @@ protected function setHeaders(HtmlResponse $response, array $headers) { } } } - + /** * Ensure proper key/data order and defaults for renderable head items. * @@ -291,7 +298,7 @@ protected function setHeaders(HtmlResponse $response, array $headers) { protected function processHtmlHead(array $html_head) { $head = []; foreach ($html_head as $item) { - list ($data, $key) = $item; + list($data, $key) = $item; if (!isset($data['#type'])) { $data['#type'] = 'html_tag'; } @@ -339,6 +346,7 @@ protected function processHtmlHeadLink(array $html_head_link) { if ($should_add_header) { // Also add a HTTP header "Link:". + // @todo: Change this to Html::escape() after https://www.drupal.org/node/2550945 $href = '<' . SafeMarkup::checkPlain($attributes['href']) . '>;'; unset($attributes['href']); $attached['http_header'][] = ['Link', $href . drupal_http_header_attributes($attributes), TRUE]; diff --git a/core/modules/system/src/Tests/Render/HtmlResponseAttachmentsTest.php b/core/modules/system/src/Tests/Render/HtmlResponseAttachmentsTest.php index 1268ab3..1441541 100644 --- a/core/modules/system/src/Tests/Render/HtmlResponseAttachmentsTest.php +++ b/core/modules/system/src/Tests/Render/HtmlResponseAttachmentsTest.php @@ -26,8 +26,8 @@ class HtmlResponseAttachmentsTest extends WebTestBase { /** * Test rendering of ['#attached']. */ - public function testAttached() { - // We only have one test method here to speed up test execution. + public function testAttachments() { + // We only have one test method here in order to speed up test execution. $this->drupalGet('/render_attached_test/teapot'); $this->assertResponse(418);