Add Traversable support of length filter

This commit is contained in:
SpacePossum
2019-04-01 11:44:13 +02:00
committed by Fabien Potencier
parent 9d5676dea1
commit 3a32f4a58b
3 changed files with 46 additions and 10 deletions
+6 -10
View File
@@ -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;
}
@@ -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('<?xml version="1.0" encoding="UTF-8"?><doc><elem/><elem/></doc>'),
'iterator' => new \SimpleIteratorForTesting()
]
--EXPECT--
2
@@ -35,3 +37,4 @@ return [
1
1
2
7
+37
View File
@@ -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);
}
}