diff --git a/core/lib/Drupal/Core/Theme/Registry.php b/core/lib/Drupal/Core/Theme/Registry.php index 5e450ab..730262c 100644 --- a/core/lib/Drupal/Core/Theme/Registry.php +++ b/core/lib/Drupal/Core/Theme/Registry.php @@ -236,7 +236,7 @@ public function get() { public function getRuntime() { $this->init($this->themeName); if (!isset($this->runtimeRegistry)) { - $this->runtimeRegistry = new ThemeRegistry('theme_registry:runtime:' . $this->theme->getName(), $this->cache, $this->lock, array('theme_registry'), $this->moduleHandler->isLoaded()); + $this->runtimeRegistry = new ThemeRegistry($this->cache, $this->lock, array('theme_registry'), $this->moduleHandler->isLoaded()); } return $this->runtimeRegistry; } diff --git a/core/lib/Drupal/Core/Utility/ThemeRegistry.php b/core/lib/Drupal/Core/Utility/ThemeRegistry.php index edc0089..bd54082 100644 --- a/core/lib/Drupal/Core/Utility/ThemeRegistry.php +++ b/core/lib/Drupal/Core/Utility/ThemeRegistry.php @@ -30,7 +30,7 @@ class ThemeRegistry extends CacheCollector implements DestructableInterface { * should be very rarely called on POST requests and this avoids polluting * the runtime cache. */ - protected $persistable; + protected $persistable = NULL; /** * The complete theme registry array. @@ -40,8 +40,6 @@ class ThemeRegistry extends CacheCollector implements DestructableInterface { /** * Constructs a ThemeRegistry object. * - * @param string $cid - * The cid for the array being cached. * @param \Drupal\Core\Cache\CacheBackendInterface $cache * The cache backend. * @param \Drupal\Core\Lock\LockBackendInterface $lock @@ -51,32 +49,63 @@ class ThemeRegistry extends CacheCollector implements DestructableInterface { * @param bool $modules_loaded * Whether all modules have already been loaded. */ - function __construct($cid, CacheBackendInterface $cache, LockBackendInterface $lock, $tags = array(), $modules_loaded = FALSE) { - $this->cid = $cid; + function __construct(CacheBackendInterface $cache, LockBackendInterface $lock, $tags = array(), $modules_loaded = FALSE) { $this->cache = $cache; $this->lock = $lock; $this->tags = $tags; - $this->persistable = $modules_loaded && \Drupal::hasRequest() && \Drupal::request()->isMethod('GET'); + } + + /** + * {@inheritdoc} + */ + protected function getCid() { + if (!$this->cid) { + $this->cid = 'theme_registry:runtime:' . $this->theme->getName(); + } - // @todo: Implement lazyload. - $this->cacheLoaded = TRUE; + return $this->cid; + } - if ($this->persistable && $cached = $this->cache->get($this->cid)) { - $this->storage = $cached->data; + /** + * Gets the persistable. + * + * @return bool + */ + protected function getPersistable() { + if ($this->persistable === NULL) { + $this->persistable = $modules_loaded && \Drupal::hasRequest() && \Drupal::request()->isMethod('GET'); } - else { - // If there is no runtime cache stored, fetch the full theme registry, - // but then initialize each value to NULL. This allows offsetExists() - // to function correctly on non-registered theme hooks without triggering - // a call to resolveCacheMiss(). - $this->storage = $this->initializeRegistry(); - foreach (array_keys($this->storage) as $key) { - $this->persist($key); + + return $this->persistable; + } + + + /** + * Gets the storage. + * + * @return array + */ + protected function getStorage() { + if (!$this->storage) { + if ($this->getPersistable() && $cached = $this->cache->get($this->getCid())) { + $this->storage = $cached->data; + } + else { + // If there is no runtime cache stored, fetch the full theme registry, + // but then initialize each value to NULL. This allows offsetExists() + // to function correctly on non-registered theme hooks without triggering + // a call to resolveCacheMiss(). + $this->storage = $this->initializeRegistry(); + foreach (array_keys($this->storage) as $key) { + $this->persist($key); + } + // RegistryTest::testRaceCondition() ensures that the cache entry is + // written on the initial construction of the theme registry. + $this->updateCache(); } - // RegistryTest::testRaceCondition() ensures that the cache entry is - // written on the initial construction of the theme registry. - $this->updateCache(); } + + return $this->storage; } /** @@ -101,7 +130,7 @@ public function has($key) { // are not registered, just check the existence of the key in the registry. // Use array_key_exists() here since a NULL value indicates that the theme // hook exists but has not yet been requested. - return array_key_exists($key, $this->storage); + return array_key_exists($key, $this->getStorage()); } /** @@ -111,10 +140,11 @@ public function get($key) { // If the offset is set but empty, it is a registered theme hook that has // not yet been requested. Offsets that do not exist at all were not // registered in hook_theme(). - if (isset($this->storage[$key])) { - return $this->storage[$key]; + $storage = $this->getStorage(); + if (isset($storage[$key])) { + return $storage[$key]; } - elseif (array_key_exists($key, $this->storage)) { + elseif (array_key_exists($key, $storage)) { return $this->resolveCacheMiss($key); } } @@ -126,34 +156,35 @@ public function resolveCacheMiss($key) { if (!isset($this->completeRegistry)) { $this->completeRegistry = \Drupal::service('theme.registry')->get(); } - $this->storage[$key] = $this->completeRegistry[$key]; - if ($this->persistable) { + $storage = $this->storage; + $storage[$key] = $this->completeRegistry[$key]; + if ($this->getPersistable()) { $this->persist($key); } - return $this->storage[$key]; + return $storage[$key]; } /** * {@inheritdoc} */ protected function updateCache($lock = TRUE) { - if (!$this->persistable) { + if (!$this->getPersistable()) { return; } // @todo: Is the custom implementation necessary? $data = array(); foreach ($this->keysToPersist as $offset => $persist) { if ($persist) { - $data[$offset] = $this->storage[$offset]; + $data[$offset] = $this->getStorage()[$offset]; } } if (empty($data)) { return; } - $lock_name = $this->cid . ':' . __CLASS__; + $lock_name = $this->getCid() . ':' . __CLASS__; if (!$lock || $this->lock->acquire($lock_name)) { - if ($cached = $this->cache->get($this->cid)) { + if ($cached = $this->cache->get($this->getCid())) { // Use array merge instead of union so that filled in values in $data // overwrite empty values in the current cache. $data = array_merge($cached->data, $data); @@ -162,7 +193,7 @@ protected function updateCache($lock = TRUE) { $registry = $this->initializeRegistry(); $data = array_merge($registry, $data); } - $this->cache->set($this->cid, $data, Cache::PERMANENT, $this->tags); + $this->cache->set($this->getCid(), $data, Cache::PERMANENT, $this->tags); if ($lock) { $this->lock->release($lock_name); }