Neos\Fusion\Core\Cache\CacheSegmentParser::extractRenderedSegments PHP Метод

extractRenderedSegments() публичный Метод

This method also prepares a cleaned up output which can be retrieved later. See getOutput() for more information.
public extractRenderedSegments ( string $content, string $randomCacheMarker = '' ) : string
$content string The content to process, ie. the rendered content with some segment markers already in place
$randomCacheMarker string A random cache marker that should be used to "protect" against content containing special characters used to mark cache segments
Результат string The outer content with placeholders instead of the actual content segments
    public function extractRenderedSegments($content, $randomCacheMarker = '')
    {
        $this->output = '';
        $this->cacheEntries = [];
        $parts = [['content' => '']];
        $currentPosition = 0;
        $level = 0;
        $nextStartPosition = strpos($content, ContentCache::CACHE_SEGMENT_START_TOKEN . $randomCacheMarker, $currentPosition);
        $nextEndPosition = strpos($content, ContentCache::CACHE_SEGMENT_END_TOKEN . $randomCacheMarker, $currentPosition);
        while (true) {
            // Nothing else to do, all segments are parsed
            if ($nextStartPosition === false && $nextEndPosition === false) {
                $part = substr($content, $currentPosition);
                $parts[0]['content'] .= $part;
                $this->output .= $part;
                break;
            }
            // A cache segment is started and no end token can be found
            if ($nextStartPosition !== false && $nextEndPosition === false) {
                throw new Exception(sprintf('No cache segment end token can be found after position %d', $currentPosition), 1391853500);
            }
            if ($level === 0 && $nextEndPosition !== false && ($nextStartPosition === false || $nextEndPosition < $nextStartPosition)) {
                throw new Exception(sprintf('Exceeding segment end token after position %d', $currentPosition), 1391853689);
            }
            // Either no other segment start was found or we encountered an segment end before the next start
            if ($nextStartPosition === false || $nextEndPosition < $nextStartPosition) {
                // Add everything until end to current level
                $part = substr($content, $currentPosition, $nextEndPosition - $currentPosition);
                $parts[$level]['content'] .= $part;
                $currentLevelPart =& $parts[$level];
                $identifier = $currentLevelPart['identifier'];
                $this->output .= $part;
                if ($currentLevelPart['type'] === ContentCache::SEGMENT_TYPE_CACHED || $currentLevelPart['type'] === ContentCache::SEGMENT_TYPE_DYNAMICCACHED) {
                    $this->cacheEntries[$identifier] = $parts[$level];
                }
                // The end marker ends the current level
                unset($parts[$level]);
                $level--;
                if ($currentLevelPart['type'] === ContentCache::SEGMENT_TYPE_UNCACHED) {
                    $parts[$level]['content'] .= ContentCache::CACHE_SEGMENT_START_TOKEN . ContentCache::CACHE_SEGMENT_MARKER . $identifier . ContentCache::CACHE_SEGMENT_SEPARATOR_TOKEN . ContentCache::CACHE_SEGMENT_MARKER . $currentLevelPart['context'] . ContentCache::CACHE_SEGMENT_END_TOKEN . ContentCache::CACHE_SEGMENT_MARKER;
                } elseif ($currentLevelPart['type'] === ContentCache::SEGMENT_TYPE_DYNAMICCACHED) {
                    $parts[$level]['content'] .= ContentCache::CACHE_SEGMENT_START_TOKEN . ContentCache::CACHE_SEGMENT_MARKER . 'evalCached=' . $identifier . ContentCache::CACHE_SEGMENT_SEPARATOR_TOKEN . ContentCache::CACHE_SEGMENT_MARKER . $currentLevelPart['context'] . ContentCache::CACHE_SEGMENT_END_TOKEN . ContentCache::CACHE_SEGMENT_MARKER;
                } else {
                    $parts[$level]['content'] .= ContentCache::CACHE_SEGMENT_START_TOKEN . ContentCache::CACHE_SEGMENT_MARKER . $identifier . ContentCache::CACHE_SEGMENT_END_TOKEN . ContentCache::CACHE_SEGMENT_MARKER;
                }
                $currentPosition = $nextEndPosition + 1 + strlen($randomCacheMarker);
                $nextEndPosition = strpos($content, ContentCache::CACHE_SEGMENT_END_TOKEN . $randomCacheMarker, $currentPosition);
            } else {
                // Push everything until now to the current stack value
                $part = substr($content, $currentPosition, $nextStartPosition - $currentPosition);
                $parts[$level]['content'] .= $part;
                $this->output .= $part;
                // Found opening marker, increase level
                $level++;
                $parts[$level] = ['content' => ''];
                $currentPosition = $nextStartPosition + 1 + strlen($randomCacheMarker);
                $nextStartPosition = strpos($content, ContentCache::CACHE_SEGMENT_START_TOKEN . $randomCacheMarker, $currentPosition);
                $nextIdentifierSeparatorPosition = strpos($content, ContentCache::CACHE_SEGMENT_SEPARATOR_TOKEN . $randomCacheMarker, $currentPosition);
                $nextSecondIdentifierSeparatorPosition = strpos($content, ContentCache::CACHE_SEGMENT_SEPARATOR_TOKEN . $randomCacheMarker, $nextIdentifierSeparatorPosition + 1);
                if ($nextIdentifierSeparatorPosition === false || $nextSecondIdentifierSeparatorPosition === false || $nextStartPosition !== false && $nextStartPosition < $nextIdentifierSeparatorPosition || $nextEndPosition !== false && $nextEndPosition < $nextIdentifierSeparatorPosition || $nextStartPosition !== false && $nextStartPosition < $nextSecondIdentifierSeparatorPosition || $nextEndPosition !== false && $nextEndPosition < $nextSecondIdentifierSeparatorPosition) {
                    throw new Exception(sprintf('Missing segment separator token after position %d', $currentPosition), 1391855139);
                }
                $identifier = substr($content, $currentPosition, $nextIdentifierSeparatorPosition - $currentPosition);
                $contextOrMetadata = substr($content, $nextIdentifierSeparatorPosition + 1 + strlen($randomCacheMarker), $nextSecondIdentifierSeparatorPosition - $nextIdentifierSeparatorPosition - 1 - strlen($randomCacheMarker));
                $parts[$level]['identifier'] = $identifier;
                if (strpos($identifier, 'eval=') === 0) {
                    $parts[$level]['type'] = ContentCache::SEGMENT_TYPE_UNCACHED;
                    $parts[$level]['context'] = $contextOrMetadata;
                } elseif (strpos($identifier, 'evalCached=') === 0) {
                    $parts[$level]['type'] = ContentCache::SEGMENT_TYPE_DYNAMICCACHED;
                    $parts[$level]['identifier'] = substr($identifier, 11);
                    $additionalData = json_decode($contextOrMetadata, true);
                    $parts[$level]['context'] = $contextOrMetadata;
                    $parts[$level]['metadata'] = $additionalData['metadata'];
                } else {
                    $parts[$level]['type'] = ContentCache::SEGMENT_TYPE_CACHED;
                    $parts[$level]['metadata'] = $contextOrMetadata;
                }
                $currentPosition = $nextSecondIdentifierSeparatorPosition + 1 + strlen($randomCacheMarker);
                $nextStartPosition = strpos($content, ContentCache::CACHE_SEGMENT_START_TOKEN . $randomCacheMarker, $currentPosition);
            }
        }
        return $parts[0]['content'];
    }

