Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 12 additions & 27 deletions Classes/Aspects/ContentCacheAspect.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,42 @@
use Neos\Cache\Frontend\StringFrontend;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Aop\JoinPointInterface;
use Neos\Utility\Exception\PropertyNotAccessibleException;
use Neos\Utility\ObjectAccess;

/**
* @Flow\Aspect
* @Flow\Scope("singleton")
*/
#[Flow\Aspect]
#[Flow\Scope("singleton")]
class ContentCacheAspect
{
private $hadUncachedSegments = false;

private $cacheTags = [];

/**
* @var null|int
*/
private $shortestLifetime = null;
private bool $hadUncachedSegments = false;

/**
* @Flow\Inject
* @var StringFrontend
*/
#[Flow\Inject]
protected $cacheFrontend;

/**
* @Flow\Before("method(Neos\Fusion\Core\Cache\ContentCache->(createUncachedSegment)())")
*/
Comment on lines 22 to 24

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also be rewritten to

#[Flow\Before("method(Neos\Fusion\Core\Cache\ContentCache->createUncachedSegment())")]

public function grabUncachedSegment(JoinPointInterface $joinPoint)
public function grabUncachedSegment(JoinPointInterface $joinPoint): void
{
$this->hadUncachedSegments = true;
}

/**
* @Flow\Before("method(Neos\Neos\Fusion\Cache\ContentCacheFlusher->shutdownObject())")
* @param JoinPointInterface $joinPoint
*
* @throws \Neos\Utility\Exception\PropertyNotAccessibleException
* @throws PropertyNotAccessibleException
*/
public function interceptNodeCacheFlush(JoinPointInterface $joinPoint)
#[Flow\Before("method(Neos\Neos\Fusion\Cache\ContentCacheFlusher->shutdownObject())")]
public function interceptNodeCacheFlush(JoinPointInterface $joinPoint): void
{
$object = $joinPoint->getProxy();

$tags = ObjectAccess::getProperty($object, 'tagsToFlush', true);
foreach ($tags as $tag => $_) {
$tag = $this->sanitizeTag($tag);
$this->cacheFrontend->flushByTag($tag);
}
$tags = array_map([$this, 'sanitizeTag'],$tags);
$this->cacheFrontend->flushByTags($tags);
}

/**
* @return bool
*/
public function hasUncachedSegments(): bool
{
return $this->hadUncachedSegments;
Expand All @@ -66,7 +51,7 @@ public function hasUncachedSegments(): bool
* @param string $tag A tag which possibly contains non-allowed characters, for example "NodeType_Acme.Com:Page"
* @return string A cleaned up tag, for example "NodeType_Acme_Com-Page"
*/
protected function sanitizeTag($tag)
protected function sanitizeTag(string $tag): string
{
return strtr($tag, '.:', '_-');
}
Expand Down
31 changes: 13 additions & 18 deletions Classes/Cache/MetadataAwareStringFrontend.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,42 +13,41 @@
*/
class MetadataAwareStringFrontend extends StringFrontend
{
const SEPARATOR = '|';
protected const SEPARATOR = '|';

/**
* Store metadata of all loaded cache entries indexed by identifier
*
* @var array
*/
protected $metadata = [];
protected array $metadata = [];

/**
* @Flow\Inject
* @var Environment
*/
#[Flow\Inject]
protected $environment;

/**
* @Flow\Inject
* @var LoggerInterface
*/
#[Flow\Inject]
protected $logger;

/**
* Set a cache entry and store additional metadata (tags and lifetime)
*
* {@inheritdoc}
*/
public function set(string $entryIdentifier, $content, array $tags = [], int $lifetime = null)
public function set(string $entryIdentifier, $string, array $tags = [], int $lifetime = null): void
{
$content = $this->insertMetadata($content, $entryIdentifier, $tags, $lifetime);
$content = $this->insertMetadata($string, $entryIdentifier, $tags, $lifetime);
parent::set($entryIdentifier, $content, $tags, $lifetime);
}

/**
* {@inheritdoc}
* @throws InvalidDataTypeException
*/
public function get(string $entryIdentifier)
public function get(string $entryIdentifier): bool|string
{
$content = parent::get($entryIdentifier);
if ($content !== false) {
Expand All @@ -60,6 +59,7 @@ public function get(string $entryIdentifier)

/**
* {@inheritdoc}
* @throws InvalidDataTypeException
*/
public function getByTag(string $tag): array
{
Expand All @@ -74,18 +74,13 @@ public function getByTag(string $tag): array
/**
* Insert metadata into the content
*
* @param string $content
* @param string $entryIdentifier The identifier metadata
* @param array $tags The tags metadata
* @param integer $lifetime The lifetime metadata
* @param integer|null $lifetime The lifetime metadata
* @return string The content including the serialized metadata
* @throws InvalidDataTypeException
*/
protected function insertMetadata($content, $entryIdentifier, array $tags, $lifetime)
protected function insertMetadata(string $content, string $entryIdentifier, array $tags, int $lifetime = null): string
{
if (!is_string($content)) {
throw new InvalidDataTypeException('Given data is of type "' . gettype($content) . '", but a string is expected for string cache.', 1433155737);
}
$metadata = [
'identifier' => $entryIdentifier,
'tags' => $tags,
Expand All @@ -105,7 +100,7 @@ protected function insertMetadata($content, $entryIdentifier, array $tags, $life
* @return string The content without metadata
* @throws InvalidDataTypeException
*/
protected function extractMetadata($entryIdentifier, $content)
protected function extractMetadata(string $entryIdentifier, string $content): string
{
$separatorIndex = strpos($content, self::SEPARATOR);
if ($separatorIndex === false) {
Expand Down Expand Up @@ -136,7 +131,7 @@ protected function extractMetadata($entryIdentifier, $content)
/**
* @return array Metadata of all loaded entries (indexed by identifier)
*/
public function getAllMetadata()
public function getAllMetadata(): array
{
return $this->metadata;
}
Expand Down
35 changes: 16 additions & 19 deletions Classes/Middleware/FusionAutoconfigurationMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,40 +16,37 @@ class FusionAutoconfigurationMiddleware implements MiddlewareInterface
public const HEADER_ENABLED = 'X-FullPageCache-EnableFusionAutoconfiguration';

/**
* @Flow\Inject
* @var MetadataAwareStringFrontend
*/
#[Flow\Inject]
protected $contentCache;

/**
* @Flow\Inject
* @var ContentCacheAspect
*/
#[Flow\Inject]
protected $contentCacheAspect;

/**
* @var boolean
* @Flow\InjectConfiguration(path="enabled")
*/
protected $enabled;
#[Flow\InjectConfiguration('enabled')]
protected bool $enabled;

public function process(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
if (!$this->enabled || !$request->hasHeader(RequestCacheMiddleware::HEADER_ENABLED)) {
return $next->handle($request)->withoutHeader(self::HEADER_ENABLED);
return $handler->handle($request)->withoutHeader(self::HEADER_ENABLED);
}

$response = $next->handle($request);
$response = $handler->handle($request);

if (!$response->hasHeader(self::HEADER_ENABLED)) {
return $response;
} else {
$response = $response->withoutHeader(self::HEADER_ENABLED);
}

list($hasUncachedSegments, $tags, $lifetime) = $this->getFusionCacheInformations();
$response = $response->withoutHeader(self::HEADER_ENABLED);

[$hasUncachedSegments, $tags, $lifetime] = $this->getFusionCacheInformation();

if ($response->hasHeader('Set-Cookie') || $hasUncachedSegments) {
if ($hasUncachedSegments || $response->hasHeader('Set-Cookie')) {
return $response;
}

Expand All @@ -63,7 +60,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface

if ($lifetime) {
$response = $response
->withHeader(RequestCacheMiddleware::HEADER_LIFTIME, $lifetime);
->withHeader(RequestCacheMiddleware::HEADER_LIFETIME, $lifetime);
}

return $response;
Expand All @@ -74,14 +71,14 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
*
* @return array with first "hasUncachedSegments", "tags" and "lifetime"
*/
public function getFusionCacheInformations(): array
public function getFusionCacheInformation(): array
{
$lifetime = null;
$tags = [];
$entriesMetadata = $this->contentCache->getAllMetadata();
foreach ($entriesMetadata as $identifier => $metadata) {
$entryTags = isset($metadata['tags']) ? $metadata['tags'] : [];
$entryLifetime = isset($metadata['lifetime']) ? $metadata['lifetime'] : null;
foreach ($entriesMetadata as $metadata) {
$entryTags = $metadata['tags'] ?? [];
$entryLifetime = $metadata['lifetime'] ?? null;
if ($entryLifetime !== null) {
if ($lifetime === null) {
$lifetime = $entryLifetime;
Expand Down
Loading