Skip to content

Commit

Permalink
Twig 3.9 compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
leofeyer committed Apr 17, 2024
1 parent 4832d5f commit 793be75
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 22 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@
"symfony/dependency-injection": "5.4.16 || 6.0.16 || 6.1.8 || 6.2.0 || 6.2.1",
"terminal42/contao-ce-access": "<3.0",
"thecodingmachine/safe": "<1.2",
"twig/twig": "3.9.0",
"zendframework/zend-code": "<3.3.1"
},
"autoload": {
Expand Down
3 changes: 2 additions & 1 deletion core-bundle/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@
"doctrine/dbal": "3.3.0",
"symfony/dependency-injection": "5.4.16 || 6.0.16 || 6.1.8 || 6.2.0 || 6.2.1",
"terminal42/contao-ce-access": "<3.0",
"thecodingmachine/safe": "<1.2"
"thecodingmachine/safe": "<1.2",
"twig/twig": "3.9.0"
},
"suggest": {
"contao/tcpdf-bundle": "To export articles as PDF files"
Expand Down
27 changes: 22 additions & 5 deletions core-bundle/src/Twig/Extension/ContaoExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,15 +168,27 @@ public function getFilters(): array
$parts = [];

foreach ($string as [$type, $chunk]) {
$parts[] = ChunkedText::TYPE_RAW === $type
? $chunk
: twig_escape_filter($env, $chunk, $strategy, $charset);
if (ChunkedText::TYPE_RAW === $type) {
$parts[] = $chunk;
} else {
// Backwards compatibility with twig/twig <3.9
if (\function_exists('twig_escape_filter')) {
$parts[] = twig_escape_filter($env, $chunk, $strategy, $charset);
} else {
$parts[] = EscaperExtension::escape($env, $chunk, $strategy, $charset);

Check failure on line 178 in core-bundle/src/Twig/Extension/ContaoExtension.php

View workflow job for this annotation

GitHub Actions / PHPStan

Call to an undefined static method Twig\Extension\EscaperExtension::escape().
}
}
}

return implode('', $parts);
}

return twig_escape_filter($env, $string, $strategy, $charset, $autoescape);
// Backwards compatibility with twig/twig <3.9
if (\function_exists('twig_escape_filter')) {
return twig_escape_filter($env, $string, $strategy, $charset, $autoescape);
}

return EscaperExtension::escape($env, $string, $strategy, $charset, $autoescape);

Check failure on line 191 in core-bundle/src/Twig/Extension/ContaoExtension.php

View workflow job for this annotation

GitHub Actions / PHPStan

Call to an undefined static method Twig\Extension\EscaperExtension::escape().
};

$twigEscaperFilterIsSafe = static function (Node $filterArgs): array {
Expand All @@ -190,7 +202,12 @@ public function getFilters(): array
return [$value, substr($value, 7)];
}

return twig_escape_filter_is_safe($filterArgs);
// Backwards compatibility with twig/twig <3.9
if (\function_exists('twig_escape_filter_is_safe')) {
return twig_escape_filter_is_safe($filterArgs);
}

return EscaperExtension::escapeFilterIsSafe($filterArgs);

Check failure on line 210 in core-bundle/src/Twig/Extension/ContaoExtension.php

View workflow job for this annotation

GitHub Actions / PHPStan

Call to an undefined static method Twig\Extension\EscaperExtension::escapeFilterIsSafe().
};

