Skip to content

Commit

Permalink
Add cacheResponse tag
Browse files Browse the repository at this point in the history
  • Loading branch information
timkelty committed May 10, 2024
1 parent ed76452 commit b28f4cb
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/web/twig/Extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use craft\web\twig\nodevisitors\EventTagFinder;
use craft\web\twig\nodevisitors\GetAttrAdjuster;
use craft\web\twig\nodevisitors\Profiler;
use craft\web\twig\tokenparsers\CacheResponseTokenParser;
use craft\web\twig\tokenparsers\CacheTokenParser;
use craft\web\twig\tokenparsers\DdTokenParser;
use craft\web\twig\tokenparsers\DeprecatedTokenParser;
Expand Down Expand Up @@ -130,6 +131,7 @@ public function getNodeVisitors(): array
public function getTokenParsers(): array
{
return [
new CacheResponseTokenParser(),
new CacheTokenParser(),
new DeprecatedTokenParser(),
new DdTokenParser(),
Expand Down
57 changes: 57 additions & 0 deletions src/web/twig/nodes/CacheResponseNode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php
/**
* @link https://craftcms.com/
* @copyright Copyright (c) Pixel & Tonic, Inc.
* @license https://craftcms.github.io/license/
*/

namespace craft\web\twig\nodes;

use DateTimeImmutable;
use Twig\Compiler;
use Twig\Node\Node;

/**
* Class CacheResponseNode
*
* @author Pixel & Tonic, Inc. <[email protected]>
* @since 4.10.0
*/
class CacheResponseNode extends Node
{
/**
* @inheritdoc
*/
public function compile(Compiler $compiler): void
{
$durationNum = $this->getAttribute('durationNum');

$duration = $durationNum === null ? null : self::durationInSeconds(
$durationNum,
$this->getAttribute('durationUnit'),
);
$line = sprintf(
'\Craft::$app->getResponse()->setCacheHeaders(%s);',
$duration,
);

$compiler->write("$line\n");
}

private static function durationInSeconds($number, $unit): int
{
if ($unit === 'week') {
if ($number == 1) {
$number = 7;
$unit = 'days';
} else {
$unit = 'weeks';
}
}

$now = new DateTimeImmutable();
$then = $now->modify("+$number $unit");

return $then->getTimestamp() - $now->getTimestamp();
}
}
83 changes: 83 additions & 0 deletions src/web/twig/tokenparsers/CacheResponseTokenParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php
/**
* @link https://craftcms.com/
* @copyright Copyright (c) Pixel & Tonic, Inc.
* @license https://craftcms.github.io/license/
*/

namespace craft\web\twig\tokenparsers;

use craft\web\twig\nodes\CacheResponseNode;
use Twig\Token;
use Twig\TokenParser\AbstractTokenParser;

/**
* Class CacheResponse
*
* @author Pixel & Tonic, Inc. <[email protected]>
* @since 4.10.0
*/
class CacheResponseTokenParser extends AbstractTokenParser
{
/**
* @inheritdoc
*/
public function parse(Token $token): CacheResponseNode
{
$lineno = $token->getLine();
$parser = $this->parser;
$stream = $parser->getStream();

$nodes = [];

$attributes = [
'durationNum' => null,
'durationUnit' => null,
];

if ($stream->test(Token::NAME_TYPE, 'never')) {
$stream->next();
$attributes['durationNum'] = 0;
} elseif ($stream->test(Token::NAME_TYPE, 'for')) {
$stream->next();
$attributes['durationNum'] = $stream->expect(Token::NUMBER_TYPE)->getValue();
$attributes['durationUnit'] = $stream->expect(Token::NAME_TYPE,
[
'sec',
'secs',
'second',
'seconds',
'min',
'mins',
'minute',
'minutes',
'hour',
'hours',
'day',
'days',
'fortnight',
'fortnights',
'forthnight',
'forthnights',
'month',
'months',
'year',
'years',
'week',
'weeks',
])->getValue();
}

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

return new CacheResponseNode($nodes, $attributes, $lineno, $this->getTag());
}

/**
* @inheritdoc
*/
public function getTag(): string
{
return 'cacheResponse';
}
}

0 comments on commit b28f4cb

Please sign in to comment.