Skip to content

Commit

Permalink
Merge branch 'release/1.7.41.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
rhukster committed Jun 1, 2023
2 parents d96b023 + 722ce55 commit d4c617f
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 40 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# v1.7.41.2
## 06/01/2023

1. [](#improved)
* Added the ability to set a configurable 'key' for the Twig Cache Tag: `{% cache 'my-key' 600 %}`
1. [](#bugfix)
* Fixed an issue with special characters in slug's would cause redirect loops

# v1.7.41.1
## 05/10/2023

Expand Down
2 changes: 1 addition & 1 deletion system/defines.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

// Some standard defines
define('GRAV', true);
define('GRAV_VERSION', '1.7.41.1');
define('GRAV_VERSION', '1.7.41.2');
define('GRAV_SCHEMA', '1.7.0_2020-11-20_1');
define('GRAV_TESTING', false);

Expand Down
2 changes: 1 addition & 1 deletion system/src/Grav/Common/Service/PagesServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public function register(Container $container)
/** @var Uri $uri */
$uri = $grav['uri'];

$path = $uri->path() ?: '/'; // Don't trim to support trailing slash default routes
$path = $uri->path() ? urldecode($uri->path()) : '/'; // Don't trim to support trailing slash default routes
$page = $pages->dispatch($path);

// Redirection tests
Expand Down
59 changes: 47 additions & 12 deletions system/src/Grav/Common/Twig/Node/TwigNodeCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
namespace Grav\Common\Twig\Node;

use Twig\Compiler;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\Node;
use Twig\Node\NodeOutputInterface;

/**
* Class TwigNodeCache
* @package Grav\Common\Twig\Node
*/
class TwigNodeCache extends Node
class TwigNodeCache extends Node implements NodeOutputInterface
{
/**
* @param string $key unique name for key
Expand All @@ -25,25 +27,58 @@ class TwigNodeCache extends Node
* @param integer $lineno
* @param string|null $tag
*/
public function __construct(string $key, int $lifetime, Node $body, $lineno, $tag = null)
public function __construct(Node $body, ?AbstractExpression $key, ?AbstractExpression $lifetime, array $defaults, int $lineno, string $tag)
{
parent::__construct(array('body' => $body), array( 'key' => $key, 'lifetime' => $lifetime), $lineno, $tag);
$nodes = ['body' => $body];

if ($key !== null) {
$nodes['key'] = $key;
}

if ($lifetime !== null) {
$nodes['lifetime'] = $lifetime;
}

parent::__construct($nodes, $defaults, $lineno, $tag);
}

/**
* {@inheritDoc}
*/
public function compile(Compiler $compiler): void
{
$boo = $this->getAttribute('key');
$compiler->addDebugInfo($this);


// Generate the cache key
if ($this->hasNode('key')) {
$compiler
->write('$key = "twigcache-" . ')
->subcompile($this->getNode('key'))
->raw(";\n");
} else {
$compiler
->write('$key = ')
->string($this->getAttribute('key'))
->raw(";\n");
}

// Set the cache timeout
if ($this->hasNode('lifetime')) {
$compiler
->write('$lifetime = ')
->subcompile($this->getNode('lifetime'))
->raw(";\n");
} else {
$compiler
->write('$lifetime = ')
->write($this->getAttribute('lifetime'))
->raw(";\n");
}

$compiler
->addDebugInfo($this)
->write("\$cache = \\Grav\\Common\\Grav::instance()['cache'];\n")
->write("\$key = \"twigcache-\" . \"" . $this->getAttribute('key') . "\";\n")
->write("\$lifetime = " . $this->getAttribute('lifetime') . ";\n")
->write("\$cache_body = \$cache->fetch(\$key);\n")
->write("if (\$cache_body === false) {\n")
->indent()
->write("\\Grav\\Common\\Grav::instance()['debugger']->addMessage(\"Cache Key: \$key, Lifetime: \$lifetime\");\n")
->write("ob_start();\n")
->indent()
->subcompile($this->getNode('body'))
Expand All @@ -53,6 +88,6 @@ public function compile(Compiler $compiler): void
->write("\$cache->save(\$key, \$cache_body, \$lifetime);\n")
->outdent()
->write("}\n")
->write("echo \$cache_body;\n");
->write("echo '' === \$cache_body ? '' : new Markup(\$cache_body, \$this->env->getCharset());\n");
}
}
}
55 changes: 29 additions & 26 deletions system/src/Grav/Common/Twig/TokenParser/TwigTokenParserCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

use Grav\Common\Grav;
use Grav\Common\Twig\Node\TwigNodeCache;
use Twig\Error\SyntaxError;
use Twig\Token;
use Twig\TokenParser\AbstractTokenParser;

Expand All @@ -22,50 +21,54 @@
* {{ some_complex_work() }}
* {% endcache %}
*
* Where the `600` is an optional lifetime in seconds
* Also can provide a unique key for the cache:
*
* {% cache "prefix-"~lang 600 %}
*
* Where the "prefix-"~lang will use a unique key based on the current language. "prefix-en" for example
*/
class TwigTokenParserCache extends AbstractTokenParser
{
/**
* @param Token $token
* @return TwigNodeCache
* @throws SyntaxError
*/
public function parse(Token $token)
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$key = $this->parser->getVarName() . $lineno;
$lifetime = Grav::instance()['cache']->getLifetime();
$lineno = $token->getLine();

// Check for optional lifetime override
if (!$stream->test(Token::BLOCK_END_TYPE)) {
$lifetime_expr = $this->parser->getExpressionParser()->parseExpression();
$lifetime = $lifetime_expr->getAttribute('value');
// Parse the optional key and timeout parameters
$defaults = [
'key' => $this->parser->getVarName() . $lineno,
'lifetime' => Grav::instance()['cache']->getLifetime()
];

$key = null;
$lifetime = null;
while (!$stream->test(Token::BLOCK_END_TYPE)) {
if ($stream->test(Token::STRING_TYPE)) {
$key = $this->parser->getExpressionParser()->parseExpression();
} elseif ($stream->test(Token::NUMBER_TYPE)) {
$lifetime = $this->parser->getExpressionParser()->parseExpression();
} else {
throw new \Twig\Error\SyntaxError("Unexpected token type in cache tag.", $token->getLine(), $stream->getSourceContext());
}
}

$stream->expect(Token::BLOCK_END_TYPE);
$body = $this->parser->subparse(array($this, 'decideCacheEnd'), true);

// Parse the content inside the cache block
$body = $this->parser->subparse([$this, 'decideCacheEnd'], true);

$stream->expect(Token::BLOCK_END_TYPE);

return new TwigNodeCache($key, $lifetime, $body, $lineno, $this->getTag());
return new TwigNodeCache($body, $key, $lifetime, $defaults, $lineno, $this->getTag());
}

/**
* Decide if current token marks end of cache block.
*
* @param Token $token
* @return bool
*/
public function decideCacheEnd(Token $token): bool
{
return $token->test('endcache');
}
/**
* {@inheritDoc}
*/

public function getTag(): string
{
return 'cache';
}
}
}

0 comments on commit d4c617f

Please sign in to comment.