diff --git a/src/Extension/CoreExtension.php b/src/Extension/CoreExtension.php index 8cb988d26f6..8e4c31c224f 100644 --- a/src/Extension/CoreExtension.php +++ b/src/Extension/CoreExtension.php @@ -417,10 +417,8 @@ public static function cycle($values, $position): mixed trigger_deprecation('twig/twig', '3.12', 'Passing a non-countable sequence of values to "%s()" is deprecated.', __METHOD__); - return $values; + $values = self::toArray($values, false); } - - $values = self::toArray($values, false); } if (!$count = \count($values)) { diff --git a/tests/Extension/CoreTest.php b/tests/Extension/CoreTest.php index 10d7e881daa..2828d297c40 100644 --- a/tests/Extension/CoreTest.php +++ b/tests/Extension/CoreTest.php @@ -21,6 +21,7 @@ */ use PHPUnit\Framework\TestCase; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Twig\Environment; use Twig\Error\RuntimeError; use Twig\Extension\CoreExtension; @@ -31,6 +32,8 @@ class CoreTest extends TestCase { + use ExpectDeprecationTrait; + /** * @dataProvider provideCycleCases */ @@ -407,6 +410,44 @@ public function testLastModified() { $this->assertGreaterThan(1000000000, (new CoreExtension())->getLastModified()); } + + /** + * @group legacy + */ + public function testCycleWithArrayAccessAndTraversableButNotCountable() + { + $this->expectDeprecation('Since twig/twig 3.12: Passing a non-countable sequence of values to "Twig\Extension\CoreExtension::cycle()" is deprecated.'); + + $seq = new class implements \ArrayAccess, \IteratorAggregate { + public function offsetExists($offset): bool + { + return true; + } + + public function offsetGet($offset): mixed + { + return 'val'; + } + + public function offsetSet($offset, $value): void + { + } + + public function offsetUnset($offset): void + { + } + + public function getIterator(): \Traversable + { + yield 'odd'; + yield 'even'; + } + }; + + $result = CoreExtension::cycle($seq, 0); + + $this->assertEquals('odd', $result, 'cycle should return the first item from the traversable sequence, not the sequence itself.'); + } } final class CoreTestIteratorAggregate implements \IteratorAggregate