Commit Graph

8157 Commits

Author SHA1 Message Date
Fabien Potencier 075dd703d0 Merge branch '3.x' into 4.x
* 3.x:
  Disable the fabbot test-case return type check
2026-07-12 15:39:22 +02:00
Fabien Potencier a5cbfabb83 tidy #4860 Disable the fabbot test-case return type check (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Disable the fabbot test-case return type check

See https://github.com/symfony-tools/fabbot/pull/18

Commits
-------

27a2dba4a7 Disable the fabbot test-case return type check
2026-07-12 15:39:13 +02:00
Fabien Potencier 27a2dba4a7 Disable the fabbot test-case return type check 2026-07-12 15:35:49 +02:00
Fabien Potencier 66bfbb27a8 Merge branch '3.x' into 4.x
* 3.x:
  Fix CS

# Conflicts:
#	src/Parser.php
#	src/Test/IntegrationTestCase.php
#	src/Test/NodeTestCase.php
2026-07-12 15:25:22 +02:00
Fabien Potencier 0b8e267bce Fix CS 2026-07-12 15:21:32 +02:00
Fabien Potencier 44f3c75117 Merge branch '3.x' into 4.x
* 3.x:
  Fix incompatible identifier() signature in test stubs
2026-07-12 15:16:40 +02:00
Fabien Potencier ef9c43187a Fix incompatible identifier() signature in test stubs 2026-07-12 15:15:28 +02:00
Fabien Potencier 5ca7debf6e Fix merge conflict resolution 2026-07-12 15:08:38 +02:00
Fabien Potencier 0b6e824ea8 Merge branch '3.x' into 4.x
* 3.x:
  Add void return type hint even in tests
  Run php-cs-fixer sequentially so the void_return src-only customiser is applied
  Fix CHANGELOG
  [Intl] Add format_list filter using PHP 8.5's IntlListFormatter

# Conflicts:
#	.github/workflows/ci.yml
#	CHANGELOG
#	extra/cssinliner-extra/Tests/LegacyFunctionsTest.php
#	extra/html-extra/Tests/CvaTest.php
#	extra/html-extra/Tests/HtmlAttrMergeTest.php
#	extra/html-extra/Tests/HtmlAttrTest.php
#	extra/html-extra/Tests/LegacyFunctionsTest.php
#	extra/inky-extra/Tests/LegacyFunctionsTest.php
#	extra/markdown-extra/Tests/FunctionalTest.php
#	extra/markdown-extra/Tests/LegacyFunctionsTest.php
#	extra/twig-extra-bundle/DependencyInjection/Compiler/MissingExtensionSuggestorPass.php
#	extra/twig-extra-bundle/DependencyInjection/TwigExtraExtension.php
#	extra/twig-extra-bundle/TwigExtraBundle.php
#	src/Extension/CoreExtension.php
#	src/Extension/EscaperExtension.php
#	src/Node/CheckSecurityCallNode.php
#	src/Node/Expression/FunctionExpression.php
#	src/Node/ModuleNode.php
#	src/Node/Node.php
#	src/Node/TypesNode.php
#	src/Resources/core.php
#	src/Resources/debug.php
#	src/Test/IntegrationTestCase.php
#	tests/CustomExtensionTest.php
#	tests/EnvironmentTest.php
#	tests/ExpressionParserTest.php
#	tests/Extension/CoreTest.php
#	tests/Extension/EscaperTest.php
#	tests/Extension/LegacyDebugFunctionsTest.php
#	tests/Extension/LegacyStringLoaderFunctionsTest.php
#	tests/Extension/SandboxStateChangeTest.php
#	tests/Extension/SandboxTest.php
#	tests/LexerTest.php
#	tests/Node/Expression/CallTest.php
#	tests/Node/Expression/ConditionalTest.php
#	tests/Node/NodeTest.php
#	tests/Resources/LegacyCoreTest.php
#	tests/TemplateTest.php
#	tests/Util/CallableArgumentsExtractorTest.php
2026-07-12 13:55:37 +02:00
Fabien Potencier 9c6d76b61c Add void return type hint even in tests 2026-07-12 13:43:08 +02:00
Fabien Potencier 71badee960 Run php-cs-fixer sequentially so the void_return src-only customiser is applied 2026-07-10 16:33:45 +02:00
Fabien Potencier 209a98402b Fix CHANGELOG 2026-07-08 22:23:12 +02:00
Fabien Potencier 5bcd992138 feature #4852 [Intl] Add format_list filter using PHP 8.5's IntlListFormatter (BreyndotEchse)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

