-
-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
387 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<?php | ||
|
||
/** | ||
* This file is part of the Nette Framework (https://nette.org) | ||
* Copyright (c) 2004 David Grudl (https://davidgrudl.com) | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Nette\Bridges\CacheLatte; | ||
|
||
use Latte; | ||
use Latte\Compiler\Nodes\AuxiliaryNode; | ||
use Latte\Compiler\Nodes\TemplateNode; | ||
use Latte\Compiler\Tag; | ||
use Latte\Engine; | ||
use Nette\Caching\Storage; | ||
|
||
|
||
/** | ||
* Latte v3 extension for Nette Caching | ||
*/ | ||
final class CacheExtension extends Latte\Extension | ||
{ | ||
private bool $used; | ||
private Storage $storage; | ||
|
||
|
||
public function __construct(Storage $storage) | ||
{ | ||
$this->storage = $storage; | ||
} | ||
|
||
|
||
public function beforeCompile(Latte\Engine $engine): void | ||
{ | ||
$this->used = false; | ||
} | ||
|
||
|
||
public function getTags(): array | ||
{ | ||
return [ | ||
'cache' => function (Tag $tag): \Generator { | ||
$this->used = true; | ||
return Nodes\CacheNode::create($tag); | ||
}, | ||
]; | ||
} | ||
|
||
|
||
public function getPasses(): array | ||
{ | ||
return [ | ||
'cacheInitialization' => function (TemplateNode $node): void { | ||
if ($this->used) { | ||
$node->head->append(new AuxiliaryNode(fn() => Nodes\CacheNode::class . '::initRuntime($this);')); | ||
} | ||
}, | ||
]; | ||
} | ||
|
||
|
||
public function beforeRender(Engine $engine): void | ||
{ | ||
$engine->addProvider('cacheStorage', $this->storage); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
<?php | ||
|
||
/** | ||
* This file is part of the Latte (https://latte.nette.org) | ||
* Copyright (c) 2008 David Grudl (https://davidgrudl.com) | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
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; | ||
|
||
|
||
/** | ||
* {cache} ... {/cache} | ||
*/ | ||
class CacheNode extends StatementNode | ||
{ | ||
public ArrayNode $args; | ||
public AreaNode $content; | ||
public ?Position $endLine; | ||
|
||
|
||
/** @return \Generator<int, ?array, array{AreaNode, ?Tag}, static> */ | ||
public static function create(Tag $tag): \Generator | ||
{ | ||
$node = new static; | ||
$node->args = $tag->parser->parseArguments(); | ||
[$node->content, $endTag] = yield; | ||
$node->endLine = $endTag?->position; | ||
return $node; | ||
} | ||
|
||
|
||
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 | ||
try { | ||
%node | ||
Nette\Bridges\CacheLatte\Nodes\CacheNode::endCache($this->global->cacheStack) %line; | ||
} catch (\Throwable $ʟ_e) { | ||
Nette\Bridges\CacheLatte\Nodes\CacheNode::rollback($this->global->cacheStack); throw $ʟ_e; | ||
} | ||
|
||
|
||
XX, | ||
Nette\Utils\Random::generate(), | ||
$this->args, | ||
$this->position, | ||
$this->content, | ||
$this->endLine, | ||
); | ||
} | ||
|
||
|
||
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(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
use Nette\Bridges\CacheLatte\Nodes\CacheNode; | ||
use Nette\Caching\Cache; | ||
use Nette\Caching\Storages\DevNullStorage; | ||
use Tester\Assert; | ||
|
||
require __DIR__ . '/../bootstrap.php'; | ||
|
||
if (version_compare(Latte\Engine::VERSION, '3', '<')) { | ||
Tester\Environment::skip('Test for Latte 3'); | ||
} | ||
|
||
|
||
test('', function () { | ||
$parents = []; | ||
$dp = [Cache::Tags => ['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 = function () use ($dp) { | ||
return $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 = function () use ($dp) { | ||
return $dp; | ||
}; | ||
$outputHelper = CacheNode::createCache(new DevNullStorage, 'test', $parents, ['dependencies' => $dpFallback]); | ||
CacheNode::endCache($parents); | ||
Assert::same($dp, $outputHelper->dependencies); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
Noncached content | ||
|
||
|
||
<h1>HELLO</h1> | ||
|
||
<p>Included file (11)</p> | ||
|
||
hello |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?php | ||
%A% | ||
if (Nette\Bridges\CacheLatte\Nodes\CacheNode::createCache($this->global->cacheStorage, '%[\w]+%', $this->global->cacheStack)) /* 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% */; | ||
} catch (\Throwable $ʟ_e) { | ||
Nette\Bridges\CacheLatte\Nodes\CacheNode::rollback($this->global->cacheStack); | ||
throw $ʟ_e; | ||
} | ||
%A% |
Oops, something went wrong.