/** * Pulls data out of cache. * Also, it checks all related tags for expiration/version-up. * * @see sfCache::get * @param string $key * @param mixed $default returned back if result is false * @return mixed */ public function get($key, $default = null) { $cacheMetadata = new CacheMetadata($this->getCache()->get($key, $default)); $data = $cacheMetadata->getData(); if (null !== $data) { $fetchedCacheTags = $cacheMetadata->getTags(); if (0 !== count($fetchedCacheTags)) { /** * speed up multi tag selection from backend */ $tagKeys = array_keys($fetchedCacheTags); $storedTags = $this->getCache()->getMany($tagKeys); $hasExpired = false; /** * getMany returns keys with NULL value if some key is missing. * In case arrays are equal, cache is not expired */ if ($fetchedCacheTags === $storedTags) { $this->getLogger()->log('V', 'via equal compare'); # one tag is expired, no reasons to continue # (should revalidate cache data) } else { $extendedKeysWithCurrentVersions = array_combine(array_keys($storedTags), array_values($fetchedCacheTags)); # check for data tags is expired foreach ($storedTags as $tagKey => $tagLatestVersion) { $tagVersion = $extendedKeysWithCurrentVersions[$tagKey]; # tag is exprired or version is old if (!$tagLatestVersion || $tagVersion < $tagLatestVersion) { $this->getLogger()->log('v', sprintf('%s(%s=>%s)', $tagKey, $tagVersion, $tagLatestVersion)); # one tag is expired, no reasons to continue # (should revalidate cache data) $hasExpired = true; break; } $this->getLogger()->log('V', sprintf('%s(%s)', $tagKey, $tagLatestVersion)); } } // some cache tags is invalidated if ($hasExpired) { if ($this->isLocked($key)) { # return old cache coz new data is writing to the current cache $data = $cacheMetadata->getData(); } else { # cache no locked, but cache is expired $data = null; } } else { $data = $cacheMetadata->getData(); } } else { $data = $cacheMetadata->getData(); } } $this->getLogger()->log($data !== $default ? 'G' : 'g', $key); return $data; }
/** * Listens to the 'view.cache.filter_content' event to decorate a chunk of HTML with cache information. * * Added info about linked tags * * @param sfEvent $event A sfEvent instance * @param string $content The HTML content * * @return string The decorated HTML string */ public function decorateContentWithDebug(sfEvent $event, $content) { $updatedContent = parent::decorateContentWithDebug($event, $content); if ($content === $updatedContent) { return $content; } $cacheMetadata = new CacheMetadata($this->getCache()->get($this->generateCacheKey($event['uri']))); if (null === $cacheMetadata->getData()) { return $content; } $tags = $cacheMetadata->getTags(); ksort($tags, SORT_ASC); $tagsCount = count($tags); $tagsContent = sprintf('[cache tags] count: %d', $tagsCount); if (0 != $tagsCount) { $tagsContent .= ', tags:'; foreach ($tags as $name => $version) { $tagsContent .= sprintf(' <span title="%s">%s</span>,', htmlspecialchars($version, ENT_QUOTES, sfConfig::get('sf_charset')), htmlspecialchars($name, ENT_QUOTES, sfConfig::get('sf_charset'))); } $tagsContent = substr($tagsContent, 0, -1) . '.'; } $textToReplace = ' <br /> '; return str_replace($textToReplace, $tagsContent, $updatedContent); }