Neos.Fusion/Classes/Core/Cache/CacheSegmentParser.php
protected function parseSegment($currentPosition)
    {
        $nextStartPosition = $this->calculateNextTokenPosition($currentPosition, ContentCache::CACHE_SEGMENT_START_TOKEN);
        if ($nextStartPosition !== $currentPosition) {
            throw new Exception(sprintf('The current position (%d) is not the start of a segment, next start position %d', $currentPosition, $nextStartPosition), 1472464124);
        }

        $segmentData = [
            'identifier' => '',
            'type' => '',
            'context' => '',
            'metadata' => '',
            'content' => '',
            'cleanContent' => '',
            'embed' => ''
        ];

        $nextEndPosition = $this->calculateNextTokenPosition($currentPosition, ContentCache::CACHE_SEGMENT_END_TOKEN);
        $currentPosition = $this->calculateCurrentPosition($nextStartPosition);
        $nextStartPosition = $this->calculateNextTokenPosition($currentPosition, ContentCache::CACHE_SEGMENT_START_TOKEN);

        $nextIdentifierSeparatorPosition = $this->calculateNextTokenPosition($currentPosition, ContentCache::CACHE_SEGMENT_SEPARATOR_TOKEN);
        $nextSecondIdentifierSeparatorPosition = $this->calculateNextTokenPosition($nextIdentifierSeparatorPosition + 1, ContentCache::CACHE_SEGMENT_SEPARATOR_TOKEN);

        if ($nextIdentifierSeparatorPosition === false || $nextSecondIdentifierSeparatorPosition === false
            || $nextStartPosition !== false && $nextStartPosition < $nextSecondIdentifierSeparatorPosition
            || $nextEndPosition !== false && $nextEndPosition < $nextSecondIdentifierSeparatorPosition
        ) {
            throw new Exception(sprintf('Missing segment separator token after position %d', $currentPosition), 1391855139);
        }

        $identifier = $this->extractContent($currentPosition, $nextIdentifierSeparatorPosition);
        $contextOrMetadata = $this->extractContent($this->calculateCurrentPosition($nextIdentifierSeparatorPosition), $nextSecondIdentifierSeparatorPosition);

        $segmentData['identifier'] = $identifier;
        $segmentData['type'] = ContentCache::SEGMENT_TYPE_CACHED;
        $segmentData['metadata'] = $contextOrMetadata;
        $segmentData['context'] = $contextOrMetadata;

        if (strpos($identifier, 'eval=') === 0) {
            $segmentData['type'] = ContentCache::SEGMENT_TYPE_UNCACHED;
            unset($segmentData['metadata']);
            $this->uncachedPartCount++;
        }

        if (strpos($identifier, 'evalCached=') === 0) {
            $segmentData['type'] = ContentCache::SEGMENT_TYPE_DYNAMICCACHED;
            $segmentData['identifier'] = substr($identifier, 11);
            $additionalData = json_decode($contextOrMetadata, true);
            $segmentData['metadata'] = $additionalData['metadata'];
            $this->uncachedPartCount++;
        }

        $currentPosition = $this->calculateCurrentPosition($nextSecondIdentifierSeparatorPosition);
        $segmentData = $this->extractContentAndSubSegments($currentPosition, $segmentData);

        if ($segmentData['type'] === ContentCache::SEGMENT_TYPE_CACHED || $segmentData['type'] === ContentCache::SEGMENT_TYPE_DYNAMICCACHED) {
            $this->cacheSegments[$identifier] = $this->reduceSegmentDataToCacheRelevantInformation($segmentData);
        }

        return $segmentData;
    }
