cid = $cid; $this->bin = $bin; $this->tags = $tags; $this->persistable = module_load_all(NULL) && $_SERVER['REQUEST_METHOD'] == 'GET'; $data = array(); if ($this->persistable && $cached = cache($this->bin)->get($this->cid)) { $data = $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(). $data = $this->initializeRegistry(); if ($this->persistable) { $this->set($data); } } $this->storage = $data; } /** * Initializes the full theme registry. * * @return * An array with the keys of the full theme registry, but the values * initialized to NULL. */ function initializeRegistry() { $this->completeRegistry = theme_get_registry(); return array_fill_keys(array_keys($this->completeRegistry), NULL); } public function offsetExists($offset) { // Since the theme registry allows for theme hooks to be requested that // 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($offset, $this->storage); } public function offsetGet($offset) { // 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[$offset])) { return $this->storage[$offset]; } elseif (array_key_exists($offset, $this->storage)) { return $this->resolveCacheMiss($offset); } } public function resolveCacheMiss($offset) { if (!isset($this->completeRegistry)) { $this->completeRegistry = theme_get_registry(); } $this->storage[$offset] = $this->completeRegistry[$offset]; if ($this->persistable) { $this->persist($offset); } return $this->storage[$offset]; } public function set($data, $lock = TRUE) { $lock_name = $this->cid . ':' . $this->bin; if (!$lock || lock()->acquire($lock_name)) { if ($cached = cache($this->bin)->get($this->cid)) { // 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); } else { $registry = $this->initializeRegistry(); $data = array_merge($registry, $data); } cache($this->bin)->set($this->cid, $data, CacheBackendInterface::CACHE_PERMANENT, $this->tags); if ($lock) { lock()->release($lock_name); } } } }