diff --git a/core/lib/Drupal/Core/Template/TwigPhpStorageCache.php b/core/lib/Drupal/Core/Template/TwigPhpStorageCache.php index 90572c4..3a524bd 100644 --- a/core/lib/Drupal/Core/Template/TwigPhpStorageCache.php +++ b/core/lib/Drupal/Core/Template/TwigPhpStorageCache.php @@ -68,9 +68,6 @@ protected function storage() { * {@inheritdoc} */ public function generateKey($name, $className) { - // This substring keeps 132 bits of the hash. - $hash = substr(Crypt::hashBase64($className), 0, 22); - if (strpos($name, '{# inline_template_start #}') === 0) { // $name is an inline template, and can have characters that are not valid // for a filename. $hash is unique for each inline template so we just use @@ -80,21 +77,19 @@ public function generateKey($name, $className) { else { $name = basename($name); } - // If the suffix is longer that 45 characters then we truncate it so the + + // If the suffix is longer that 61 characters then we truncate it so the // length of the filename can't grow beyond that. Windows only supports 255 // characters in a path. If the files directory is in the usual place of // 'sites/default/files' then the maximum relative path of a twig file is - // 153 characters. This is made up of: + // 153 characters. We use 148 of that as follows: // - 30 (/sites/default/files/php/twig/) // - 9 (prefix + _) - // - 45 (suffix) - // - 69 (/ + hmac_hash + .php) - if (strlen($name) > 22) { - $name = substr($name, 0, 22); - } - $suffix = $name . '_' . $hash; + // - 61 (suffix) + // - 48 (/ + hmac_hash + .php) + $suffix = substr($name, 0, 30) . '_' . substr(Crypt::hashBase64($className), 0, 30); - // The first part is what is invalidated. + // The cache prefix is what gets invalidated. return $this->templateCacheFilenamePrefix . '_' . $suffix; } diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 6dc2663..4568b2a 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -1794,3 +1794,12 @@ function system_update_8203() { ->set('logging', 1) ->save(TRUE); } + +/** + * Clear caches due to change in Twig template cache names. + * + * @see \Drupal\Core\Template\TwigPhpStorageCache::generateKey() + */ +function system_update_8204() { + // Empty update to cause a cache rebuild. +} diff --git a/core/tests/Drupal/KernelTests/Core/Theme/TwigEnvironmentTest.php b/core/tests/Drupal/KernelTests/Core/Theme/TwigEnvironmentTest.php index 06f5826..e9811b4 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/TwigEnvironmentTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/TwigEnvironmentTest.php @@ -88,7 +88,7 @@ public function testInlineTemplate() { $cache = $environment->getCache(); $class = $environment->getTemplateClass($name); - $expected = $hash . '_inline-template_' . substr(Crypt::hashBase64($class), 0, 22); + $expected = $hash . '_inline-template_' . substr(Crypt::hashBase64($class), 0, 30); $this->assertEqual($expected, $cache->generateKey($name, $class)); } @@ -117,6 +117,14 @@ public function testCacheFilename() { // static cache. $environment = \Drupal::service('twig'); + // A template basename > 30 characters should be truncated in the cache key. + $cache = $environment->getCache(); + $long_name = 'core/modules/system/templates/block--system-messages-block.html.twig'; + $this->assertGreaterThan(30, strlen(basename($long_name))); + $class = $environment->getTemplateClass($long_name); + $key = $cache->generateKey($long_name, $class); + $this->assertEquals(70, strlen($key)); + $original_filename = $environment->getCacheFilename('core/modules/system/templates/container.html.twig'); \Drupal::getContainer()->set('twig', NULL);