Commit Graph

6153 Commits

Author SHA1 Message Date
Fabien Potencier 4be326aeeb Fix tests and CS 2023-11-21 14:57:52 +01:00
Fabien Potencier 9f42a76306 minor #3835 Removed duplicate sentence in macro scoping (virtualize)
This PR was merged into the 3.x branch.

Discussion
----------

Removed duplicate sentence in macro scoping

Commits
-------

73f5cad8 Remove duplicate sentence in macro scoping
2023-10-26 17:56:31 -07:00
Fabien Potencier b285fccd59 bug #3830 Catch errors thrown during template rendering (richards-square)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Catch errors thrown during template rendering

Some errors, like not providing a function the proper number of arguments or division by zero, extend from `\Error` rather than `\Exception`. This PR catches these types of errors during template rendering and throws a `RuntimeError` in order to provide better debugging information.

Commits
-------

85bf01b4 Catch errors thrown during template rendering
2023-10-26 17:55:51 -07:00
Drew Richards 85bf01b4ab Catch errors thrown during template rendering 2023-10-26 17:55:48 -07:00
Fabien Potencier 9a602c7532 feature #3695 Add @codeCoverageIgnore to untestable compiled methods (markhuot)
This PR was merged into the 3.x branch.

Discussion
----------

Add `@codeCoverageIgnore` to untestable compiled methods

I've been experimenting with adding my compiled templates to my code coverage reports and it works largely as expected. Templates that get executed return percentages accurate to the number of lines the tests actually cover. The only exception are the "meta" methods on the compiled template that aren't necessarily called by the tests.

This PR adds ``@codeCoverageIgnore`` comments to the compiled template for all non-display methods so the coverage report only lists lines from `doDisplay`.

I'm assuming that I will need to update some of the Twig tests to account for these new comments, but am curious if you'd be open to this change.

An example screenshot below. The last line shows line 46 out of the compiled template is never executed. The compiled template's `getDebugInfo` even correctly informs me that line 46 maps to line 4 in my `.twig` so I'll work on updating the line numbering next.

