Feature: #102422 - Introduce CacheDataCollector Api

See forge#102422

Description

A new API has been introduced to collect cache tags and their corresponding lifetime. This API is used in TYPO3 to accumulate cache tags from page cache and content object cache.

The API is implemented as a new PSR-7 request attribute 'frontend.cache.collector', which makes this API independent from TSFE.

Every cache tag has a lifetime. The minimum lifetime is calculated from all given cache tags. By default, the lifetime of a cache tag is set to PHP_INT_MAX, so it expires many years in the future. API users must therefore define the lifetime of a cache tag individually.

The current TSFE API is deprecated in favor of the new API, as the current cache tag API implementation does not allow to set lifetime and extension authors had to work around it.

Example

Add a single cache tag with 24 hours lifetime
use TYPO3\CMS\Core\Cache\CacheTag;

$cacheDataCollector = $request->getAttribute('frontend.cache.collector');
$cacheDataCollector->addCacheTags(
    new CacheTag('tx_myextension_mytable', 86400)
);
Copied!
Add multiple cache tags with different lifetimes
use TYPO3\CMS\Core\Cache\CacheTag;

$cacheDataCollector = $request->getAttribute('frontend.cache.collector');
$cacheDataCollector->addCacheTags(
    new CacheTag('tx_myextension_mytable_123', 3600),
    new CacheTag('tx_myextension_mytable_456', 2592000)
);
Copied!
Remove a cache tag
use TYPO3\CMS\Core\Cache\CacheTag;

$cacheDataCollector = $request->getAttribute('frontend.cache.collector');
$cacheDataCollector->removeCacheTags(
    new CacheTag('tx_myextension_mytable_123')
);
Copied!
Remove multiple cache tags
use TYPO3\CMS\Core\Cache\CacheTag;

$cacheDataCollector = $request->getAttribute('frontend.cache.collector');
$cacheDataCollector->removeCacheTags(
    new CacheTag('tx_myextension_mytable_123'),
    new CacheTag('tx_myextension_mytable_456')
);
Copied!
Get minimum lifetime, calculated from all cache tags
$cacheDataCollector = $request->getAttribute('frontend.cache.collector');
$cacheDataCollector->getLifetime();
Copied!
Get all cache tags
$cacheDataCollector = $request->getAttribute('frontend.cache.collector');
$cacheDataCollector->getCacheTags();
Copied!

The following event should only be used in code that has no access to the request attribute 'frontend.cache.collector', it is marked @internal and may vanish: It designed to allow passive cache-data signaling, without exactly knowing the current context and not having the current request at hand. It is not meant to allow for cache tag interception or extension.

Add cache tag without access to the request object
$this->eventDispatcher->dispatch(
    new AddCacheTagEvent(
        new CacheTag('tx_myextension_mytable_123', 3600)
    )
);
Copied!