diff --git a/CHANGELOG b/CHANGELOG index 7e9ad26144..b5e117f4b2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ * 1.38.0 (2019-XX-XX) + * fixed batch filter clobbers array keys when fill parameter is used + * added preserveKeys support for the batch filter * fixed "embed" support when used from "template_from_string" * added the possibility to pass a TemplateWrapper to Twig\Environment::load() * improved the performance of the sandbox diff --git a/src/Extension/CoreExtension.php b/src/Extension/CoreExtension.php index 21178b6ef3..63265d619a 100644 --- a/src/Extension/CoreExtension.php +++ b/src/Extension/CoreExtension.php @@ -1638,23 +1638,22 @@ function twig_constant_is_defined($constant, $object = null) * * @return array */ -function twig_array_batch($items, $size, $fill = null) +function twig_array_batch($items, $size, $fill = null, $preserveKeys = true) { if ($items instanceof \Traversable) { - $items = iterator_to_array($items, false); + $items = iterator_to_array($items, $preserveKeys); } $size = ceil($size); - $result = array_chunk($items, $size, true); + $result = array_chunk($items, $size, $preserveKeys); - if (null !== $fill && !empty($result)) { + if (null !== $fill && $result) { $last = \count($result) - 1; if ($fillCount = $size - \count($result[$last])) { - $result[$last] = array_merge( - $result[$last], - array_fill(0, $fillCount, $fill) - ); + for ($i = 0; $i < $fillCount; $i++) { + $result[$last][] = $fill; + } } } diff --git a/test/Twig/Tests/Fixtures/filters/batch_with_keys.test b/test/Twig/Tests/Fixtures/filters/batch_with_keys.test index f3279a636f..e56cd79bbc 100644 --- a/test/Twig/Tests/Fixtures/filters/batch_with_keys.test +++ b/test/Twig/Tests/Fixtures/filters/batch_with_keys.test @@ -1,8 +1,8 @@ --TEST-- "batch" filter preserves array keys --TEMPLATE-- -{{ {'foo': 'bar', 'key': 'value'}|batch(4)|first|keys|join(',') }} -{{ {'foo': 'bar', 'key': 'value'}|batch(4, 'fill')|first|keys|join(',') }} +{{ {'foo': 'bar', 'key': 'value'}|batch(4)|first|keys|join(',') }} +{{ {'foo': 'bar', 'key': 'value'}|batch(4, 'fill')|first|keys|join(',') }} --DATA-- return [] --EXPECT-- diff --git a/test/Twig/Tests/Fixtures/filters/batch_with_more_elements.test b/test/Twig/Tests/Fixtures/filters/batch_with_more_elements.test new file mode 100644 index 0000000000..90f4de6859 --- /dev/null +++ b/test/Twig/Tests/Fixtures/filters/batch_with_more_elements.test @@ -0,0 +1,23 @@ +--TEST-- +"batch" filter +--TEMPLATE-- +{% for row in items|batch(3, 'fill') %} +
+ {% for key, column in row %} +
{{ column }}
+ {% endfor %} +
+{% endfor %} +--DATA-- +return ['items' => ['a' => 'a', 'b' => 'b', 'c' => 'c', 'd' => 'd', '123' => 'e']] +--EXPECT-- +
+
a
+
b
+
c
+
+
+
d
+
e
+
fill
+