[Intl] Add format_list filter using PHP 8.5's IntlListFormatter

Adds a new `format_list` Twig filter to IntlExtension that formats arrays using using PHP 8.5's IntlListFormatter

On PHP < 8.5, using the filter throws a RuntimeError explaining the dependency on IntlListFormatter (Checks if `class_exists` to allow polyfills).

CI workflow only covered up to PHP 8.4, so I extended it to also run PHPUnit against 8.5.
phpstan's PHP version also bumped to 8.5.

Commits
-------

163f1b6341 [Intl] Add format_list filter using PHP 8.5's IntlListFormatter
2026-07-08 22:22:47 +02:00
Marvin Feldmann 163f1b6341 [Intl] Add format_list filter using PHP 8.5's IntlListFormatter 2026-07-08 22:22:44 +02:00
Fabien Potencier 8b5e0a1957 Remove deprecated code 2026-07-08 21:35:57 +02:00
Fabien Potencier ea8aadf94d Merge branch '3.x' into 4.x
* 3.x:
  Exempt test files from the void_return rule regardless of the config location
  fix version in deprecation message for tag usage outside of root template
  Fix array access with a Stringable key on ArrayAccess objects using object keys
  Throw a SyntaxError instead of a PHP fatal error when a macro argument is defined twice
  Bump version
  Prepare the 3.28.0 release
  Render backed enums using their backing value in the html_attr function
  Tweak previous merge
  Add documention note about variable scope of override blocks in {% embed ... only %}
  Define the macro at the template root in the cache macro fixture
  Update CHANGELOG
  Fix a PHP 8.5 chr() deprecation when decoding octal string escapes
  Fix Markup truthiness in boolean expressions

# Conflicts:
#	CHANGELOG
#	doc/deprecated.rst
#	src/Environment.php
#	src/Node/Expression/TempNameExpression.php
#	src/Node/IfNode.php
#	src/Node/MacroNode.php
#	src/NodeVisitor/CorrectnessNodeVisitor.php
#	tests/Fixtures/tags/inheritance/extends_in_condition.test
#	tests/Fixtures/tags/inheritance/use_in_condition.test
#	tests/Fixtures/tags/inheritance/use_in_macro.test
#	tests/Fixtures/tags/macro/macro_in_block.test
#	tests/Fixtures/tags/macro/macro_in_condition.test
2026-07-08 21:22:49 +02:00
Fabien Potencier 4a7cd7057d Exempt test files from the void_return rule regardless of the config location 2026-07-08 21:16:09 +02:00
Fabien Potencier 8ada671fc3 bug #4856 Fix array access with a Stringable key on ArrayAccess objects using object keys (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Fix array access with a Stringable key on ArrayAccess objects using object keys

Closes #4855

Commits
-------

679b8fd610 Fix array access with a Stringable key on ArrayAccess objects using object keys
2026-07-08 21:15:02 +02:00
Fabien Potencier 2fb736d033 tidy #4857 Fix version in deprecation message for tag usage outside of root template (MrYamous)
This PR was merged into the 3.x branch.

Discussion
----------

Fix version in deprecation message for tag usage outside of root template

#4292 has been introduced in 3.28 and related deprecations are shown for this version in changelog file

