diff --git a/CHANGELOG b/CHANGELOG
index a0b9de2b713..faa5f4a20c6 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,6 @@
-# 3.7.2 (2023-XX-XX)
+# 3.8.0 (2023-XX-XX)
- * n/a
+ * Deprecate `twig_test_iterable` function. Use the native `is_iterable` instead.
# 3.7.1 (2023-08-28)
diff --git a/src/Extension/CoreExtension.php b/src/Extension/CoreExtension.php
index 2302f907355..d049d6f4e24 100644
--- a/src/Extension/CoreExtension.php
+++ b/src/Extension/CoreExtension.php
@@ -251,7 +251,7 @@ public function getTests(): array
new TwigTest('divisible by', null, ['node_class' => DivisiblebyTest::class, 'one_mandatory_argument' => true]),
new TwigTest('constant', null, ['node_class' => ConstantTest::class]),
new TwigTest('empty', 'twig_test_empty'),
- new TwigTest('iterable', 'twig_test_iterable'),
+ new TwigTest('iterable', 'is_iterable'),
];
}
@@ -391,7 +391,7 @@ function twig_random(Environment $env, $values = null, $max = null)
}
}
- if (!twig_test_iterable($values)) {
+ if (!is_iterable($values)) {
return $values;
}
@@ -528,7 +528,7 @@ function twig_date_converter(Environment $env, $date = null, $timezone = null)
*/
function twig_replace_filter($str, $from)
{
- if (!twig_test_iterable($from)) {
+ if (!is_iterable($from)) {
throw new RuntimeError(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".', \is_object($from) ? \get_class($from) : \gettype($from)));
}
@@ -625,7 +625,7 @@ function twig_array_merge(...$arrays)
$result = [];
foreach ($arrays as $argNumber => $array) {
- if (!twig_test_iterable($array)) {
+ if (!is_iterable($array)) {
throw new RuntimeError(sprintf('The merge filter only works with arrays or "Traversable", got "%s" for argument %d.', \gettype($array), $argNumber + 1));
}
@@ -655,7 +655,7 @@ function twig_slice(Environment $env, $item, $start, $length = null, $preserveKe
if ($start >= 0 && $length >= 0 && $item instanceof \Iterator) {
try {
- return iterator_to_array(new \LimitIterator($item, $start, null === $length ? -1 : $length), $preserveKeys);
+ return iterator_to_array(new \LimitIterator($item, $start, $length ?? -1), $preserveKeys);
} catch (\OutOfBoundsException $e) {
return [];
}
@@ -721,7 +721,7 @@ function twig_last(Environment $env, $item)
*/
function twig_join_filter($value, $glue = '', $and = null)
{
- if (!twig_test_iterable($value)) {
+ if (!is_iterable($value)) {
$value = (array) $value;
}
@@ -1229,7 +1229,7 @@ function twig_call_macro(Template $template, string $method, array $args, int $l
*/
function twig_ensure_traversable($seq)
{
- if ($seq instanceof \Traversable || \is_array($seq)) {
+ if (is_iterable($seq)) {
return $seq;
}
@@ -1292,10 +1292,12 @@ function twig_test_empty($value)
* @param mixed $value A variable
*
* @return bool true if the value is traversable
+ *
+ * @deprecated since Twig 3.8, to be removed in 4.0 (use the native "is_iterable" function instead)
*/
function twig_test_iterable($value)
{
- return $value instanceof \Traversable || \is_array($value);
+ return is_iterable($value);
}
/**
@@ -1427,7 +1429,7 @@ function twig_constant_is_defined($constant, $object = null)
*/
function twig_array_batch($items, $size, $fill = null, $preserveKeys = true)
{
- if (!twig_test_iterable($items)) {
+ if (!is_iterable($items)) {
throw new RuntimeError(sprintf('The "batch" filter expects an array or "Traversable", got "%s".', \is_object($items) ? \get_class($items) : \gettype($items)));
}
@@ -1671,7 +1673,7 @@ function twig_array_column($array, $name, $index = null): array
function twig_array_filter(Environment $env, $array, $arrow)
{
- if (!twig_test_iterable($array)) {
+ if (!is_iterable($array)) {
throw new RuntimeError(sprintf('The "filter" filter expects an array or "Traversable", got "%s".', \is_object($array) ? \get_class($array) : \gettype($array)));
}
diff --git a/src/Loader/FilesystemLoader.php b/src/Loader/FilesystemLoader.php
index 62267a11c89..e10c8f2b092 100644
--- a/src/Loader/FilesystemLoader.php
+++ b/src/Loader/FilesystemLoader.php
@@ -36,7 +36,7 @@ class FilesystemLoader implements LoaderInterface
*/
public function __construct($paths = [], string $rootPath = null)
{
- $this->rootPath = (null === $rootPath ? getcwd() : $rootPath).\DIRECTORY_SEPARATOR;
+ $this->rootPath = ($rootPath ?? getcwd()).\DIRECTORY_SEPARATOR;
if (null !== $rootPath && false !== ($realPath = realpath($rootPath))) {
$this->rootPath = $realPath.\DIRECTORY_SEPARATOR;
}
diff --git a/src/Node/WithNode.php b/src/Node/WithNode.php
index 56a334496e9..2ac9123d0d1 100644
--- a/src/Node/WithNode.php
+++ b/src/Node/WithNode.php
@@ -45,7 +45,7 @@ public function compile(Compiler $compiler): void
->write(sprintf('$%s = ', $varsName))
->subcompile($node)
->raw(";\n")
- ->write(sprintf("if (!twig_test_iterable(\$%s)) {\n", $varsName))
+ ->write(sprintf("if (!is_iterable(\$%s)) {\n", $varsName))
->indent()
->write("throw new RuntimeError('Variables passed to the \"with\" tag must be a hash.', ")
->repr($node->getTemplateLine())
diff --git a/src/NodeVisitor/EscaperNodeVisitor.php b/src/NodeVisitor/EscaperNodeVisitor.php
index 3d92ac9f258..c390d7cc71b 100644
--- a/src/NodeVisitor/EscaperNodeVisitor.php
+++ b/src/NodeVisitor/EscaperNodeVisitor.php
@@ -189,7 +189,7 @@ private function needEscaping()
return $this->statusStack[\count($this->statusStack) - 1];
}
- return $this->defaultStrategy ? $this->defaultStrategy : false;
+ return $this->defaultStrategy ?: false;
}
private function getEscaperFilter(string $type, Node $node): FilterExpression
diff --git a/src/Profiler/Dumper/HtmlDumper.php b/src/Profiler/Dumper/HtmlDumper.php
index 1f2433b4d36..3c0daf1c8d3 100644
--- a/src/Profiler/Dumper/HtmlDumper.php
+++ b/src/Profiler/Dumper/HtmlDumper.php
@@ -37,7 +37,7 @@ protected function formatTemplate(Profile $profile, $prefix): string
protected function formatNonTemplate(Profile $profile, $prefix): string
{
- return sprintf('%s└ %s::%s(%s)', $prefix, $profile->getTemplate(), $profile->getType(), isset(self::$colors[$profile->getType()]) ? self::$colors[$profile->getType()] : 'auto', $profile->getName());
+ return sprintf('%s└ %s::%s(%s)', $prefix, $profile->getTemplate(), $profile->getType(), self::$colors[$profile->getType()] ?? 'auto', $profile->getName());
}
protected function formatTime(Profile $profile, $percent): string
diff --git a/src/Test/NodeTestCase.php b/src/Test/NodeTestCase.php
index 3b8b2c86c67..8b1bef776d3 100644
--- a/src/Test/NodeTestCase.php
+++ b/src/Test/NodeTestCase.php
@@ -43,7 +43,7 @@ public function assertNodeCompilation($source, Node $node, Environment $environm
protected function getCompiler(Environment $environment = null)
{
- return new Compiler(null === $environment ? $this->getEnvironment() : $environment);
+ return new Compiler($environment ?? $this->getEnvironment());
}
protected function getEnvironment()