protected function parseSegment($currentPosition)
    {
        $nextStartPosition = $this->calculateNextTokenPosition($currentPosition, ContentCache::CACHE_SEGMENT_START_TOKEN);
        if ($nextStartPosition !== $currentPosition) {
            throw new Exception(sprintf('The current position (%d) is not the start of a segment, next start position %d', $currentPosition, $nextStartPosition), 1472464124);
        }

        $segmentData = [
            'identifier' => '',
            'type' => '',
            'context' => '',
            'metadata' => '',
            'content' => '',
            'cleanContent' => '',
            'embed' => ''
        ];

        $nextEndPosition = $this->calculateNextTokenPosition($currentPosition, ContentCache::CACHE_SEGMENT_END_TOKEN);
        $currentPosition = $this->calculateCurrentPosition($nextStartPosition);
        $nextStartPosition = $this->calculateNextTokenPosition($currentPosition, ContentCache::CACHE_SEGMENT_START_TOKEN);

        $nextIdentifierSeparatorPosition = $this->calculateNextTokenPosition($currentPosition, ContentCache::CACHE_SEGMENT_SEPARATOR_TOKEN);
        $nextSecondIdentifierSeparatorPosition = $this->calculateNextTokenPosition($nextIdentifierSeparatorPosition + 1, ContentCache::CACHE_SEGMENT_SEPARATOR_TOKEN);

        if ($nextIdentifierSeparatorPosition === false || $nextSecondIdentifierSeparatorPosition === false
            || $nextStartPosition !== false && $nextStartPosition < $nextSecondIdentifierSeparatorPosition
            || $nextEndPosition !== false && $nextEndPosition < $nextSecondIdentifierSeparatorPosition
        ) {
            throw new Exception(sprintf('Missing segment separator token after position %d', $currentPosition), 1391855139);
        }

        $identifier = $this->extractContent($currentPosition, $nextIdentifierSeparatorPosition);
        $contextOrMetadata = $this->extractContent($this->calculateCurrentPosition($nextIdentifierSeparatorPosition), $nextSecondIdentifierSeparatorPosition);

        $segmentData['identifier'] = $identifier;
        $segmentData['type'] = ContentCache::SEGMENT_TYPE_CACHED;
        $segmentData['metadata'] = $contextOrMetadata;
        $segmentData['context'] = $contextOrMetadata;

        if (strpos($identifier, 'eval=') === 0) {
            $segmentData['type'] = ContentCache::SEGMENT_TYPE_UNCACHED;
            unset($segmentData['metadata']);
            $this->uncachedPartCount++;
        }

        if (strpos($identifier, 'evalCached=') === 0) {
            $segmentData['type'] = ContentCache::SEGMENT_TYPE_DYNAMICCACHED;
            $segmentData['identifier'] = substr($identifier, 11);
            $additionalData = json_decode($contextOrMetadata, true);
            $segmentData['metadata'] = $additionalData['metadata'];
            $this->uncachedPartCount++;
        }

        $currentPosition = $this->calculateCurrentPosition($nextSecondIdentifierSeparatorPosition);
        $segmentData = $this->extractContentAndSubSegments($currentPosition, $segmentData);

        if ($segmentData['type'] === ContentCache::SEGMENT_TYPE_CACHED || $segmentData['type'] === ContentCache::SEGMENT_TYPE_DYNAMICCACHED) {
            $this->cacheSegments[$identifier] = $this->reduceSegmentDataToCacheRelevantInformation($segmentData);
        }

        return $segmentData;
    }