![image](https://user-images.githubusercontent.com/48975/166098890-fbaf99ad-9aa4-4430-9f82-050f482a6777.png)

Commits
-------

1cf610bd Add `@codeCoverageIgnore` to untestable compiled methods
2023-10-26 17:52:38 -07:00
Fabien Potencier 065634f498 bug #3844 Fix IntlExtension::formatDateTime use of date formatter prototype (drjayvee)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Fix IntlExtension::formatDateTime use of date formatter prototype

See https://github.com/twigphp/intl-extra/pull/6 for more details

Commits
-------

c75762c3 Fix IntlExtension::formatDateTime use of date formatter prototype
2023-10-26 17:47:32 -07:00
Jeroen Versteeg c75762c354 Fix IntlExtension::formatDateTime use of date formatter prototype 2023-10-26 17:47:31 -07:00
Fabien Potencier 248855b34b Merge branch '2.x' into 3.x
* 2.x:
  Fix premature loop exit in Security Policy lookup of allowed methods/properties
2023-10-26 17:38:13 -07:00
Fabien Potencier 02262dee80 bug #3873 Fix premature loop exit in Security Policy lookup of allowed methods/properties (YSaxon)
This PR was squashed before being merged into the 2.x branch.

Discussion
----------

Fix premature loop exit in Security Policy lookup of allowed methods/properties

The current security policy logic exits too soon when checking permissions for allowed classes and their methods/properties, causing false negatives in situations involving classes related by inheritance.

Consider the following configuration:

```
'methods' => [
  'App\BasicCollection' => ['sortAlphabetically'],
  'App\AdvancedCollection'=> ['sortByTimestamp'],
],
```
where `AdvancedCollection` is a subclass of `BasicCollection`, and `mylist` is an instance of `AdvancedCollection`

If you try to call `{{ mylist.sortByTimestamp() }}`, the current code will first match `mylist` against `App\BasicCollection`. Since `sortByTimestamp` is not an allowed method for `App\BasicCollection`, the code will exit the loop and incorrectly deny access. It will never get to checking `App\AdvancedCollection`.

Note that reordering classes in the config can't solve this issue. If you flipped the order, then it would fail for `{{ mylist.sortAlphabetically() }}` instead.

This pull request fixes the issue by only exiting the loop early when both the class and method/property match.

Commits
-------

5e1838db Fix premature loop exit in Security Policy lookup of allowed methods/properties
2023-10-26 17:37:16 -07:00
Yaakov Saxon 5e1838dbca Fix premature loop exit in Security Policy lookup of allowed methods/properties 2023-10-26 17:37:13 -07:00
Fabien Potencier 415f4cc3ee minor #3896 Compile Elvis operator into Elvis operator ?: (GromNaN)
This PR was merged into the 3.x branch.

Discussion
----------

Compile Elvis operator into Elvis operator `?:`

When using ternary operator without "then" part, the "condition" part is evaluated twice, which is inconsistent with how PHP works.
The Twig template `A ?: B` is currently compiled as `A ? A : B` in PHP. This PR change it to `A ?: B`.

If `A` is a complex expression, it improves performance to only execute the expression once.
If `A` is has a side effect (like updating a variable), the expression being executed twice could result in a bug. ([example in PHP](https://3v4l.org/LWZLR))

Example with ``@WebProfiler`/Collector/form.html.twig` [line 9](https://github.com/symfony/symfony/blob/e6d1ed4edb5ae197ec7d25ddaf64cfa456229504/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig#L9) (see deep [diff](https://www.diffchecker.com/jOm3dE13/))

```twig
{{ collector.data.nb_errors ?: collector.data.forms|length }}
```

Previous compilation:
```php
echo twig_escape_filter($this->env, (((isset($context["error_count"]) || array_key_exists("error_count", $context) ? $context["error_count"] : (function () { throw new RuntimeError('Variable "error_count" does not exist.', 9, $this->source); })())) ? ((isset($context["error_count"]) || array_key_exists("error_count", $context) ? $context["error_count"] : (function () { throw new RuntimeError('Variable "error_count" does not exist.', 9, $this->source); })())) : (twig_get_attribute($this->env, $this->source, (isset($context["collector"]) || array_key_exists("collector", $context) ? $context["collector"] : (function () { throw new RuntimeError('Variable "collector" does not exist.', 9, $this->source); })()), "countDefines", [], "any", false, false, false, 9))), "html", null, true);
```

After this change:
```php
echo twig_escape_filter($this->env, ((isset($context["error_count"]) || array_key_exists("error_count", $context) ? $context["error_count"] : (function () { throw new RuntimeError('Variable "error_count" does not exist.', 9, $this->source); })()) ?: twig_get_attribute($this->env, $this->source, (isset($context["collector"]) || array_key_exists("collector", $context) ? $context["collector"] : (function () { throw new RuntimeError('Variable "collector" does not exist.', 9, $this->source); })()), "countDefines", [], "any", false, false, false, 9)), "html", null, true);
```

Commits
-------

fb0d7495 Compile Elvis operator with Elvis operator
2023-10-22 14:57:13 +02:00
Fabien Potencier 758018b79b minor #3897 Compile starts/ends with using str_starts_with and str_ends_with (GromNaN)
This PR was merged into the 3.x branch.

Discussion
----------

Compile `starts/ends with` using `str_starts_with` and `str_ends_with`

Since we now require PHP 8.0 polyfill #3884, we can use `str_starts_with` and `str_ends_with` to compile `starts with` and `ends with` expressions.

Example with `bootstrap_4_layout.html.twig` [line 6-7](https://github.com/symfony/symfony/blob/e6d1ed4edb5ae197ec7d25ddaf64cfa456229504/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig#L6-L7) (see deep [diff](https://www.diffchecker.com/18CtPeja/)):

```twig
    {%- set prepend = not (money_pattern starts with '{{') -%}
    {%- set append = not (money_pattern ends with '}}') -%}
```

Previous compilation:
```php
// line 6
$context["prepend"] =  !(is_string($__internal_compile_0 = (isset($context["money_pattern"]) || array_key_exists("money_pattern", $context) ? $context["money_pattern"] : (function () { throw new RuntimeError('Variable "money_pattern" does not exist.', 6, $this->source); })())) && is_string($__internal_compile_1 = "{{") && ('' === $__internal_compile_1 || 0 === strpos($__internal_compile_0, $__internal_compile_1)));
// line 7
$context["append"] =  !(is_string($__internal_compile_2 = (isset($context["money_pattern"]) || array_key_exists("money_pattern", $context) ? $context["money_pattern"] : (function () { throw new RuntimeError('Variable "money_pattern" does not exist.', 7, $this->source); })())) && is_string($__internal_compile_3 = "}}") && ('' === $__internal_compile_3 || $__internal_compile_3 === substr($__internal_compile_2, -strlen($__internal_compile_3))));
```

With this change:
```php
// line 6
$context["prepend"] =  !(is_string($__internal_compile_0 = (isset($context["money_pattern"]) || array_key_exists("money_pattern", $context) ? $context["money_pattern"] : (function () { throw new RuntimeError('Variable "money_pattern" does not exist.', 6, $this->source); })())) && is_string($__internal_compile_1 = "{{") && str_starts_with($__internal_compile_0, $__internal_compile_1));
// line 7
$context["append"] =  !(is_string($__internal_compile_2 = (isset($context["money_pattern"]) || array_key_exists("money_pattern", $context) ? $context["money_pattern"] : (function () { throw new RuntimeError('Variable "money_pattern" does not exist.', 7, $this->source); })())) && is_string($__internal_compile_3 = "}}") && str_ends_with($__internal_compile_2, $__internal_compile_3));
```

Commits
-------

30b5a566 Compile starts/ends with using PHP8 functions str_starts/ends_with
2023-10-22 14:56:22 +02:00
Jérôme Tamarelle 30b5a56625 Compile starts/ends with using PHP8 functions str_starts/ends_with 2023-10-21 19:44:29 +02:00
Jérôme Tamarelle fb0d7495a8 Compile Elvis operator with Elvis operator 2023-10-21 19:08:38 +02:00
Fabien Potencier 51cfad8039 minor #3855 Update signature to acknowledge a TemplateWrapper (richardhj)
This PR was merged into the 3.x branch.

Discussion
----------

Update signature to acknowledge a TemplateWrapper

`$name` legitimately can be of type `Twig\TemplateWrapper`. This is already considered in line 1331. This PR updates the method signature in the PHPDoc.

This PR is necessary because other developers may rely on the signature, see contao/contao#6169.

Commits
-------

b0cabc09 Update signature to acknowledge a TemplateWrapper
2023-10-20 17:52:20 +02:00
Fabien Potencier f1b5227477 minor #3884 Use PHP 8.0 functions with polyfill (GromNaN)
This PR was merged into the 3.x branch.

Discussion
----------

Use PHP 8.0 functions with polyfill

Backport some changes from #3881 into 3.x using `symfony/polyfill-php80`.

- `str_starts_with`
- `str_ends_with`
- `str_contains`
- `get_debug_type`

Benefits:
- Less conflicts when both 3.x and 4.x branches will be maintained.
- Performance gain for PHP 8.0+ ([83,7% of installs](https://packagist.org/packages/twig/twig/php-stats#3))

Commits
-------

1d5c0928 Use PHP 8.0 functions with polyfill
2023-10-20 17:49:50 +02:00
Fabien Potencier 6f62291c14 Add missing docs 2023-10-20 17:48:30 +02:00
Fabien Potencier 8b55ad4420 minor #3885 Use PHP 7.1 features : is_iterable, ?? and ?: (GromNaN)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Use PHP 7.1 features : `is_iterable`, `??` and `?:`

Apply the following changes with rector, compatible with PHP 7.1:

```php
return static function (RectorConfig $rectorConfig): void {
    $rectorConfig->paths([
        __DIR__ . '/src',
        __DIR__ . '/doc',
        __DIR__ . '/tests',
        __DIR__ . '/extra',
    ]);
    $rectorConfig->rule(\Rector\Php53\Rector\Ternary\TernaryToElvisRector::class);
    $rectorConfig->rule(\Rector\Php70\Rector\Ternary\TernaryToNullCoalescingRector::class);
    $rectorConfig->rule(\Rector\Php71\Rector\BooleanOr\IsIterableRector::class);
};
```

Commits
-------

991f518d Replace calls to twig_test_iterable to is_iterable
6ca0d773 Convert Ternary to Elvis or Null Coalescing
cb8a8247 Use is_iterable when possible
2023-10-20 17:47:22 +02:00
Jérôme Tamarelle 991f518d32 Replace calls to twig_test_iterable to is_iterable 2023-10-20 17:47:18 +02:00
Jérôme Tamarelle 6ca0d773c5 Convert Ternary to Elvis or Null Coalescing 2023-10-20 17:47:17 +02:00
Jérôme Tamarelle cb8a824784 Use is_iterable when possible 2023-10-20 17:46:53 +02:00
Fabien Potencier 78e52452ea minor #3886 Remove TemplateWrapper::render() 2nd parameter not used (GromNaN)
This PR was merged into the 3.x branch.

Discussion
----------

Remove `TemplateWrapper::render()` 2nd parameter not used

The 2nd virtual parameter of `TemplateWrapper::render()` was added by #2805.
`Template::render()` don't define and don't use this 2nd parameter.

Running the test suite, this method never get more than 1 parameter (I assumed it could be used by the compiled Template via the backtrace, but it isn't).

Commits
-------

c56b87b4 Remove TemplateWrapper::render 2nd parameter not used
2023-10-20 17:44:29 +02:00
Fabien Potencier eaf22ba98d Fix CS 2023-10-20 17:39:50 +02:00
Fabien Potencier fec3a7fd22 minor #3888 Remove unused variables and unreachable code (GromNaN)
This PR was merged into the 3.x branch.

Discussion
----------

Remove unused variables and unreachable code

I did some archaeology to find the origin of each useless line of code. Details in comments.

Commits
-------

6d715e20 Remove unused variables and unreachable code
2023-10-20 17:39:04 +02:00
Fabien Potencier fd3f179718 Rewrite an example 2023-10-20 17:35:29 +02:00
Fabien Potencier 86f5bdccc2 minor #3892 range example leads to Array to string conversion exception (devojifr)
This PR was merged into the 3.x branch.

Discussion
----------

range example leads to Array to string conversion exception

In templates documentation, a range example is displayed and leads to an Array to string conversion exception without a join filter.

Commits
-------

53496507 range example leads to Array to string conversion exception
2023-10-20 17:33:15 +02:00
Fabien Potencier e4780e9cdf minor #3894 fix NumberFormatter::TYPE_CURRENCY being deprecated in PHP 8.3 (mbolli)
This PR was merged into the 3.x branch.

Discussion
----------

fix `NumberFormatter::TYPE_CURRENCY` being deprecated in PHP 8.3

It was never used anyway (by Twig and by PHP), so removing it should not have any side-effects.

Commits
-------

223ba6ec fix `NumberFormatter::TYPE_CURRENCY` being deprecated in PHP 8.3
2023-10-20 17:30:58 +02:00
Michael Bolli 223ba6ecde fix NumberFormatter::TYPE_CURRENCY being deprecated in PHP 8.3 2023-10-20 16:28:22 +02:00
devojifr 5349650781 range example leads to Array to string conversion exception
In templates documentation, a range example is displayed and leads to an Array to string conversion exception without a join filter.
2023-10-14 11:22:02 +02:00
Fabien Potencier 90647839ac minor #3889 Add Twiggy extension for VS Code to docs. (moetelo)
This PR was merged into the 3.x branch.

Discussion
----------

Add `Twiggy` extension for VS Code to docs.

Commits
-------

81799a74 Add `Twiggy` extension for VS Code to docs.
2023-10-12 08:35:06 +02:00
Mikhail Gunin 81799a7461 Add Twiggy extension for VS Code to docs. 2023-10-11 16:09:47 +03:00
Fabien Potencier e5d989fcfa bug #3887 restore return type annotations (xabbuh)
This PR was merged into the 3.x branch.

Discussion
----------

restore return type annotations

Commits
-------

41f1b037 restore return type annotations
2023-10-09 09:05:06 +02:00
Jérôme Tamarelle 6d715e2002 Remove unused variables and unreachable code 2023-10-08 21:18:06 +02:00
Christian Flothmann 41f1b0370a restore return type annotations 2023-10-08 20:59:56 +02:00
Jérôme Tamarelle c56b87b4d7 Remove TemplateWrapper::render 2nd parameter not used 2023-10-08 19:29:03 +02:00
Jérôme Tamarelle 1d5c09285f Use PHP 8.0 functions with polyfill 2023-10-08 17:11:07 +02:00
Fabien Potencier 2d37866aa2 minor #3882 Fix CS (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Fix CS

Commits
-------

5193653e Fix CS
2023-10-08 09:10:40 +02:00
Fabien Potencier 5193653ecb Fix CS 2023-10-08 09:05:22 +02:00
Fabien Potencier 3ae6fb8723 Merge branch '2.x' into 3.x
* 2.x:
  Set Twig 2 end of maintenance to December 2023
2023-09-15 08:04:59 +02:00
Fabien Potencier b83a0446cf Set Twig 2 end of maintenance to December 2023 2023-09-15 07:23:59 +02:00
Fabien Potencier 25382c09cc Merge branch '2.x' into 3.x
* 2.x:
  Remove Drupal tests
2023-09-11 17:41:35 +02:00
Fabien Potencier 974c866961 Remove Drupal tests 2023-09-11 17:40:51 +02:00
Fabien Potencier 0dcf775161 minor #3878 Fix CI (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Fix CI

Commits
-------

5f7c48ca Fix tests
2023-09-11 17:39:57 +02:00
Fabien Potencier 5f7c48ca7d Fix tests 2023-09-11 17:36:13 +02:00
Fabien Potencier 680e74e649 minor #3877 allow Symfony 7 packages to be installed (xabbuh)
This PR was merged into the 3.x branch.

Discussion
----------

allow Symfony 7 packages to be installed

Commits
-------

b8b0c396 allow Symfony 7 packages to be installed
2023-09-11 15:24:56 +02:00
Christian Flothmann b8b0c39663 allow Symfony 7 packages to be installed 2023-09-11 13:25:50 +02:00
Fabien Potencier 8ca93d8563 Merge branch '2.x' into 3.x
* 2.x:
  Bump CI actions
2023-09-11 13:19:19 +02:00
Fabien Potencier 4d800d7632 Bump CI actions 2023-09-11 13:19:11 +02:00
Fabien Potencier fd8f61b626 Bump version 2023-08-28 13:10:15 +02:00
Fabien Potencier a0ce373a0c Prepare the 3.7.1 release v3.7.1 2023-08-28 13:09:02 +02:00