But in some part of code including deprecation message, it's about 3.27, this is confusing when upgrading Twig

Commits
-------

fc4dee393c fix version in deprecation message for tag usage outside of root template
2026-07-08 20:57:26 +02:00
Matthieu Lempereur fc4dee393c fix version in deprecation message for tag usage outside of root template 2026-07-08 19:01:20 +02:00
Fabien Potencier 679b8fd610 Fix array access with a Stringable key on ArrayAccess objects using object keys 2026-07-06 22:42:11 +02:00
Fabien Potencier d1abdf483a bug #4853 Throw a SyntaxError instead of a PHP fatal error when a macro argument is defined twice (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Throw a SyntaxError instead of a PHP fatal error when a macro argument is defined twice

Commits
-------

0d283d304a Throw a SyntaxError instead of a PHP fatal error when a macro argument is defined twice
2026-07-04 11:20:43 +02:00
Fabien Potencier 0d283d304a Throw a SyntaxError instead of a PHP fatal error when a macro argument is defined twice 2026-07-04 11:17:28 +02:00
Fabien Potencier 54e5bc1453 Bump version 2026-07-03 22:44:56 +02:00
Fabien Potencier 597c12ed28 Prepare the 3.28.0 release v3.28.0 2026-07-03 22:44:34 +02:00
Fabien Potencier 6a175a5745 bug #4850 Render backed enums using their backing value in the html_attr function (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Render backed enums using their backing value in the html_attr function

Closes #4848

Commits
-------

9323a82eb9 Render backed enums using their backing value in the html_attr function
2026-06-25 09:13:09 +02:00
Fabien Potencier 9323a82eb9 Render backed enums using their backing value in the html_attr function 2026-06-25 08:50:01 +02:00
Fabien Potencier ec0f5d5dad Tweak previous merge 2026-06-19 08:06:30 +02:00
Fabien Potencier 4007231f2f minor #4845 Add documention note about variable scope of override blocks in {% embed ... only %} (andy-blum)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Add documention note about variable scope of override blocks in {% embed ... only %}

Closes #4844

Commits
-------

068a2e6cb4 Add documention note about variable scope of override blocks in {% embed ... only %}
2026-06-19 08:03:28 +02:00
Andy Blum 068a2e6cb4 Add documention note about variable scope of override blocks in {% embed ... only %} 2026-06-19 08:03:24 +02:00
Fabien Potencier f6152fe256 minor #4843 Define macros at the template root in the cache macro fixture (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Define macros at the template root in the cache macro fixture

Commits
-------

424d2f1195 Define the macro at the template root in the cache macro fixture
2026-06-15 22:52:31 +02:00
Fabien Potencier 424d2f1195 Define the macro at the template root in the cache macro fixture 2026-06-13 12:59:44 +02:00
Fabien Potencier e3b8e15e37 Update CHANGELOG 2026-06-13 12:29:03 +02:00
Fabien Potencier 2f202b006b bug #4841 Fix Markup truthiness in boolean expressions (xtrime-ru)
This PR was merged into the 3.x branch.

Discussion
----------

Fix Markup truthiness in boolean expressions

## Summary

Fixes Markup truthiness handling in boolean expressions.

`trim` can return a `Twig\Markup` instance for safe strings. Empty `Markup` objects must behave like empty strings in Twig truth tests, but PHP treats all objects as truthy. This caused expressions like this to incorrectly evaluate as true:
```twig
{% set x %}    {% endset %}
{% if x|trim and x|trim %}fail{% else %}ok{% endif %}
```

This case was working properly in https://github.com/twigphp/Twig/releases/tag/v3.14.2 and earlier.

