From 2e352dee324d05687fb3589efac9dd6765a534a4 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Fri, 21 Nov 2025 12:16:41 +0100 Subject: [PATCH] Fix Twig 3 deprecations --- src/TwigHooks/src/Twig/Node/HookNode.php | 29 ++++++++++++++-- .../src/Twig/TokenParser/HookTokenParser.php | 33 +++++++++++++++++-- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/TwigHooks/src/Twig/Node/HookNode.php b/src/TwigHooks/src/Twig/Node/HookNode.php index 9f8b50ffd..5ce1fb164 100644 --- a/src/TwigHooks/src/Twig/Node/HookNode.php +++ b/src/TwigHooks/src/Twig/Node/HookNode.php @@ -14,10 +14,12 @@ namespace Sylius\TwigHooks\Twig\Node; use Sylius\TwigHooks\Twig\Runtime\HooksRuntime; +use Twig\Attribute\YieldReady; use Twig\Compiler; use Twig\Node\Expression\ArrayExpression; use Twig\Node\Node; +#[YieldReady] final class HookNode extends Node { public function __construct( @@ -25,8 +27,30 @@ public function __construct( ?Node $context, bool $only, int $lineno, - ?string $tag = null, ) { + if (\func_num_args() > 4) { + trigger_deprecation('sylius/twig-hooks', '0.11.0', \sprintf('The "tag" constructor argument of the "%s" class is deprecated and ignored (check which TokenParser class set it to "%s"), the tag is now automatically set by the Parser when needed.', static::class, func_get_arg(4) ?: 'null')); + } + + // Remove when twig < 3.12 support is dropped + if (!class_exists(\Twig\Node\Expression\FunctionNode\EnumCasesFunction::class)) { + $tag = func_get_arg(4); + + parent::__construct( + [ + 'name' => $name, + 'hook_level_context' => $context ?? new ArrayExpression([], $lineno), + ], + [ + 'only' => $only, + ], + $lineno, + $tag, + ); + + return; + } + parent::__construct( [ 'name' => $name, @@ -36,7 +60,6 @@ public function __construct( 'only' => $only, ], $lineno, - $tag, ); } @@ -49,7 +72,7 @@ public function compile(Compiler $compiler): void HooksRuntime::class, ))->raw("\n"); - $compiler->raw('echo $hooksRuntime->renderHook('); + $compiler->raw(sprintf('%s $hooksRuntime->renderHook(', class_exists(YieldReady::class) ? 'yield' : 'echo')); $compiler->subcompile($this->getNode('name')); $compiler->raw(', '); $compiler->subcompile($this->getNode('hook_level_context')); diff --git a/src/TwigHooks/src/Twig/TokenParser/HookTokenParser.php b/src/TwigHooks/src/Twig/TokenParser/HookTokenParser.php index 330811c15..e549221b6 100644 --- a/src/TwigHooks/src/Twig/TokenParser/HookTokenParser.php +++ b/src/TwigHooks/src/Twig/TokenParser/HookTokenParser.php @@ -15,6 +15,7 @@ use Sylius\TwigHooks\Twig\Node\HookNode; use Twig\Node\Node; +use Twig\Node\Nodes; use Twig\Token; use Twig\TokenParser\AbstractTokenParser; @@ -26,11 +27,21 @@ public function parse(Token $token): Node { $lineno = $token->getLine(); $stream = $this->parser->getStream(); - $hooksNames = $this->parser->getExpressionParser()->parseExpression(); + if (method_exists($this->parser, 'parseExpression')) { + $hooksNames = $this->parser->parseExpression(); + } else { + // Remove when Twig 3.21 support is dropped + $hooksNames = $this->parser->getExpressionParser()->parseExpression(); + } $hookContext = null; if ($stream->nextIf(Token::NAME_TYPE, 'with')) { - $hookContext = $this->parser->getExpressionParser()->parseMultitargetExpression(); + if (method_exists($this->parser, 'parseExpression')) { + $hookContext = $this->parseMultitargetExpression(); + } else { + // Remove when Twig 3.21 support is dropped + $hookContext = $this->parser->getExpressionParser()->parseMultitargetExpression(); + } } $only = false; @@ -40,6 +51,11 @@ public function parse(Token $token): Node $stream->expect(Token::BLOCK_END_TYPE); + if (class_exists(\Twig\Node\Expression\FunctionNode\EnumCasesFunction::class)) { + return new HookNode($hooksNames, $hookContext, $only, $lineno); + } + + // Remove when twig < 3.12 support is dropped return new HookNode($hooksNames, $hookContext, $only, $lineno, $this->getTag()); } @@ -47,4 +63,17 @@ public function getTag(): string { return self::TAG; } + + private function parseMultitargetExpression(): Nodes + { + $targets = []; + while (true) { + $targets[] = $this->parser->parseExpression(); + if (!$this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, ',')) { + break; + } + } + + return new Nodes($targets); + } }