Skip to content

Commit

Permalink
Merge remote-tracking branch 'o/3.x' into 3.x
Browse files Browse the repository at this point in the history
  • Loading branch information
danog committed Nov 22, 2023
2 parents bcffc35 + aeeec9a commit 633800a
Show file tree
Hide file tree
Showing 65 changed files with 385 additions and 228 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ jobs:
- '8.0'
- '8.1'
- '8.2'
- '8.3'
experimental: [false]

steps:
Expand Down Expand Up @@ -75,6 +76,7 @@ jobs:
- '8.0'
- '8.1'
- '8.2'
- '8.3'
extension:
- 'extra/cache-extra'
- 'extra/cssinliner-extra'
Expand Down
12 changes: 11 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
# 3.7.2 (2023-XX-XX)
# 3.8.1 (2023-XX-XX)

* n/a

# 3.8.0 (2023-11-21)

* Catch errors thrown during template rendering
* Fix IntlExtension::formatDateTime use of date formatter prototype
* Fix premature loop exit in Security Policy lookup of allowed methods/properties
* Remove NumberFormatter::TYPE_CURRENCY (deprecated in PHP 8.3)
* Restore return type annotations
* Allow Symfony 7 packages to be installed
* Deprecate `twig_test_iterable` function. Use the native `is_iterable` instead.

# 3.7.1 (2023-08-28)

* Fix some phpdocs
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
],
"require": {
"php": ">=7.2.5",
"symfony/polyfill-php80": "^1.22",
"symfony/polyfill-mbstring": "^1.3",
"symfony/polyfill-ctype": "^1.8"
},
Expand Down
3 changes: 3 additions & 0 deletions doc/deprecated.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ Deprecated Features
This document lists deprecated features in Twig 3.x. Deprecated features are
kept for backward compatibility and removed in the next major release (a
feature that was deprecated in Twig 3.x is removed in Twig 4.0).

The `twig_test_iterable` function is deprecated; use the native `is_iterable`
instead.
4 changes: 0 additions & 4 deletions doc/tags/macro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,6 @@ When calling ``import`` or ``from`` from a ``block`` tag, the imported macros
are only defined in the current block and they override macros defined at the
template level with the same names.

When calling ``import`` or ``from`` from a ``macro`` tag, the imported macros
are only defined in the current macro and they override macros defined at the
template level with the same names.

Checking if a Macro is defined
------------------------------

Expand Down
9 changes: 5 additions & 4 deletions doc/templates.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Many IDEs support syntax highlighting and auto-completion for Twig:
* *Notepad++* via the `Notepad++ Twig Highlighter`_
* *Emacs* via `web-mode.el`_
* *Atom* via the `PHP-twig for atom`_
* *Visual Studio Code* via the `Twig pack`_ or `Modern Twig`_
* *Visual Studio Code* via the `Twig pack`_, `Modern Twig`_ or `Twiggy`_

You might also be interested in:

Expand Down Expand Up @@ -753,10 +753,10 @@ The following operators don't fit into any of the other categories:

