From a4e51c82e60fca8f9e46338fd2bf8c080fee019e Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Wed, 8 Apr 2015 22:09:50 +0100
Subject: [PATCH] Issue #2464877 by Wim Leers: Update
 RendererInterface::addDependency() to accept *any* object, not only
 CachableDependencyInterface objects

---
 .../Drupal/Core/Render/BubbleableMetadata.php | 20 ++++++++++++-----
 core/lib/Drupal/Core/Render/Renderer.php      |  2 +-
 .../Drupal/Core/Render/RendererInterface.php  |  4 ++--
 .../Core/Render/BubbleableMetadataTest.php    |  6 ++++-
 .../Drupal/Tests/Core/Render/RendererTest.php | 22 ++++++++++++++++++-
 5 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/core/lib/Drupal/Core/Render/BubbleableMetadata.php b/core/lib/Drupal/Core/Render/BubbleableMetadata.php
index c4852a99aaf7..31a1f851c3aa 100644
--- a/core/lib/Drupal/Core/Render/BubbleableMetadata.php
+++ b/core/lib/Drupal/Core/Render/BubbleableMetadata.php
@@ -109,18 +109,26 @@ public static function createFromRenderArray(array $build) {
   }
 
   /**
-   * Creates a bubbleable metadata object from a cacheable depended object.
+   * Creates a bubbleable metadata object from a depended object.
    *
-   * @param \Drupal\Core\Cache\CacheableDependencyInterface $object
+   * @param \Drupal\Core\Cache\CacheableDependencyInterface|mixed $object
    *   The object whose cacheability metadata to retrieve.
    *
    * @return static
    */
-  public static function createFromObject(CacheableDependencyInterface $object) {
+  public static function createFromObject($object) {
+    if ($object instanceof CacheableDependencyInterface) {
+      $meta = new static();
+      $meta->contexts = $object->getCacheContexts();
+      $meta->tags = $object->getCacheTags();
+      $meta->maxAge = $object->getCacheMaxAge();
+      return $meta;
+    }
+
+    // Objects that don't implement CacheableDependencyInterface must be assumed
+    // to be uncacheable, so set max-age 0.
     $meta = new static();
-    $meta->contexts = $object->getCacheContexts();
-    $meta->tags = $object->getCacheTags();
-    $meta->maxAge = $object->getCacheMaxAge();
+    $meta->maxAge = 0;
     return $meta;
   }
 
diff --git a/core/lib/Drupal/Core/Render/Renderer.php b/core/lib/Drupal/Core/Render/Renderer.php
index 589180565810..34bfa0e3f8c9 100644
--- a/core/lib/Drupal/Core/Render/Renderer.php
+++ b/core/lib/Drupal/Core/Render/Renderer.php
@@ -792,7 +792,7 @@ public static function mergeBubbleableMetadata(array $a, array $b) {
   /**
    * {@inheritdoc}
    */
-  public function addDependency(array &$elements, CacheableDependencyInterface $dependency) {
+  public function addDependency(array &$elements, $dependency) {
     $meta_a = BubbleableMetadata::createFromRenderArray($elements);
     $meta_b = BubbleableMetadata::createFromObject($dependency);
     $meta_a->merge($meta_b)->applyTo($elements);
diff --git a/core/lib/Drupal/Core/Render/RendererInterface.php b/core/lib/Drupal/Core/Render/RendererInterface.php
index 85035bfa526f..da8d5673470b 100644
--- a/core/lib/Drupal/Core/Render/RendererInterface.php
+++ b/core/lib/Drupal/Core/Render/RendererInterface.php
@@ -351,10 +351,10 @@ public static function mergeBubbleableMetadata(array $a, array $b);
    *
    * @param array &$elements
    *   The render array to update.
-   * @param \Drupal\Core\Cache\CacheableDependencyInterface $dependency
+   * @param \Drupal\Core\Cache\CacheableDependencyInterface|mixed $dependency
    *   The dependency.
    */
-  public function addDependency(array &$elements, CacheableDependencyInterface $dependency);
+  public function addDependency(array &$elements, $dependency);
 
   /**
    * Merges two attachments arrays (which live under the '#attached' key).
diff --git a/core/tests/Drupal/Tests/Core/Render/BubbleableMetadataTest.php b/core/tests/Drupal/Tests/Core/Render/BubbleableMetadataTest.php
index 526b7ee899e2..721d9925c9c6 100644
--- a/core/tests/Drupal/Tests/Core/Render/BubbleableMetadataTest.php
+++ b/core/tests/Drupal/Tests/Core/Render/BubbleableMetadataTest.php
@@ -136,7 +136,7 @@ public function providerTestCreateFromRenderArray() {
    * @covers ::createFromObject
    * @dataProvider providerTestCreateFromObject
    */
-  public function testCreateFromObject(CacheableDependencyInterface $object, BubbleableMetadata $expected) {
+  public function testCreateFromObject($object, BubbleableMetadata $expected) {
     $this->assertEquals($expected, BubbleableMetadata::createFromObject($object));
   }
 
@@ -153,12 +153,16 @@ public function providerTestCreateFromObject() {
     $nonempty_metadata->setCacheContexts(['qux'])
       ->setCacheTags(['foo:bar'])
       ->setCacheMaxAge(600);
+    $uncacheable_metadata = new BubbleableMetadata();
+    $uncacheable_metadata->setCacheMaxAge(0);
 
     $empty_cacheable_object = new TestCacheableDependency([], [], Cache::PERMANENT);
     $nonempty_cacheable_object = new TestCacheableDependency(['qux'], ['foo:bar'], 600);
+    $uncacheable_object = new \stdClass();
 
     $data[] = [$empty_cacheable_object, $empty_metadata];
     $data[] = [$nonempty_cacheable_object, $nonempty_metadata];
+    $data[] = [$uncacheable_object, $uncacheable_metadata];
 
     return $data;
   }
diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTest.php b/core/tests/Drupal/Tests/Core/Render/RendererTest.php
index 8e55ddd20ff8..56d9db11018c 100644
--- a/core/tests/Drupal/Tests/Core/Render/RendererTest.php
+++ b/core/tests/Drupal/Tests/Core/Render/RendererTest.php
@@ -626,7 +626,7 @@ public function providerTestRenderCacheMaxAge() {
    *
    * @dataProvider providerTestAddDependency
    */
-  public function testAddDependency(array $build, CacheableDependencyInterface $object, array $expected) {
+  public function testAddDependency(array $build, $object, array $expected) {
     $this->renderer->addDependency($build, $object);
     $this->assertEquals($build, $expected);
   }
@@ -681,6 +681,26 @@ public function providerTestAddDependency() {
           '#post_render_cache' => [],
         ],
       ],
+      // Cacheable render array, no cacheability.
+      [
+        [
+          '#cache' => [
+            'contexts' => ['theme'],
+            'tags' => ['bar'],
+            'max-age' => 600,
+          ]
+        ],
+        new \stdClass(),
+        [
+          '#cache' => [
+            'contexts' => ['theme'],
+            'tags' => ['bar'],
+            'max-age' => 0,
+          ],
+          '#attached' => [],
+          '#post_render_cache' => [],
+        ],
+      ],
     ];
   }
 
-- 
GitLab