## Related commits
- Bug was introduced in [v3.15.0](https://github.com/twigphp/Twig/releases/tag/v3.15.0) in this commit https://github.com/twigphp/Twig/commit/10c3142d3b036910f63080070c101bfff61e0743
- Partially fixed here:  https://github.com/twigphp/Twig/commit/10c3142d3b036910f63080070c101bfff61e0743

## Changes

- Added `TrueTest::wrap()` to centralize wrapping non-primitive expressions with Twig’s Markup-aware true test.
- Reused `TrueTest::wrap()` in:
  - `IfNode`
  - conditional ternary expressions
  - `and`, `or`, and `xor` binary expressions
  - Elvis expressions
  - unary `not`
- Added regression coverage for boolean operators (`and`, `or`, `xor`, `not`) and ternary/Elvis expressions whose operands evaluate to empty `Markup`.

## Tests
```bash
./vendor/bin/simple-phpunit tests/IntegrationTest.php --filter markup_test
```

Commits
-------

f5afaabf54 Fix Markup truthiness in boolean expressions
2026-06-13 12:28:15 +02:00
Fabien Potencier 8a93950693 bug #4842 Fix a PHP 8.5 chr() deprecation when decoding octal string escapes (austinderrick)
This PR was merged into the 3.x branch.

Discussion
----------

Fix a PHP 8.5 chr() deprecation when decoding octal string escapes

PHP 8.5 deprecates passing a value outside the `[0, 255]` range to `chr()`.

The string-escape decoder in `Lexer::stringEscape()` accepts up to three octal digits, so a template containing an escape such as `"\777"` (= 511) reaches `chr()` out of range and emits:

> `chr(): Providing a value not in-between 0 and 255 is deprecated, this is because a byte value must be in the [0, 255] interval. The value used will be constrained using % 256`

`chr()` already constrains the value with `% 256`, so applying `% 256` explicitly preserves the exact byte that was produced before while silencing the deprecation. The hex-escape branch is unaffected because it is capped at two digits (`\xff` = 255).

Reproducer (PHP 8.5):

```twig
{{ "\777" }}
```

Tests added to `getStringWithEscapedDelimiter()` cover `"\777"` (constrained to `0xff`) and `"\400"` (wraps to a NUL byte). The full suite passes on PHP 8.5; without this change the bridge reports the `chr()` notice as a self-deprecation.

Commits
-------

153094b601 Fix a PHP 8.5 chr() deprecation when decoding octal string escapes
2026-06-13 07:22:34 +02:00
Derrick Austin 153094b601 Fix a PHP 8.5 chr() deprecation when decoding octal string escapes
PHP 8.5 deprecates passing a value outside the [0, 255] range to chr().
The string-escape decoder in the lexer accepts up to three octal digits,
so an escape such as "\777" (= 511) reaches chr() out of range and emits:

    chr(): Providing a value not in-between 0 and 255 is deprecated ...

chr() already constrains the value with "% 256", so applying "% 256"
explicitly preserves the exact byte while silencing the deprecation. The
hex escape branch is unaffected because it is capped at two digits (0xff).
2026-06-13 07:22:26 +02:00
Alexander Pankratov f5afaabf54 Fix Markup truthiness in boolean expressions 2026-06-11 15:33:21 +02:00
Fabien Potencier eb8ca3b887 Remove deprecated code 2026-06-11 08:16:23 +02:00
Fabien Potencier 46a11071c2 Fix merge conflict resolution 2026-06-11 07:59:29 +02:00
Fabien Potencier 04ace9dba0 Merge branch '3.x' into 4.x
* 3.x:
  Handle single-node child template bodies in cleanup
  Keep captured block definitions supported
  Clarify captured block deprecation wording
  Simplify correctness visitor checks
  Move extends validation into correctness visitor
  Fix correctness visitor regressions
  Fix test assertions that did not verify the intended behavior
  Address review: fix block-nesting checks in CorrectnessNodeVisitor
  Move the extends-in-block and extends-in-macro errors into the CorrectnessNodeVisitor
  Introduce a CorrectnessNodeVisitor to validate that templates are semantically correct
  Mark Markup as final
  Allow calling a macro with a dynamic name via the dot operator
  Add an allow-list for tests to the sandbox security policy
  Fix markdown_to_html mangling content that starts with a blank line

# Conflicts:
#	CHANGELOG
#	doc/deprecated.rst
#	doc/sandbox.rst
#	src/ExpressionParser/Infix/DotExpressionParser.php
#	src/Extension/CoreExtension.php
#	src/Markup.php
#	src/Node/CheckSecurityNode.php
#	src/Node/Expression/Filter/DefaultFilter.php
#	src/Node/Expression/NullCoalesceExpression.php
#	src/Node/IfNode.php
#	src/NodeVisitor/SandboxNodeVisitor.php
#	src/Parser.php
#	src/Sandbox/SecurityPolicy.php
#	tests/Extension/SandboxTest.php
#	tests/ParserTest.php
2026-06-11 07:57:54 +02:00
Fabien Potencier 7f9714a13e feature #4292 Introduce a CorrectnessNodeVisitor to validate that templates are semantically correct (fabpot)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Introduce a CorrectnessNodeVisitor to validate that templates are semantically correct

This PR addresses several issues around the correctness of templates.
Being able to parse and compile a template does not mean that it is semantically correct. To enforce correctness, we currently have several places where we deal with it:

 * `Parser::filterBodyNodes()`: This method is a mix of ensuring the correctness of a template, but it also changes the body node of a child template (something that is always needed and not part of the correctness checks)
 * `ExtendsTokenParser`: It checks that an `extend` tag is not embedded into a block or a macro. The `extend` tag is not the only one that must be at the root of a template

This PR introduces a new `CorrectnessNodeVisitor` that has the responsibility to check that a template is semantically correct. It's the continuation of work that started a long time ago in #2687 (where I mentioned the weirdness of some supported templates like those mentioned in #3926 and deprecated by this PR).

Closes #3698: Having a `use` tag embedded in another tag (like `if` in the mentioned PR) is deprecated and will not be possible in 4.0.

Commits
-------

c0504b90c5 Handle single-node child template bodies in cleanup
a69d3dc71e Keep captured block definitions supported
16e5a937ed Clarify captured block deprecation wording
8a0ae2204c Simplify correctness visitor checks
ffcae61b15 Move extends validation into correctness visitor
d96eac3895 Fix correctness visitor regressions
89e8699a73 Fix test assertions that did not verify the intended behavior
4b2e651dd5 Address review: fix block-nesting checks in CorrectnessNodeVisitor
de7bbc7be9 Move the extends-in-block and extends-in-macro errors into the CorrectnessNodeVisitor
c12100525e Introduce a CorrectnessNodeVisitor to validate that templates are semantically correct
2026-06-11 07:44:10 +02:00
Fabien Potencier c0504b90c5 Handle single-node child template bodies in cleanup 2026-06-11 07:44:00 +02:00
Fabien Potencier a69d3dc71e Keep captured block definitions supported 2026-06-11 07:43:59 +02:00
Fabien Potencier 16e5a937ed Clarify captured block deprecation wording 2026-06-11 07:43:47 +02:00
Fabien Potencier 8a0ae2204c Simplify correctness visitor checks 2026-06-11 07:43:47 +02:00
Fabien Potencier ffcae61b15 Move extends validation into correctness visitor 2026-06-11 07:43:47 +02:00
Fabien Potencier d96eac3895 Fix correctness visitor regressions 2026-06-11 07:43:46 +02:00
Fabien Potencier 89e8699a73 Fix test assertions that did not verify the intended behavior 2026-06-11 07:43:36 +02:00
Fabien Potencier 4b2e651dd5 Address review: fix block-nesting checks in CorrectnessNodeVisitor 2026-06-11 07:43:36 +02:00
Fabien Potencier de7bbc7be9 Move the extends-in-block and extends-in-macro errors into the CorrectnessNodeVisitor 2026-06-11 07:43:36 +02:00