Usage Example

 /**
  * Takes a string of content which includes cache segment markers, extracts the marked segments, writes those
  * segments which can be cached to the actual cache and returns the cleaned up original content without markers.
  *
  * This method is called by the TypoScript Runtime while rendering a TypoScript object.
  *
  * @param string $content The content with an outer cache segment
  * @param boolean $storeCacheEntries Whether to store extracted cache segments in the cache
  * @return string The (pure) content without cache segment markers
  */
 public function processCacheSegments($content, $storeCacheEntries = true)
 {
     $this->parser->extractRenderedSegments($content, $this->randomCacheMarker);
     if ($storeCacheEntries) {
         $segments = $this->parser->getCacheSegments();
         foreach ($segments as $segment) {
             $metadata = explode(';', $segment['metadata']);
             $tagsValue = $metadata[0] === '' ? [] : ($metadata[0] === '*' ? false : explode(',', $metadata[0]));
             // FALSE means we do not need to store the cache entry again (because it was previously fetched)
             if ($tagsValue !== false) {
                 $lifetime = isset($metadata[1]) ? (int) $metadata[1] : null;
                 $this->cache->set($segment['identifier'], $segment['content'], $this->sanitizeTags($tagsValue), $lifetime);
             }
         }
     }
     return $this->parser->getOutput();
 }
All Usage Examples Of Neos\Fusion\Core\Cache\CacheSegmentParser::extractRenderedSegments