From 3a32f4a58bed686c81cdb23ff152113dbe3e250d Mon Sep 17 00:00:00 2001 From: SpacePossum Date: Mon, 1 Apr 2019 11:44:13 +0200 Subject: [PATCH] Add Traversable support of length filter --- src/Extension/CoreExtension.php | 16 ++++----- test/Twig/Tests/Fixtures/filters/length.test | 3 ++ test/Twig/Tests/IntegrationTest.php | 37 ++++++++++++++++++++ 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/Extension/CoreExtension.php b/src/Extension/CoreExtension.php index c959e315b..cf1447a2e 100644 --- a/src/Extension/CoreExtension.php +++ b/src/Extension/CoreExtension.php @@ -1301,22 +1301,18 @@ if (\function_exists('mb_get_info')) { return mb_strlen($thing, $env->getCharset()); } - if ($thing instanceof \SimpleXMLElement) { + if ($thing instanceof \Countable || \is_array($thing) || $thing instanceof \SimpleXMLElement) { return \count($thing); } - if (\is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) { - return mb_strlen((string) $thing, $env->getCharset()); - } - - if ($thing instanceof \Countable || \is_array($thing)) { - return \count($thing); - } - - if ($thing instanceof \IteratorAggregate) { + if ($thing instanceof \Traversable) { return iterator_count($thing); } + if (\is_object($thing) && method_exists($thing, '__toString')) { + return mb_strlen((string) $thing, $env->getCharset()); + } + return 1; } diff --git a/test/Twig/Tests/Fixtures/filters/length.test b/test/Twig/Tests/Fixtures/filters/length.test index 67d2f6ac8..52ad9e8b2 100644 --- a/test/Twig/Tests/Fixtures/filters/length.test +++ b/test/Twig/Tests/Fixtures/filters/length.test @@ -11,6 +11,7 @@ {{ magic|length }} {{ non_countable|length }} {{ simple_xml_element|length }} +{{ iterator|length }} --DATA-- return [ 'array' => [1, 4], @@ -23,6 +24,7 @@ return [ 'magic' => new MagicCallStub(), /* used to assert we do *not* call __call */ 'non_countable' => new \StdClass(), 'simple_xml_element' => new \SimpleXMLElement(''), + 'iterator' => new \SimpleIteratorForTesting() ] --EXPECT-- 2 @@ -35,3 +37,4 @@ return [ 1 1 2 +7 diff --git a/test/Twig/Tests/IntegrationTest.php b/test/Twig/Tests/IntegrationTest.php index 3d9a14cdd..e4b7d1d82 100644 --- a/test/Twig/Tests/IntegrationTest.php +++ b/test/Twig/Tests/IntegrationTest.php @@ -345,3 +345,40 @@ class IteratorAggregateStub implements \IteratorAggregate return new \ArrayIterator($this->data); } } + +class SimpleIteratorForTesting implements Iterator +{ + private $data = [1, 2, 3, 4, 5, 6, 7]; + private $key = 0; + + public function current() + { + return $this->key; + } + + public function next() + { + ++$this->key; + } + + public function key() + { + return $this->key; + } + + public function valid() + { + return isset($this->data[$this->key]); + } + + public function rewind() + { + $this->key = 0; + } + + public function __toString() + { + // for testing, make sure string length returned is not the same as the `iterator_count` + return str_repeat('X', iterator_count($this) + 10); + } +}