Loading core/lib/Drupal/Core/Render/PlaceholderGenerator.php +10 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,16 @@ public function createPlaceholder(array $element) { '#cache' => TRUE, ]); // Be sure cache contexts and tags are sorted before serializing them and // making hash. Issue #3225328 removes sort from contexts and tags arrays // for performances reasons. if (isset($placeholder_render_array['#cache']['contexts'])) { sort($placeholder_render_array['#cache']['contexts']); } if (isset($placeholder_render_array['#cache']['tags'])) { sort($placeholder_render_array['#cache']['tags']); } // Generate placeholder markup. Note that the only requirement is that this // is unique markup that isn't easily guessable. The #lazy_builder callback // and its arguments are put in the placeholder markup solely to simplify<<< Loading core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php +10 −0 Original line number Diff line number Diff line Loading @@ -274,6 +274,16 @@ protected static function generateBigPipePlaceholderId($original_placeholder, ar // Generate a BigPipe placeholder ID (to be used by BigPipe's JavaScript). // @see \Drupal\Core\Render\PlaceholderGenerator::createPlaceholder() if (isset($placeholder_render_array['#lazy_builder'])) { // Be sure cache contexts and tags are sorted before serializing them and // making hash. Issue #3225328 removes sort from contexts and tags arrays // for performances reasons. if (isset($placeholder_render_array['#cache']['contexts'])) { sort($placeholder_render_array['#cache']['contexts']); } if (isset($placeholder_render_array['#cache']['tags'])) { sort($placeholder_render_array['#cache']['tags']); } $callback = $placeholder_render_array['#lazy_builder'][0]; $arguments = $placeholder_render_array['#lazy_builder'][1]; $token = Crypt::hashBase64(serialize($placeholder_render_array)); Loading core/tests/Drupal/Tests/Core/Render/PlaceholderGeneratorTest.php +40 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ namespace Drupal\Tests\Core\Render; use Drupal\Component\Utility\Html; use Drupal\Core\Cache\Cache; /** * @coversDefaultClass \Drupal\Core\Render\PlaceholderGenerator Loading Loading @@ -36,6 +37,45 @@ public function testCreatePlaceholderGeneratesValidHtmlMarkup(array $element) { $this->assertEquals($original_placeholder_markup, $processed_placeholder_markup); } /** * Create an element with #lazy_builder callback. Between two renders, cache * contexts nor tags sort change. Placeholder should generate same hash to not * be rendered twice. * * @covers ::createPlaceholder */ public function testRenderPlaceholdersDifferentSortedContextsTags() { $contexts_1 = ['user', 'foo']; $contexts_2 = ['foo', 'user']; $tags_1 = ['current-temperature', 'foo']; $tags_2 = ['foo', 'current-temperature']; $test_element = [ '#cache' => [ 'max-age' => Cache::PERMANENT, ], '#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', ['foo' => TRUE]], ]; $test_element['#cache']['contexts'] = $contexts_1; $test_element['#cache']['tags'] = $tags_1; $placeholder_element1 = $this->placeholderGenerator->createPlaceholder($test_element); $test_element['#cache']['contexts'] = $contexts_2; $test_element['#cache']['tags'] = $tags_1; $placeholder_element2 = $this->placeholderGenerator->createPlaceholder($test_element); $test_element['#cache']['contexts'] = $contexts_1; $test_element['#cache']['tags'] = $tags_2; $placeholder_element3 = $this->placeholderGenerator->createPlaceholder($test_element); // Verify placeholder and specially hash are same with different contexts // order. $this->assertSame((string) $placeholder_element1['#markup'], (string) $placeholder_element2['#markup']); // Verify placeholder and specially hash are same with different tags order. $this->assertSame((string) $placeholder_element1['#markup'], (string) $placeholder_element3['#markup']); } /** * @return array */ Loading Loading
core/lib/Drupal/Core/Render/PlaceholderGenerator.php +10 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,16 @@ public function createPlaceholder(array $element) { '#cache' => TRUE, ]); // Be sure cache contexts and tags are sorted before serializing them and // making hash. Issue #3225328 removes sort from contexts and tags arrays // for performances reasons. if (isset($placeholder_render_array['#cache']['contexts'])) { sort($placeholder_render_array['#cache']['contexts']); } if (isset($placeholder_render_array['#cache']['tags'])) { sort($placeholder_render_array['#cache']['tags']); } // Generate placeholder markup. Note that the only requirement is that this // is unique markup that isn't easily guessable. The #lazy_builder callback // and its arguments are put in the placeholder markup solely to simplify<<< Loading
core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php +10 −0 Original line number Diff line number Diff line Loading @@ -274,6 +274,16 @@ protected static function generateBigPipePlaceholderId($original_placeholder, ar // Generate a BigPipe placeholder ID (to be used by BigPipe's JavaScript). // @see \Drupal\Core\Render\PlaceholderGenerator::createPlaceholder() if (isset($placeholder_render_array['#lazy_builder'])) { // Be sure cache contexts and tags are sorted before serializing them and // making hash. Issue #3225328 removes sort from contexts and tags arrays // for performances reasons. if (isset($placeholder_render_array['#cache']['contexts'])) { sort($placeholder_render_array['#cache']['contexts']); } if (isset($placeholder_render_array['#cache']['tags'])) { sort($placeholder_render_array['#cache']['tags']); } $callback = $placeholder_render_array['#lazy_builder'][0]; $arguments = $placeholder_render_array['#lazy_builder'][1]; $token = Crypt::hashBase64(serialize($placeholder_render_array)); Loading
core/tests/Drupal/Tests/Core/Render/PlaceholderGeneratorTest.php +40 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ namespace Drupal\Tests\Core\Render; use Drupal\Component\Utility\Html; use Drupal\Core\Cache\Cache; /** * @coversDefaultClass \Drupal\Core\Render\PlaceholderGenerator Loading Loading @@ -36,6 +37,45 @@ public function testCreatePlaceholderGeneratesValidHtmlMarkup(array $element) { $this->assertEquals($original_placeholder_markup, $processed_placeholder_markup); } /** * Create an element with #lazy_builder callback. Between two renders, cache * contexts nor tags sort change. Placeholder should generate same hash to not * be rendered twice. * * @covers ::createPlaceholder */ public function testRenderPlaceholdersDifferentSortedContextsTags() { $contexts_1 = ['user', 'foo']; $contexts_2 = ['foo', 'user']; $tags_1 = ['current-temperature', 'foo']; $tags_2 = ['foo', 'current-temperature']; $test_element = [ '#cache' => [ 'max-age' => Cache::PERMANENT, ], '#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', ['foo' => TRUE]], ]; $test_element['#cache']['contexts'] = $contexts_1; $test_element['#cache']['tags'] = $tags_1; $placeholder_element1 = $this->placeholderGenerator->createPlaceholder($test_element); $test_element['#cache']['contexts'] = $contexts_2; $test_element['#cache']['tags'] = $tags_1; $placeholder_element2 = $this->placeholderGenerator->createPlaceholder($test_element); $test_element['#cache']['contexts'] = $contexts_1; $test_element['#cache']['tags'] = $tags_2; $placeholder_element3 = $this->placeholderGenerator->createPlaceholder($test_element); // Verify placeholder and specially hash are same with different contexts // order. $this->assertSame((string) $placeholder_element1['#markup'], (string) $placeholder_element2['#markup']); // Verify placeholder and specially hash are same with different tags order. $this->assertSame((string) $placeholder_element1['#markup'], (string) $placeholder_element3['#markup']); } /** * @return array */ Loading