protected function parseSegment ( $ currentPosition ) { $ nextStartPosition = $ this -> calculateNextTokenPosition ( $ currentPosition , ContentCache :: CACHE_SEGMENT_START_TOKEN ) ; if ( $ nextStartPosition !== $ currentPosition ) { throw new Exception ( sprintf ( 'The current position (%d) is not the start of a segment, next start position %d' , $ currentPosition , $ nextStartPosition ) , 1472464124 ) ; } $ segmentData = [ 'identifier' => '' , 'type' => '' , 'context' => '' , 'metadata' => '' , 'content' => '' , 'cleanContent' => '' , 'embed' => '' ] ; $ nextEndPosition = $ this -> calculateNextTokenPosition ( $ currentPosition , ContentCache :: CACHE_SEGMENT_END_TOKEN ) ; $ currentPosition = $ this -> calculateCurrentPosition ( $ nextStartPosition ) ; $ nextStartPosition = $ this -> calculateNextTokenPosition ( $ currentPosition , ContentCache :: CACHE_SEGMENT_START_TOKEN ) ; $ nextIdentifierSeparatorPosition = $ this -> calculateNextTokenPosition ( $ currentPosition , ContentCache :: CACHE_SEGMENT_SEPARATOR_TOKEN ) ; $ nextSecondIdentifierSeparatorPosition = $ this -> calculateNextTokenPosition ( $ nextIdentifierSeparatorPosition + 1 , ContentCache :: CACHE_SEGMENT_SEPARATOR_TOKEN ) ; if ( $ nextIdentifierSeparatorPosition === false || $ nextSecondIdentifierSeparatorPosition === false || $ nextStartPosition !== false && $ nextStartPosition < $ nextSecondIdentifierSeparatorPosition || $ nextEndPosition !== false && $ nextEndPosition < $ nextSecondIdentifierSeparatorPosition ) { throw new Exception ( sprintf ( 'Missing segment separator token after position %d' , $ currentPosition ) , 1391855139 ) ; } $ identifier = $ this -> extractContent ( $ currentPosition , $ nextIdentifierSeparatorPosition ) ; $ contextOrMetadata = $ this -> extractContent ( $ this -> calculateCurrentPosition ( $ nextIdentifierSeparatorPosition ) , $ nextSecondIdentifierSeparatorPosition ) ; $ segmentData [ 'identifier' ] = $ identifier ; $ segmentData [ 'type' ] = ContentCache :: SEGMENT_TYPE_CACHED ; $ segmentData [ 'metadata' ] = $ contextOrMetadata ; $ segmentData [ 'context' ] = $ contextOrMetadata ; if ( strpos ( $ identifier , 'eval=' ) === 0 ) { $ segmentData [ 'type' ] = ContentCache :: SEGMENT_TYPE_UNCACHED ; unset ( $ segmentData [ 'metadata' ] ) ; $ this -> uncachedPartCount ++ ; } if ( strpos ( $ identifier , 'evalCached=' ) === 0 ) { $ segmentData [ 'type' ] = ContentCache :: SEGMENT_TYPE_DYNAMICCACHED ; $ segmentData [ 'identifier' ] = substr ( $ identifier , 11 ) ; $ additionalData = json_decode ( $ contextOrMetadata , true ) ; $ segmentData [ 'metadata' ] = $ additionalData [ 'metadata' ] ; $ this -> uncachedPartCount ++ ; } $ currentPosition = $ this -> calculateCurrentPosition ( $ nextSecondIdentifierSeparatorPosition ) ; $ segmentData = $ this -> extractContentAndSubSegments ( $ currentPosition , $ segmentData ) ; if ( $ segmentData [ 'type' ] === ContentCache :: SEGMENT_TYPE_CACHED || $ segmentData [ 'type' ] === ContentCache :: SEGMENT_TYPE_DYNAMICCACHED ) { $ this -> cacheSegments [ $ identifier ] = $ this -> reduceSegmentDataToCacheRelevantInformation ( $ segmentData ) ; } return $ segmentData ; }
Parses a segment at current position diving down into nested segments.

The returned segmentData array has the following keys:
- identifier -> The identifier of this entry for cached segments (or the eval expression for everything else)
- type -> The type of segment (one of the ContentCache::SEGMENT_TYPE_* constants)
- context -> eventual context information saved for a cached segment (optional)
- metadata -> cache entry metadata like tags
- content -> the content of this segment including embed code for sub segments
- cleanContent -> the raw content without any cache references for this segment and all sub segments
- embed -> the placeholder content for this segment to be used in "content" of parent segments

@param integer $currentPosition
@return array
@throws Exception
Parses a segment at current position diving down into nested segments .