From 12bc556d84439dfef7263123fa64038513ded74e Mon Sep 17 00:00:00 2001 From: Jacob Dreesen Date: Thu, 29 Jan 2026 16:52:27 +0100 Subject: [PATCH] Add `withoutAutomaticTagging` method to `CacheActivator` that allows controlling tagging for certain code --- config/services.php | 2 ++ src/CacheActivator.php | 54 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/config/services.php b/config/services.php index 3c06ca5..dcc2a11 100644 --- a/config/services.php +++ b/config/services.php @@ -24,11 +24,13 @@ use function Symfony\Component\DependencyInjection\Loader\Configurator\abstract_arg; use function Symfony\Component\DependencyInjection\Loader\Configurator\param; use function Symfony\Component\DependencyInjection\Loader\Configurator\service; +use function Symfony\Component\DependencyInjection\Loader\Configurator\service_closure; return static function (ContainerConfigurator $configurator) { $services = $configurator->services(); $services->set('neusta_pimcore_http_cache.cache_activator', CacheActivator::class) + ->arg('$responseTagger', service_closure('neusta_pimcore_http_cache.response_tagger')) ->alias(CacheActivator::class, 'neusta_pimcore_http_cache.cache_activator'); $services->set('neusta_pimcore_http_cache.cache_invalidator', CacheInvalidatorAdapter::class) diff --git a/src/CacheActivator.php b/src/CacheActivator.php index d875317..66dd085 100644 --- a/src/CacheActivator.php +++ b/src/CacheActivator.php @@ -2,10 +2,18 @@ namespace Neusta\Pimcore\HttpCacheBundle; +use Neusta\Pimcore\HttpCacheBundle\Cache\CacheTag; +use Neusta\Pimcore\HttpCacheBundle\Cache\CacheTags; + final class CacheActivator { private bool $isCachingActive = true; + public function __construct( + private readonly \Closure $responseTagger, + ) { + } + public function isCachingActive(): bool { return $this->isCachingActive; @@ -20,4 +28,50 @@ public function deactivateCaching(): void { $this->isCachingActive = false; } + + /** + * @template T + * + * @param \Closure(): (T|\Generator) $fn + * + * @return T + */ + public function withoutAutomaticTagging(\Closure $fn): mixed + { + $previous = $this->isCachingActive; + $this->isCachingActive = false; + + $tags = new CacheTags(); + + try { + $result = $fn(); + + if ($result instanceof \Generator) { + $index = 0; + foreach ($result as $key => $yielded) { + ++$index; + + if (!$yielded instanceof CacheTag && !$yielded instanceof CacheTags) { + throw new \LogicException(\sprintf( + 'Invalid yielded value at index %d (key: %s): Expected only "%s" or "%s", got "%s".', + $index, + \is_int($key) || \is_string($key) ? $key : get_debug_type($key), + CacheTag::class, + CacheTags::class, + get_debug_type($yielded), + )); + } + + $tags = $tags->with($yielded); + } + + $result = $result->getReturn(); + } + } finally { + $this->isCachingActive = $previous; + ($this->responseTagger)()->tag($tags); + } + + return $result; + } }