diff --git a/src/Bridges/CacheLatte/CacheExtension.php b/src/Bridges/CacheLatte/CacheExtension.php index b82f99e8..3d38a9d9 100644 --- a/src/Bridges/CacheLatte/CacheExtension.php +++ b/src/Bridges/CacheLatte/CacheExtension.php @@ -53,7 +53,7 @@ public function getPasses(): array return [ 'cacheInitialization' => function (TemplateNode $node): void { if ($this->used) { - $node->head->append(new AuxiliaryNode(fn() => Nodes\CacheNode::class . '::initRuntime($this);')); + $node->head->append(new AuxiliaryNode(fn() => '$this->global->cache->initialize($this);')); } }, ]; @@ -63,7 +63,13 @@ public function getPasses(): array public function getProviders(): array { return [ - 'cacheStorage' => $this->storage, + 'cache' => new Runtime($this->storage), ]; } + + + public function getCacheKey(Latte\Engine $engine): array + { + return ['version' => 2]; + } } diff --git a/src/Bridges/CacheLatte/Nodes/CacheNode.php b/src/Bridges/CacheLatte/Nodes/CacheNode.php index 4faf2591..02e029ff 100644 --- a/src/Bridges/CacheLatte/Nodes/CacheNode.php +++ b/src/Bridges/CacheLatte/Nodes/CacheNode.php @@ -9,15 +9,12 @@ namespace Nette\Bridges\CacheLatte\Nodes; -use Latte; use Latte\Compiler\Nodes\AreaNode; use Latte\Compiler\Nodes\Php\Expression\ArrayNode; use Latte\Compiler\Nodes\StatementNode; use Latte\Compiler\Position; use Latte\Compiler\PrintContext; use Latte\Compiler\Tag; -use Nette; -use Nette\Caching\Cache; /** @@ -45,17 +42,18 @@ public function print(PrintContext $context): string { return $context->format( <<<'XX' - if (Nette\Bridges\CacheLatte\Nodes\CacheNode::createCache($this->global->cacheStorage, %dump, $this->global->cacheStack, %node?)) %line + if ($this->global->cache->createCache(%dump, %node?)) %line try { %node - Nette\Bridges\CacheLatte\Nodes\CacheNode::endCache($this->global->cacheStack) %line; + $this->global->cache->end() %line; } catch (\Throwable $ʟ_e) { - Nette\Bridges\CacheLatte\Nodes\CacheNode::rollback($this->global->cacheStack); throw $ʟ_e; + $this->global->cache->rollback(); + throw $ʟ_e; } XX, - Nette\Utils\Random::generate(), + base64_encode(random_bytes(10)), $this->args, $this->position, $this->content, @@ -69,81 +67,4 @@ public function &getIterator(): \Generator yield $this->args; yield $this->content; } - - - /********************* run-time helpers ****************d*g**/ - - - public static function initRuntime(Latte\Runtime\Template $template): void - { - if (!empty($template->global->cacheStack)) { - $file = (new \ReflectionClass($template))->getFileName(); - if (@is_file($file)) { // @ - may trigger error - end($template->global->cacheStack)->dependencies[Cache::Files][] = $file; - } - } - } - - - /** - * Starts the output cache. Returns Nette\Caching\OutputHelper object if buffering was started. - * @return Nette\Caching\OutputHelper|\stdClass - */ - public static function createCache( - Nette\Caching\Storage $cacheStorage, - string $key, - ?array &$parents, - ?array $args = null, - ) { - if ($args) { - if (array_key_exists('if', $args) && !$args['if']) { - return $parents[] = new \stdClass; - } - - $key = array_merge([$key], array_intersect_key($args, range(0, count($args)))); - } - - if ($parents) { - end($parents)->dependencies[Cache::Items][] = $key; - } - - $cache = new Cache($cacheStorage, 'Nette.Templating.Cache'); - if ($helper = $cache->capture($key)) { - $parents[] = $helper; - - if (isset($args['dependencies'])) { - $args += $args['dependencies'](); - } - - $helper->dependencies[Cache::Tags] = $args['tags'] ?? null; - $helper->dependencies[Cache::Expire] = $args['expiration'] ?? $args['expire'] ?? '+ 7 days'; - } - - return $helper; - } - - - /** - * Ends the output cache. - * @param Nette\Caching\OutputHelper[] $parents - */ - public static function endCache(array &$parents): void - { - $helper = array_pop($parents); - if ($helper instanceof Nette\Caching\OutputHelper) { - $helper->end(); - } - } - - - /** - * @param Nette\Caching\OutputHelper[] $parents - */ - public static function rollback(array &$parents): void - { - $helper = array_pop($parents); - if ($helper instanceof Nette\Caching\OutputHelper) { - $helper->rollback(); - } - } } diff --git a/src/Bridges/CacheLatte/Runtime.php b/src/Bridges/CacheLatte/Runtime.php new file mode 100644 index 00000000..d0546699 --- /dev/null +++ b/src/Bridges/CacheLatte/Runtime.php @@ -0,0 +1,98 @@ + */ + private array $stack = []; + + + public function __construct( + private Nette\Caching\Storage $storage, + ) { + } + + + public function initialize(Latte\Runtime\Template $template): void + { + if ($this->stack) { + $file = (new \ReflectionClass($template))->getFileName(); + if (@is_file($file)) { // @ - may trigger error + end($this->stack)->dependencies[Cache::Files][] = $file; + } + } + } + + + /** + * Starts the output cache. Returns true if buffering was started. + */ + public function createCache(string $key, ?array $args = null): bool + { + if ($args) { + if (array_key_exists('if', $args) && !$args['if']) { + $this->stack[] = new \stdClass; + return true; + } + + $key = array_merge([$key], array_intersect_key($args, range(0, count($args)))); + } + + if ($this->stack) { + end($this->stack)->dependencies[Cache::Items][] = $key; + } + + $cache = new Cache($this->storage, 'Nette.Templating.Cache'); + if ($helper = $cache->capture($key)) { + $this->stack[] = $helper; + + if (isset($args['dependencies'])) { + $args += $args['dependencies'](); + } + + $helper->dependencies[Cache::Tags] = $args['tags'] ?? null; + $helper->dependencies[Cache::Expire] = $args['expiration'] ?? $args['expire'] ?? '+ 7 days'; + } + + return (bool) $helper; + } + + + /** + * Ends the output cache. + */ + public function end(): void + { + $helper = array_pop($this->stack); + if ($helper instanceof OutputHelper) { + $helper->end(); + } + } + + + public function rollback(): void + { + $helper = array_pop($this->stack); + if ($helper instanceof OutputHelper) { + $helper->rollback(); + } + } +} diff --git a/tests/Bridges.Latte3/CacheNode.phpt b/tests/Bridges.Latte3/CacheNode.phpt deleted file mode 100644 index c4d506f8..00000000 --- a/tests/Bridges.Latte3/CacheNode.phpt +++ /dev/null @@ -1,45 +0,0 @@ - ['rum', 'cola']]; - $outputHelper = CacheNode::createCache(new DevNullStorage, 'test', $parents, $dp); - Assert::type(Nette\Caching\OutputHelper::class, $outputHelper); - CacheNode::endCache($parents); - Assert::same($dp + [Cache::Expire => '+ 7 days'], $outputHelper->dependencies); -}); - -test('', function () { - $parents = []; - $dp = [Cache::Tags => ['rum', 'cola']]; - $dpFallback = fn() => $dp; - $outputHelper = CacheNode::createCache(new DevNullStorage, 'test', $parents, ['dependencies' => $dpFallback]); - CacheNode::endCache($parents); - Assert::same($dp + [Cache::Expire => '+ 7 days'], $outputHelper->dependencies); -}); - -test('', function () { - $parents = []; - $dp = [ - Cache::Tags => ['rum', 'cola'], - Cache::Expire => '+ 1 days', - ]; - $dpFallback = fn() => $dp; - $outputHelper = CacheNode::createCache(new DevNullStorage, 'test', $parents, ['dependencies' => $dpFallback]); - CacheNode::endCache($parents); - Assert::same($dp, $outputHelper->dependencies); -}); diff --git a/tests/Bridges.Latte3/Runtime.phpt b/tests/Bridges.Latte3/Runtime.phpt new file mode 100644 index 00000000..83a5121b --- /dev/null +++ b/tests/Bridges.Latte3/Runtime.phpt @@ -0,0 +1,47 @@ + ['rum', 'cola']]; + Assert::true($runtime->createCache('test', $dp)); + $stack = Assert::with($runtime, fn() => $this->stack); + $runtime->end(); + Assert::same($dp + [Cache::Expire => '+ 7 days'], $stack[0]->dependencies); +}); + +test('', function () { + $runtime = new Runtime(new DevNullStorage); + $dp = [Cache::Tags => ['rum', 'cola']]; + $dpFallback = fn() => $dp; + Assert::true($runtime->createCache('test', ['dependencies' => $dpFallback])); + $stack = Assert::with($runtime, fn() => $this->stack); + $runtime->end(); + Assert::same($dp + [Cache::Expire => '+ 7 days'], $stack[0]->dependencies); +}); + +test('', function () { + $runtime = new Runtime(new DevNullStorage); + $dp = [ + Cache::Tags => ['rum', 'cola'], + Cache::Expire => '+ 1 days', + ]; + $dpFallback = fn() => $dp; + Assert::true($runtime->createCache('test', ['dependencies' => $dpFallback])); + $stack = Assert::with($runtime, fn() => $this->stack); + $runtime->end(); + Assert::same($dp, $stack[0]->dependencies); +}); diff --git a/tests/Bridges.Latte3/expected/cache.inc.php b/tests/Bridges.Latte3/expected/cache.inc.php index af4ef1a7..b7594fe2 100644 --- a/tests/Bridges.Latte3/expected/cache.inc.php +++ b/tests/Bridges.Latte3/expected/cache.inc.php @@ -1,14 +1,14 @@ global->cacheStorage, '%[\w]+%', $this->global->cacheStack)) /* line %d% */ + if ($this->global->cache->createCache('%a%')) /* line %d% */ try { echo ' '; echo LR\Filters::escapeHtmlText(($this->filters->lower)($title)) /* line %d% */; echo "\n"; - Nette\Bridges\CacheLatte\Nodes\CacheNode::endCache($this->global->cacheStack) /* line %d% */; + $this->global->cache->end() /* line %d% */; } catch (\Throwable $ʟ_e) { - Nette\Bridges\CacheLatte\Nodes\CacheNode::rollback($this->global->cacheStack); + $this->global->cache->rollback(); throw $ʟ_e; } %A% diff --git a/tests/Bridges.Latte3/expected/cache.php b/tests/Bridges.Latte3/expected/cache.php index ee462bdf..14e5034a 100644 --- a/tests/Bridges.Latte3/expected/cache.php +++ b/tests/Bridges.Latte3/expected/cache.php @@ -3,7 +3,7 @@ echo 'Noncached content '; - if (Nette\Bridges\CacheLatte\Nodes\CacheNode::createCache($this->global->cacheStorage, '%[\w]+%', $this->global->cacheStack, [$id, 'tags' => 'mytag'])) /* line %d% */ + if ($this->global->cache->createCache('%a%', [$id, 'tags' => 'mytag'])) /* line %d% */ try { echo '

'; @@ -14,9 +14,9 @@ $this->createTemplate('include.cache.latte', ['localvar' => 11] + $this->params, 'include')->renderToContentType('html') /* line %d% */; echo "\n"; - Nette\Bridges\CacheLatte\Nodes\CacheNode::endCache($this->global->cacheStack) /* line %d% */; + $this->global->cache->end() /* line %d% */; } catch (\Throwable $ʟ_e) { - Nette\Bridges\CacheLatte\Nodes\CacheNode::rollback($this->global->cacheStack); + $this->global->cache->rollback(); throw $ʟ_e; } } @@ -25,5 +25,5 @@ public function prepare(): array { %A% - Nette\Bridges\CacheLatte\Nodes\CacheNode::initRuntime($this); + $this->global->cache->initialize($this); %A%