From f17875da7a0130724976bf2df59a4fcb67696adf Mon Sep 17 00:00:00 2001 From: discomrade Date: Sun, 27 Feb 2022 10:44:34 -0100 Subject: [PATCH] Enable compatibility with Twig 2.x --- composer.json | 2 +- composer.lock | 4 +- inc/lib/twig/extensions/Extension/I18n.php | 40 +++----- inc/lib/twig/extensions/Node/Trans.php | 97 ++++++++++++------- inc/lib/twig/extensions/TokenParser/Trans.php | 73 ++++++++------ inc/template.php | 6 +- 6 files changed, 123 insertions(+), 99 deletions(-) diff --git a/composer.json b/composer.json index 8dc18dcd..eabd6a12 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "ext-mbstring": ">=5.4", "ext-gd": ">=5.4", "ext-pdo": ">=5.4", - "twig/twig": "^1.44.2", + "twig/twig": "^2.14.11", "lifo/ip": "^1.0", "gettext/gettext": "^1.0", "mrclay/minify": "^2.1.6", diff --git a/composer.lock b/composer.lock index 3012c9e0..171e053e 100644 --- a/composer.lock +++ b/composer.lock @@ -348,7 +348,7 @@ }, { "name": "twig/twig", - "version": "v1.44.5", + "version": "v2.14.11", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", @@ -410,7 +410,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v1.44.5" + "source": "https://github.com/twigphp/Twig/tree/v2.14.11" }, "funding": [ { diff --git a/inc/lib/twig/extensions/Extension/I18n.php b/inc/lib/twig/extensions/Extension/I18n.php index bc6a05bd..897add6f 100644 --- a/inc/lib/twig/extensions/Extension/I18n.php +++ b/inc/lib/twig/extensions/Extension/I18n.php @@ -3,43 +3,29 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) 2010-2019 Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -class Twig_Extensions_Extension_I18n extends Twig_Extension + +namespace Twig\Extensions; + +use Twig\Extension\AbstractExtension; +use Twig\Extensions\TokenParser\TransTokenParser; +use Twig\TwigFilter; + +class I18nExtension extends AbstractExtension { - /** - * Returns the token parser instances to add to the existing list. - * - * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances - */ public function getTokenParsers() { - return array(new Twig_Extensions_TokenParser_Trans()); + return [new TransTokenParser()]; } - /** - * Returns a list of filters to add to the existing list. - * - * @return array An array of filters - */ public function getFilters() { - return array( - new Twig_SimpleFilter('trans', 'gettext'), - ); - } - - /** - * Returns the name of the extension. - * - * @return string The extension name - */ - public function getName() - { - return 'i18n'; + return [ + new TwigFilter('trans', 'gettext'), + ]; } } - diff --git a/inc/lib/twig/extensions/Node/Trans.php b/inc/lib/twig/extensions/Node/Trans.php index e7dc1ca8..506046a1 100644 --- a/inc/lib/twig/extensions/Node/Trans.php +++ b/inc/lib/twig/extensions/Node/Trans.php @@ -3,43 +3,66 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) 2010-2019 Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ +namespace Twig\Extensions\Node; + +use Twig\Compiler; +use Twig\Node\CheckToStringNode; +use Twig\Node\Expression\AbstractExpression; +use Twig\Node\Expression\ConstantExpression; +use Twig\Node\Expression\FilterExpression; +use Twig\Node\Expression\NameExpression; +use Twig\Node\Expression\TempNameExpression; +use Twig\Node\Node; +use Twig\Node\PrintNode; + /** - * Represents a trans node. - * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ -class Twig_Extensions_Node_Trans extends Twig_Node +class TransNode extends Node { - public function __construct(Twig_NodeInterface $body, Twig_NodeInterface $plural = null, Twig_Node_Expression $count = null, $lineno, $tag = null) + public function __construct(Node $body, Node $plural = null, AbstractExpression $count = null, Node $notes = null, $lineno, $tag = null) { - parent::__construct(array('count' => $count, 'body' => $body, 'plural' => $plural), array(), $lineno, $tag); + $nodes = ['body' => $body]; + if (null !== $count) { + $nodes['count'] = $count; + } + if (null !== $plural) { + $nodes['plural'] = $plural; + } + if (null !== $notes) { + $nodes['notes'] = $notes; + } + + parent::__construct($nodes, [], $lineno, $tag); } - /** - * Compiles the node to PHP. - * - * @param Twig_Compiler A Twig_Compiler instance - */ - public function compile(Twig_Compiler $compiler) + public function compile(Compiler $compiler) { $compiler->addDebugInfo($this); list($msg, $vars) = $this->compileString($this->getNode('body')); - if (null !== $this->getNode('plural')) { + if ($this->hasNode('plural')) { list($msg1, $vars1) = $this->compileString($this->getNode('plural')); $vars = array_merge($vars, $vars1); } - $function = null === $this->getNode('plural') ? 'gettext' : 'ngettext'; + $function = $this->getTransFunction($this->hasNode('plural')); + + if ($this->hasNode('notes')) { + $message = trim($this->getNode('notes')->getAttribute('data')); + + // line breaks are not allowed cause we want a single line comment + $message = str_replace(["\n", "\r"], ' ', $message); + $compiler->write("// notes: {$message}\n"); + } if ($vars) { $compiler @@ -47,12 +70,12 @@ class Twig_Extensions_Node_Trans extends Twig_Node ->subcompile($msg) ; - if (null !== $this->getNode('plural')) { + if ($this->hasNode('plural')) { $compiler ->raw(', ') ->subcompile($msg1) ->raw(', abs(') - ->subcompile($this->getNode('count')) + ->subcompile($this->hasNode('count') ? $this->getNode('count') : null) ->raw(')') ; } @@ -64,7 +87,7 @@ class Twig_Extensions_Node_Trans extends Twig_Node $compiler ->string('%count%') ->raw(' => abs(') - ->subcompile($this->getNode('count')) + ->subcompile($this->hasNode('count') ? $this->getNode('count') : null) ->raw('), ') ; } else { @@ -84,12 +107,12 @@ class Twig_Extensions_Node_Trans extends Twig_Node ->subcompile($msg) ; - if (null !== $this->getNode('plural')) { + if ($this->hasNode('plural')) { $compiler ->raw(', ') ->subcompile($msg1) ->raw(', abs(') - ->subcompile($this->getNode('count')) + ->subcompile($this->hasNode('count') ? $this->getNode('count') : null) ->raw(')') ; } @@ -98,28 +121,27 @@ class Twig_Extensions_Node_Trans extends Twig_Node } } - protected function compileString(Twig_NodeInterface $body) + private function compileString(Node $body): array { - if ($body instanceof Twig_Node_Expression_Name || $body instanceof Twig_Node_Expression_Constant || $body instanceof Twig_Node_Expression_TempName) { - return array($body, array()); + if ($body instanceof NameExpression || $body instanceof ConstantExpression || $body instanceof TempNameExpression) { + return [$body, []]; } - $vars = array(); - if (count($body)) { + $vars = []; + if (\count($body)) { $msg = ''; foreach ($body as $node) { - if (get_class($node) === 'Twig_Node' && $node->getNode(0) instanceof Twig_Node_SetTemp) { - $node = $node->getNode(1); - } - - if ($node instanceof Twig_Node_Print) { + if ($node instanceof PrintNode) { $n = $node->getNode('expr'); - while ($n instanceof Twig_Node_Expression_Filter) { + while ($n instanceof FilterExpression) { $n = $n->getNode('node'); } + while ($n instanceof CheckToStringNode) { + $n = $n->getNode('expr'); + } $msg .= sprintf('%%%s%%', $n->getAttribute('name')); - $vars[] = new Twig_Node_Expression_Name($n->getAttribute('name'), $n->getLine()); + $vars[] = new NameExpression($n->getAttribute('name'), $n->getTemplateLine()); } else { $msg .= $node->getAttribute('data'); } @@ -128,6 +150,11 @@ class Twig_Extensions_Node_Trans extends Twig_Node $msg = $body->getAttribute('data'); } - return array(new Twig_Node(array(new Twig_Node_Expression_Constant(trim($msg), $body->getLine()))), $vars); + return [new Node([new ConstantExpression(trim($msg), $body->getTemplateLine())]), $vars]; + } + + private function getTransFunction(bool $plural): string + { + return $plural ? 'ngettext' : 'gettext'; } -} \ No newline at end of file +} diff --git a/inc/lib/twig/extensions/TokenParser/Trans.php b/inc/lib/twig/extensions/TokenParser/Trans.php index 4a0fad41..bf8eefba 100644 --- a/inc/lib/twig/extensions/TokenParser/Trans.php +++ b/inc/lib/twig/extensions/TokenParser/Trans.php @@ -3,78 +3,89 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) 2010-2019 Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -class Twig_Extensions_TokenParser_Trans extends Twig_TokenParser + +namespace Twig\Extensions\TokenParser; + +use Twig\Error\SyntaxError; +use Twig\Extensions\Node\TransNode; +use Twig\Node\Expression\NameExpression; +use Twig\Node\Node; +use Twig\Node\PrintNode; +use Twig\Node\TextNode; +use Twig\Token; +use Twig\TokenParser\AbstractTokenParser; + +class TransTokenParser extends AbstractTokenParser { - /** - * Parses a token and returns a node. - * - * @param Twig_Token $token A Twig_Token instance - * - * @return Twig_NodeInterface A Twig_NodeInterface instance - */ - public function parse(Twig_Token $token) + public function parse(Token $token) { $lineno = $token->getLine(); $stream = $this->parser->getStream(); $count = null; $plural = null; + $notes = null; - if (!$stream->test(Twig_Token::BLOCK_END_TYPE)) { + if (!$stream->test(Token::BLOCK_END_TYPE)) { $body = $this->parser->getExpressionParser()->parseExpression(); } else { - $stream->expect(Twig_Token::BLOCK_END_TYPE); - $body = $this->parser->subparse(array($this, 'decideForFork')); - if ('plural' === $stream->next()->getValue()) { + $stream->expect(Token::BLOCK_END_TYPE); + $body = $this->parser->subparse([$this, 'decideForFork']); + $next = $stream->next()->getValue(); + + if ('plural' === $next) { $count = $this->parser->getExpressionParser()->parseExpression(); - $stream->expect(Twig_Token::BLOCK_END_TYPE); - $plural = $this->parser->subparse(array($this, 'decideForEnd'), true); + $stream->expect(Token::BLOCK_END_TYPE); + $plural = $this->parser->subparse([$this, 'decideForFork']); + + if ('notes' === $stream->next()->getValue()) { + $stream->expect(Token::BLOCK_END_TYPE); + $notes = $this->parser->subparse([$this, 'decideForEnd'], true); + } + } elseif ('notes' === $next) { + $stream->expect(Token::BLOCK_END_TYPE); + $notes = $this->parser->subparse([$this, 'decideForEnd'], true); } } - $stream->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Token::BLOCK_END_TYPE); $this->checkTransString($body, $lineno); - return new Twig_Extensions_Node_Trans($body, $plural, $count, $lineno, $this->getTag()); + return new TransNode($body, $plural, $count, $notes, $lineno, $this->getTag()); } - public function decideForFork(Twig_Token $token) + public function decideForFork(Token $token) { - return $token->test(array('plural', 'endtrans')); + return $token->test(['plural', 'notes', 'endtrans']); } - public function decideForEnd(Twig_Token $token) + public function decideForEnd(Token $token) { return $token->test('endtrans'); } - /** - * Gets the tag name associated with this token parser. - * - * @param string The tag name - */ public function getTag() { return 'trans'; } - protected function checkTransString(Twig_NodeInterface $body, $lineno) + private function checkTransString(Node $body, $lineno) { foreach ($body as $i => $node) { if ( - $node instanceof Twig_Node_Text + $node instanceof TextNode || - ($node instanceof Twig_Node_Print && $node->getNode('expr') instanceof Twig_Node_Expression_Name) + ($node instanceof PrintNode && $node->getNode('expr') instanceof NameExpression) ) { continue; } - throw new Twig_Error_Syntax(sprintf('The text to be translated with "trans" can only contain references to simple variables'), $lineno); + throw new SyntaxError(sprintf('The text to be translated with "trans" can only contain references to simple variables'), $lineno); } } -} \ No newline at end of file +} diff --git a/inc/template.php b/inc/template.php index 4c4fa36d..1d08cc61 100644 --- a/inc/template.php +++ b/inc/template.php @@ -10,16 +10,16 @@ $twig = false; function load_twig() { global $twig, $config; - $loader = new Twig_Loader_Filesystem($config['dir']['template']); + $loader = new Twig\Loader\FilesystemLoader($config['dir']['template']); $loader->setPaths($config['dir']['template']); - $twig = new Twig_Environment($loader, array( + $twig = new Twig\Environment($loader, array( 'autoescape' => false, 'cache' => is_writable('templates') || (is_dir('templates/cache') && is_writable('templates/cache')) ? "{$config['dir']['template']}/cache" : false, 'debug' => $config['debug'] )); $twig->addExtension(new Twig_Extensions_Extension_Tinyboard()); - $twig->addExtension(new Twig_Extensions_Extension_I18n()); + $twig->addExtension(new Twig\Extensions\I18nExtension()); } function Element($templateFile, array $options) {