diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3e9eb3b..99dfa17c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,16 +19,8 @@ jobs: max-parallel: 4 fail-fast: false matrix: - php: ['7.4', '8.0', '8.1'] - symfony: ['^4.4', '^5.4', '^6.0'] - exclude: - - symfony: '^6.0' - php: '7.4' - include: - - symfony: '^4.4' - deprecations: 'max[self]=0' - - symfony: '^5.4' - deprecations: '' + php: ['8.1', '8.2', '8.3'] + symfony: ['^5.4', '^6.4'] steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 596b5c38..b0079932 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -41,7 +41,7 @@ ], 'declare_strict_types' => true, 'no_leading_import_slash' => true, - 'no_trailing_comma_in_singleline_array' => true, + 'no_trailing_comma_in_singleline' => true, 'no_singleline_whitespace_before_semicolons' => true, 'no_unused_imports' => true, 'concat_space' => ['spacing' => 'one'], @@ -55,7 +55,7 @@ 'no_blank_lines_after_phpdoc' => true, 'array_syntax' => ['syntax' => 'short'], 'whitespace_after_comma_in_array' => true, - 'function_typehint_space' => true, + 'type_declaration_spaces' => true, 'single_line_comment_style' => true, 'no_alias_functions' => true, 'lowercase_cast' => true, diff --git a/composer.json b/composer.json index 3764b277..18edea61 100644 --- a/composer.json +++ b/composer.json @@ -16,27 +16,27 @@ } ], "require": { - "php": "^7.4 || ^8.0", + "php": "^8.1", "erusev/parsedown": "^1.7 || 2.*.*@dev", "knplabs/knp-menu-bundle": "^2.2 || ^3.0", "knplabs/knp-paginator-bundle": "^3.0 || ^4.0 || ^5.0", "setasign/fpdi": "^2.3", - "symfony/asset": "^4.4 || ^5.4 || ^6.0", - "symfony/dependency-injection": "^4.4 || ^5.4 || ^6.0", + "symfony/asset": "^5.4 || ^6.4", + "symfony/dependency-injection": "^5.4 || ^6.4", "symfony/deprecation-contracts": "^2.5 || ^3.0", - "symfony/form": "^4.4 || ^5.4 || ^6.0", - "symfony/framework-bundle": "^4.4 || ^5.4 || ^6.0", - "symfony/http-kernel": "^4.4 || ^5.4 || ^6.0", - "symfony/security-bundle": "^4.4 || ^5.4 || ^6.0", - "symfony/translation": "^4.4 || ^5.4 || ^6.0", - "symfony/twig-bundle": "^4.4 || ^5.4 || ^6.0", + "symfony/form": "^5.4 || ^6.4", + "symfony/framework-bundle": "^5.4 || ^6.4", + "symfony/http-kernel": "^5.4 || ^6.4", + "symfony/security-bundle": "^5.4 || ^6.4", + "symfony/translation": "^5.4 || ^6.4", + "symfony/twig-bundle": "^5.4 || ^6.4", "tecnickcom/tcpdf": "^6.7", "twig/twig": "^3.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.0", "overtrue/phplint": "^3.0 || ^4.0", - "symfony/phpunit-bridge": "^4.4 || ^5.4 || ^6.0", + "symfony/phpunit-bridge": "^5.4 || ^6.4", "symfony/webpack-encore-bundle": "^1.13" }, "suggest": { diff --git a/src/Twig/Node/ExampleNode.php b/src/Twig/Node/ExampleNode.php index a0d86089..8919ce39 100644 --- a/src/Twig/Node/ExampleNode.php +++ b/src/Twig/Node/ExampleNode.php @@ -11,14 +11,15 @@ namespace T3G\Bundle\TemplateBundle\Twig\Node; use Twig\Compiler; +use Twig\Environment; use Twig\Node\Node; use Twig\Node\NodeOutputInterface; class ExampleNode extends Node implements NodeOutputInterface { - protected $tagName = 'example'; + protected string $tagName = 'example'; - public function __construct(Node $body = null, Node $attributes = null, int $lineno, string $tag = null) + public function __construct(Node $body, ?Node $attributes, int $lineno, string $tag = null) { $nodes = ['body' => $body]; if ($attributes !== null) { @@ -28,9 +29,9 @@ public function __construct(Node $body = null, Node $attributes = null, int $lin parent::__construct($nodes, [], $lineno, $tag); } - public function compile(Compiler $compiler) + public function compile(Compiler $compiler): void { - $attributeStorageName = uniqid($this->tagName); + $attributeStorageName = $this->tagName . hash('xxh3', uniqid($this->tagName, true)); $compiler->addDebugInfo($this); if ($this->hasNode('attributes')) { @@ -47,11 +48,24 @@ public function compile(Compiler $compiler) $compiler->write('$' . $attributeStorageName . ' = [];' . PHP_EOL); } - $compiler - ->write('ob_start();' . PHP_EOL) - ->subcompile($this->getNode('body')) - ->write('$content = ob_get_clean();' . PHP_EOL) - ->write('echo $this->env->getExtension(\'T3G\Bundle\TemplateBundle\Twig\Extension\BlockExtension\')->exampleFunction($this->env, $content, $' . $attributeStorageName . ');' . PHP_EOL) - ; + if (version_compare(Environment::VERSION, '3.9.0', '>=')) { + // twig >= 3.9 + $compiler + ->write('$content = implode("", iterator_to_array((function () use (&$context, $macros, $blocks) {' . PHP_EOL) + ->indent() + ->subcompile($this->getNode('body')) + ->outdent() + ->write('})(), false));' . PHP_EOL) + ->write('yield $this->env->getExtension(\'T3G\Bundle\TemplateBundle\Twig\Extension\BlockExtension\')->exampleFunction($this->env, $content, $' . $attributeStorageName . ');' . PHP_EOL) + ; + } else { + // twig < 3.9 + $compiler + ->write('ob_start();' . PHP_EOL) + ->subcompile($this->getNode('body')) + ->write('$content = ob_get_clean();' . PHP_EOL) + ->write('echo $this->env->getExtension(\'T3G\Bundle\TemplateBundle\Twig\Extension\BlockExtension\')->exampleFunction($this->env, $content, $' . $attributeStorageName . ');' . PHP_EOL) + ; + } } } diff --git a/src/Twig/Node/ExpandNode.php b/src/Twig/Node/ExpandNode.php index 8ca58d88..1b075871 100644 --- a/src/Twig/Node/ExpandNode.php +++ b/src/Twig/Node/ExpandNode.php @@ -11,14 +11,15 @@ namespace T3G\Bundle\TemplateBundle\Twig\Node; use Twig\Compiler; +use Twig\Environment; use Twig\Node\Node; use Twig\Node\NodeOutputInterface; class ExpandNode extends Node implements NodeOutputInterface { - protected $tagName = 'expand'; + protected string $tagName = 'expand'; - public function __construct(Node $body = null, Node $attributes = null, int $lineno, string $tag = null) + public function __construct(Node $body, ?Node $attributes, int $lineno, string $tag = null) { $nodes = ['body' => $body]; if ($attributes !== null) { @@ -30,7 +31,7 @@ public function __construct(Node $body = null, Node $attributes = null, int $lin public function compile(Compiler $compiler) { - $attributeStorageName = uniqid($this->tagName); + $attributeStorageName = $this->tagName . hash('xxh3', uniqid($this->tagName, true)); $compiler->addDebugInfo($this); if ($this->hasNode('attributes')) { @@ -47,11 +48,24 @@ public function compile(Compiler $compiler) $compiler->write('$' . $attributeStorageName . ' = [];' . PHP_EOL); } - $compiler - ->write('ob_start();' . PHP_EOL) - ->subcompile($this->getNode('body')) - ->write('$content = ob_get_clean();' . PHP_EOL) - ->write('echo $this->env->getExtension(\'T3G\Bundle\TemplateBundle\Twig\Extension\TextExtension\')->expand($this->env, $content, $' . $attributeStorageName . ');' . PHP_EOL) - ; + if (version_compare(Environment::VERSION, '3.9.0', '>=')) { + // twig >= 3.9 + $compiler + ->write('$content = implode("", iterator_to_array((function () use (&$context, $macros, $blocks) {' . PHP_EOL) + ->indent() + ->subcompile($this->getNode('body')) + ->outdent() + ->write('})(), false));' . PHP_EOL) + ->write('yield $this->env->getExtension(\'T3G\Bundle\TemplateBundle\Twig\Extension\TextExtension\')->expand($this->env, $content, $' . $attributeStorageName . ');' . PHP_EOL) + ; + } else { + // twig < 3.9 + $compiler + ->write('ob_start();' . PHP_EOL) + ->subcompile($this->getNode('body')) + ->write('$content = ob_get_clean();' . PHP_EOL) + ->write('echo $this->env->getExtension(\'T3G\Bundle\TemplateBundle\Twig\Extension\TextExtension\')->expand($this->env, $content, $' . $attributeStorageName . ');' . PHP_EOL) + ; + } } } diff --git a/src/Twig/Node/FrameNode.php b/src/Twig/Node/FrameNode.php index 38d1925d..f644aceb 100644 --- a/src/Twig/Node/FrameNode.php +++ b/src/Twig/Node/FrameNode.php @@ -11,14 +11,15 @@ namespace T3G\Bundle\TemplateBundle\Twig\Node; use Twig\Compiler; +use Twig\Environment; use Twig\Node\Node; use Twig\Node\NodeOutputInterface; class FrameNode extends Node implements NodeOutputInterface { - protected $tagName = 'frame'; + protected string $tagName = 'frame'; - public function __construct(Node $body = null, Node $attributes = null, int $lineno, string $tag = null) + public function __construct(Node $body, ?Node $attributes, int $lineno, string $tag = null) { $nodes = ['body' => $body]; if ($attributes !== null) { @@ -28,9 +29,9 @@ public function __construct(Node $body = null, Node $attributes = null, int $lin parent::__construct($nodes, [], $lineno, $tag); } - public function compile(Compiler $compiler) + public function compile(Compiler $compiler): void { - $attributeStorageName = uniqid($this->tagName); + $attributeStorageName = $this->tagName . hash('xxh3', uniqid($this->tagName, true)); $compiler->addDebugInfo($this); if ($this->hasNode('attributes')) { @@ -47,11 +48,24 @@ public function compile(Compiler $compiler) $compiler->write('$' . $attributeStorageName . ' = [];' . PHP_EOL); } - $compiler - ->write('ob_start();' . PHP_EOL) - ->subcompile($this->getNode('body')) - ->write('$content = ob_get_clean();' . PHP_EOL) - ->write('echo $this->env->getExtension(\'T3G\Bundle\TemplateBundle\Twig\Extension\BlockExtension\')->frameFunction($this->env, $content, $' . $attributeStorageName . ');' . PHP_EOL) - ; + if (version_compare(Environment::VERSION, '3.9.0', '>=')) { + // twig >= 3.9 + $compiler + ->write('$content = implode("", iterator_to_array((function () use (&$context, $macros, $blocks) {' . PHP_EOL) + ->indent() + ->subcompile($this->getNode('body')) + ->outdent() + ->write('})(), false));' . PHP_EOL) + ->write('yield $this->env->getExtension(\'T3G\Bundle\TemplateBundle\Twig\Extension\BlockExtension\')->frameFunction($this->env, $content, $' . $attributeStorageName . ');' . PHP_EOL) + ; + } else { + // twig < 3.9 + $compiler + ->write('ob_start();' . PHP_EOL) + ->subcompile($this->getNode('body')) + ->write('$content = ob_get_clean();' . PHP_EOL) + ->write('echo $this->env->getExtension(\'T3G\Bundle\TemplateBundle\Twig\Extension\BlockExtension\')->frameFunction($this->env, $content, $' . $attributeStorageName . ');' . PHP_EOL) + ; + } } }