return [
Expand Down
8 changes: 4 additions & 4 deletions core-bundle/src/Twig/Extension/DeprecationsNodeVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,24 @@
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Node;
use Twig\Node\PrintNode;
use Twig\NodeVisitor\AbstractNodeVisitor;
use Twig\NodeVisitor\NodeVisitorInterface;

/**
* @internal
*/
class DeprecationsNodeVisitor extends AbstractNodeVisitor
class DeprecationsNodeVisitor implements NodeVisitorInterface
{
public function getPriority(): int
{
return 10;
}

protected function doEnterNode(Node $node, Environment $env): Node
public function enterNode(Node $node, Environment $env): Node
{
return $node;
}

protected function doLeaveNode(Node $node, Environment $env): Node
public function leaveNode(Node $node, Environment $env): Node
{
return $this->handleDeprecatedInsertTagUsage($node);
}
Expand Down
8 changes: 4 additions & 4 deletions core-bundle/src/Twig/Interop/ContaoEscaperNodeVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use Twig\Node\Expression\FilterExpression;
use Twig\Node\ModuleNode;
use Twig\Node\Node;
use Twig\NodeVisitor\AbstractNodeVisitor;
use Twig\NodeVisitor\NodeVisitorInterface;

/**
* This NodeVisitor alters all "escape('html')" and "escape('html_attr')"
Expand All @@ -27,7 +27,7 @@
*
* @experimental
*/
final class ContaoEscaperNodeVisitor extends AbstractNodeVisitor
final class ContaoEscaperNodeVisitor implements NodeVisitorInterface
{
private ?array $escaperFilterNodes = null;

Expand All @@ -52,7 +52,7 @@ public function getPriority(): int
return 1;
}

protected function doEnterNode(Node $node, Environment $env): Node
public function enterNode(Node $node, Environment $env): Node
{
$isAffected = static function (array $rules, string $name): bool {
foreach ($rules as $rule) {
Expand All @@ -75,7 +75,7 @@ protected function doEnterNode(Node $node, Environment $env): Node
return $node;
}

protected function doLeaveNode(Node $node, Environment $env)
public function leaveNode(Node $node, Environment $env): Node
{
if ($node instanceof ModuleNode && null !== $this->escaperFilterNodes) {
foreach ($this->escaperFilterNodes as [$escaperFilterNode, $strategy]) {
Expand Down
8 changes: 4 additions & 4 deletions core-bundle/src/Twig/Interop/PhpTemplateProxyNodeVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
use Twig\Node\BlockNode;
use Twig\Node\ModuleNode;
use Twig\Node\Node;
use Twig\NodeVisitor\AbstractNodeVisitor;
use Twig\NodeVisitor\NodeVisitorInterface;

/**
* @experimental
*/
final class PhpTemplateProxyNodeVisitor extends AbstractNodeVisitor
final class PhpTemplateProxyNodeVisitor implements NodeVisitorInterface
{
private string $extensionName;

Expand All @@ -36,12 +36,12 @@ public function getPriority(): int
return 0;
}

protected function doEnterNode(Node $node, Environment $env): Node
public function enterNode(Node $node, Environment $env): Node
{
return $node;
}

protected function doLeaveNode(Node $node, Environment $env): Node
public function leaveNode(Node $node, Environment $env): Node
{
if ($node instanceof ModuleNode && ContaoTwigUtil::isLegacyTemplate($node->getTemplateName() ?? '')) {
$this->configurePhpTemplateProxy($node);
Expand Down
24 changes: 20 additions & 4 deletions core-bundle/tests/Twig/Extension/ContaoExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,11 @@ public function provideTemplateNames(): \Generator
* This test makes sure the function's signatures remains the same and changes
* to the original codebase do not stay unnoticed.
*
* @param \ReflectionFunction|\ReflectionMethod $reflector
*
* @dataProvider provideTwigFunctionSignatures
*/
public function testContaoUsesCorrectTwigFunctionSignatures(string $function, array $expectedParameters): void
public function testContaoUsesCorrectTwigFunctionSignatures($reflector, array $expectedParameters): void
{
// Make sure the functions outside the class scope are loaded
new \ReflectionClass(EscaperExtension::class);
Expand All @@ -360,15 +362,22 @@ public function testContaoUsesCorrectTwigFunctionSignatures(string $function, ar
($type = $parameter->getType()) instanceof \ReflectionNamedType ? $type->getName() : null,
$parameter->getName(),
],
(new \ReflectionFunction($function))->getParameters()
$reflector->getParameters()
);
$this->assertSame($parameters, $expectedParameters);
}

public function provideTwigFunctionSignatures(): \Generator
{
// Backwards compatibility with twig/twig <3.9
if (\function_exists('twig_escape_filter')) {
$escape = new \ReflectionFunction('twig_escape_filter');
} else {
$escape = new \ReflectionMethod(EscaperExtension::class.'::escape');
}

yield [
'twig_escape_filter',
$escape,
[
[Environment::class, 'env'],
[null, 'string'],
Expand All @@ -378,8 +387,15 @@ public function provideTwigFunctionSignatures(): \Generator
],
];

// Backwards compatibility with twig/twig <3.9
if (\function_exists('twig_escape_filter_is_safe')) {
$escapeisSafe = new \ReflectionFunction('twig_escape_filter_is_safe');
} else {
$escapeisSafe = new \ReflectionMethod(EscaperExtension::class.'::escapeFilterIsSafe');
}

yield [
'twig_escape_filter_is_safe',
$escapeisSafe,
[
[Node::class, 'filterArgs'],
],
Expand Down

0 comments on commit 793be75

Please sign in to comment.