.. code-block:: twig
{{ 1..5 }}
{% for i in 1..5 %}{{ i }}{% endfor %}
{# equivalent to #}
{{ range(1, 5) }}
{# is equivalent to #}
{% for i in range(1, 5) %}{{ i }}{% endfor %}
Note that you must use parentheses when combining it with the filter operator
due to the :ref:`operator precedence rules <twig-expressions>`:
Expand Down Expand Up @@ -891,3 +891,4 @@ Twig can be extended. If you want to create your own extensions, read the
.. _`Twig pack`: https://marketplace.visualstudio.com/items?itemName=bajdzis.vscode-twig-pack
.. _`Modern Twig`: https://marketplace.visualstudio.com/items?itemName=Stanislav.vscode-twig
.. _`Twig Language Server`: https://github.com/kaermorchen/twig-language-server/tree/master/packages/language-server
.. _`Twiggy`: https://marketplace.visualstudio.com/items?itemName=moetelo.twiggy
4 changes: 2 additions & 2 deletions extra/cache-extra/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
"require": {
"php": ">=7.2.5",
"symfony/cache": "^5.0|^6.0|^7.0",
"twig/twig": "^2.4|^3.0"
"twig/twig": "^3.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0|^7.0"
"symfony/phpunit-bridge": "^6.4|^7.0"
},
"autoload": {
"psr-4" : { "Twig\\Extra\\Cache\\" : "" },
Expand Down
6 changes: 3 additions & 3 deletions extra/cssinliner-extra/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
}
],
"require": {
"php": ">=7.1.3",
"php": ">=7.2.5",
"tijsverkoyen/css-to-inline-styles": "^2.0",
"twig/twig": "^2.7|^3.0"
"twig/twig": "^3.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^5.4|^6.3|^7.0"
"symfony/phpunit-bridge": "^6.4|^7.0"
},
"autoload": {
"psr-4" : { "Twig\\Extra\\CssInliner\\" : "" },
Expand Down
6 changes: 3 additions & 3 deletions extra/html-extra/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
}
],
"require": {
"php": ">=7.1.3",
"php": ">=7.2.5",
"symfony/mime": "^5.4|^6.0|^7.0",
"twig/twig": "^2.7|^3.0"
"twig/twig": "^3.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^5.4|^6.3|^7.0"
"symfony/phpunit-bridge": "^6.4|^7.0"
},
"autoload": {
"psr-4" : { "Twig\\Extra\\Html\\" : "" },
Expand Down
6 changes: 3 additions & 3 deletions extra/inky-extra/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
}
],
"require": {
"php": ">=7.1.3",
"php": ">=7.2.5",
"lorenzo/pinky": "^1.0.5",
"twig/twig": "^2.7|^3.0"
"twig/twig": "^3.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^5.4|^6.3|^7.0"
"symfony/phpunit-bridge": "^6.4|^7.0"
},
"autoload": {
"psr-4" : { "Twig\\Extra\\Inky\\" : "" },
Expand Down
23 changes: 17 additions & 6 deletions extra/intl-extra/IntlExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ private static function availableDateFormats(): array
'int32' => \NumberFormatter::TYPE_INT32,
'int64' => \NumberFormatter::TYPE_INT64,
'double' => \NumberFormatter::TYPE_DOUBLE,
'currency' => \NumberFormatter::TYPE_CURRENCY,
];
private const NUMBER_STYLES = [
'decimal' => \NumberFormatter::DECIMAL,
Expand Down Expand Up @@ -370,7 +369,14 @@ public function formatNumberStyle(string $style, $number, array $attrs = [], str
public function formatDateTime(Environment $env, $date, ?string $dateFormat = 'medium', ?string $timeFormat = 'medium', string $pattern = '', $timezone = null, string $calendar = 'gregorian', string $locale = null): string
{
$date = twig_date_converter($env, $date, $timezone);
$formatter = $this->createDateFormatter($locale, $dateFormat, $timeFormat, $pattern, $date->getTimezone(), $calendar);

$formatterTimezone = $timezone;
if (null === $formatterTimezone) {
$formatterTimezone = $date->getTimezone();
} elseif (\is_string($formatterTimezone)) {
$formatterTimezone = new \DateTimeZone($timezone);
}
$formatter = $this->createDateFormatter($locale, $dateFormat, $timeFormat, $pattern, $formatterTimezone, $calendar);

if (false === $ret = $formatter->format($date)) {
throw new RuntimeError('Unable to format the given date.');
Expand All @@ -397,7 +403,7 @@ public function formatTime(Environment $env, $date, ?string $timeFormat = 'mediu
return $this->formatDateTime($env, $date, 'none', $timeFormat, $pattern, $timezone, $calendar, $locale);
}

private function createDateFormatter(?string $locale, ?string $dateFormat, ?string $timeFormat, string $pattern, \DateTimeZone $timezone, string $calendar): \IntlDateFormatter
private function createDateFormatter(?string $locale, ?string $dateFormat, ?string $timeFormat, string $pattern, ?\DateTimeZone $timezone, string $calendar): \IntlDateFormatter
{
$dateFormats = self::availableDateFormats();

Expand All @@ -410,7 +416,10 @@ private function createDateFormatter(?string $locale, ?string $dateFormat, ?stri
}

if (null === $locale) {
$locale = \Locale::getDefault();
if ($this->dateFormatterPrototype) {
$locale = $this->dateFormatterPrototype->getLocale();
}
$locale = $locale ?: \Locale::getDefault();
}

$calendar = 'gregorian' === $calendar ? \IntlDateFormatter::GREGORIAN : \IntlDateFormatter::TRADITIONAL;
Expand All @@ -421,12 +430,14 @@ private function createDateFormatter(?string $locale, ?string $dateFormat, ?stri
if ($this->dateFormatterPrototype) {
$dateFormatValue = $dateFormatValue ?: $this->dateFormatterPrototype->getDateType();
$timeFormatValue = $timeFormatValue ?: $this->dateFormatterPrototype->getTimeType();
$timezone = $timezone ?: $this->dateFormatterPrototype->getTimeType();
$timezone = $timezone ?: $this->dateFormatterPrototype->getTimeZone()->toDateTimeZone();
$calendar = $calendar ?: $this->dateFormatterPrototype->getCalendar();
$pattern = $pattern ?: $this->dateFormatterPrototype->getPattern();
}

$hash = $locale.'|'.$dateFormatValue.'|'.$timeFormatValue.'|'.$timezone->getName().'|'.$calendar.'|'.$pattern;
$timezoneName = $timezone ? $timezone->getName() : '(none)';

$hash = $locale.'|'.$dateFormatValue.'|'.$timeFormatValue.'|'.$timezoneName.'|'.$calendar.'|'.$pattern;

if (!isset($this->dateFormatters[$hash])) {
$this->dateFormatters[$hash] = new \IntlDateFormatter($locale, $dateFormatValue, $timeFormatValue, $timezone, $calendar, $pattern);
Expand Down
56 changes: 55 additions & 1 deletion extra/intl-extra/Tests/IntlExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,71 @@
namespace Twig\Extra\Intl\Tests;

use PHPUnit\Framework\TestCase;
use Twig\Environment;
use Twig\Extension\CoreExtension;
use Twig\Extra\Intl\IntlExtension;
use Twig\Loader\ArrayLoader;

class IntlExtensionTest extends TestCase
{
public function testFormatterWithoutProto()
{
$ext = new IntlExtension();
$env = new Environment(new ArrayLoader());

$this->assertSame('12.346', $ext->formatNumber('12.3456'));
$this->assertSame(
'Feb 20, 2020, 1:37:00 PM',
$ext->formatDateTime($env, new \DateTime('2020-02-20T13:37:00+00:00'))
);
}

public function testFormatterWithoutProtoFallsBackToCoreExtensionTimezone()
{
$ext = new IntlExtension();
$env = new Environment(new ArrayLoader());
// EET is always +2 without changes for daylight saving time
// so it has a fixed difference to UTC
$env->getExtension(CoreExtension::class)->setTimezone('EET');

$this->assertSame(
'Feb 20, 2020, 3:37:00 PM',
$ext->formatDateTime($env, new \DateTime('2020-02-20T13:37:00+00:00', new \DateTimeZone('UTC')))
);
}

public function testFormatterProto()
{
$dateFormatterProto = new \IntlDateFormatter('fr', \IntlDateFormatter::FULL, \IntlDateFormatter::FULL);
$dateFormatterProto = new \IntlDateFormatter('fr', \IntlDateFormatter::FULL, \IntlDateFormatter::FULL, new \DateTimeZone('Europe/Paris'));
$numberFormatterProto = new \NumberFormatter('fr', \NumberFormatter::DECIMAL);
$numberFormatterProto->setTextAttribute(\NumberFormatter::POSITIVE_PREFIX, '++');
$numberFormatterProto->setAttribute(\NumberFormatter::FRACTION_DIGITS, 1);
$ext = new IntlExtension($dateFormatterProto, $numberFormatterProto);
$env = new Environment(new ArrayLoader());

$this->assertSame('++12,3', $ext->formatNumber('12.3456'));
$this->assertSame(
'jeudi 20 février 2020 à 14:37:00 heure normale d’Europe centrale',
$ext->formatDateTime($env, new \DateTime('2020-02-20T13:37:00+00:00'))
);
}

public function testFormatterOverridenProto()
{
$dateFormatterProto = new \IntlDateFormatter('fr', \IntlDateFormatter::FULL, \IntlDateFormatter::FULL, new \DateTimeZone('Europe/Paris'));
$numberFormatterProto = new \NumberFormatter('fr', \NumberFormatter::DECIMAL);
$numberFormatterProto->setTextAttribute(\NumberFormatter::POSITIVE_PREFIX, '++');
$numberFormatterProto->setAttribute(\NumberFormatter::FRACTION_DIGITS, 1);
$ext = new IntlExtension($dateFormatterProto, $numberFormatterProto);
$env = new Environment(new ArrayLoader());

$this->assertSame(
'twelve point three',
$ext->formatNumber('12.3456', [], 'spellout', 'default', 'en_US')
);
$this->assertSame(
'2020-02-20 13:37:00',
$ext->formatDateTime($env, new \DateTime('2020-02-20T13:37:00+00:00'), 'short', 'short', 'yyyy-MM-dd HH:mm:ss', 'UTC', 'gregorian', 'en_US')
);
}
}
6 changes: 3 additions & 3 deletions extra/intl-extra/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
}
],
"require": {
"php": ">=7.1.3",
"twig/twig": "^2.7|^3.0",
"php": ">=7.2.5",
"twig/twig": "^3.0",
"symfony/intl": "^5.4|^6.0|^7.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^5.4|^6.3|^7.0"
"symfony/phpunit-bridge": "^6.4|^7.0"
},
"autoload": {
"psr-4" : { "Twig\\Extra\\Intl\\" : "" },
Expand Down
2 changes: 1 addition & 1 deletion extra/markdown-extra/MarkdownExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function twig_html_to_markdown(string $body, array $options = []): string
throw new \LogicException('You cannot use the "html_to_markdown" filter as league/html-to-markdown is not installed; try running "composer require league/html-to-markdown".');
}

$options = $options + [
$options += [
'hard_break' => true,
'strip_tags' => true,
'remove_nodes' => 'head style',
Expand Down
2 changes: 1 addition & 1 deletion extra/markdown-extra/Tests/FunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class FunctionalTest extends TestCase
*/
public function testMarkdown(string $template, string $expected): void
{
foreach ([LeagueMarkdown::class, ErusevMarkdown::class, /*MichelfMarkdown::class,*/ DefaultMarkdown::class] as $class) {
foreach ([LeagueMarkdown::class, ErusevMarkdown::class, /* MichelfMarkdown::class, */ DefaultMarkdown::class] as $class) {
$twig = new Environment(new ArrayLoader([
'index' => $template,
'html' => <<<EOF
Expand Down
6 changes: 3 additions & 3 deletions extra/markdown-extra/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
}
],
"require": {
"php": ">=7.1.3",
"twig/twig": "^2.7|^3.0"
"php": ">=7.2.5",
"twig/twig": "^3.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^5.4|^6.3|^7.0",
"symfony/phpunit-bridge": "^6.4|^7.0",
"erusev/parsedown": "^1.7",
"league/commonmark": "^1.0|^2.0",
"league/html-to-markdown": "^4.8|^5.0",
Expand Down
4 changes: 2 additions & 2 deletions extra/string-extra/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
"php": ">=7.2.5",
"symfony/string": "^5.4|^6.0|^7.0",
"symfony/translation-contracts": "^1.1|^2|^3",
"twig/twig": "^2.7|^3.0"
"twig/twig": "^3.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^5.4|^6.3|^7.0"
"symfony/phpunit-bridge": "^6.4|^7.0"
},
"autoload": {
"psr-4" : { "Twig\\Extra\\String\\" : "" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function load(array $configs, ContainerBuilder $container)
if ($this->isConfigEnabled($container, $config[$extension])) {
$loader->load($extension.'.php');

if ('markdown' === $extension && \class_exists(CommonMarkConverter::class)) {
if ('markdown' === $extension && class_exists(CommonMarkConverter::class)) {
$loader->load('markdown_league.php');
}
}
Expand Down
2 changes: 1 addition & 1 deletion extra/twig-extra-bundle/Tests/Fixture/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

use League\CommonMark\Extension\Strikethrough\StrikethroughExtension;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Bundle\TwigBundle\TwigBundle;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Twig\Extra\TwigExtraBundle\TwigExtraBundle;

class Kernel extends BaseKernel
Expand Down
4 changes: 2 additions & 2 deletions extra/twig-extra-bundle/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
"php": ">=7.2.5",
"symfony/framework-bundle": "^5.4|^6.0|^7.0",
"symfony/twig-bundle": "^5.4|^6.0|^7.0",
"twig/twig": "^2.7|^3.0"
"twig/twig": "^3.0"
},
"require-dev": {
"league/commonmark": "^1.0|^2.0",
"symfony/phpunit-bridge": "^5.4|^6.3|^7.0",
"symfony/phpunit-bridge": "^6.4|^7.0",
"twig/cache-extra": "^3.0",
"twig/cssinliner-extra": "^2.12|^3.0",
"twig/html-extra": "^2.12|^3.0",
Expand Down
2 changes: 1 addition & 1 deletion src/Cache/FilesystemCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public function write(string $key, string $content): void

if (self::FORCE_BYTECODE_INVALIDATION == ($this->options & self::FORCE_BYTECODE_INVALIDATION)) {
// Compile cached file into bytecode cache
if (\function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN)) {
if (\function_exists('opcache_invalidate') && filter_var(\ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN)) {
@opcache_invalidate($key, true);
} elseif (\function_exists('apc_compile_file')) {
apc_compile_file($key);
Expand Down
Loading

0 comments on commit 633800a

Please # to comment.