MapIterator::key()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace TheCodingMachine\TDBM;
6
7
use Iterator;
8
use IteratorAggregate;
9
use Traversable;
10
11
/**
12
 * An iterator that maps element of another iterator by calling a callback on it.
13
 */
14
class MapIterator implements Iterator, \JsonSerializable
15
{
16
    /**
17
     * @var Iterator
18
     */
19
    protected $iterator;
20
21
    /**
22
     * @var callable Modifies the current item in iterator
23
     */
24
    protected $callable;
25
26
    /**
27
     * @param Traversable|array $iterator
28
     * @param callable $callable This can have two parameters
29
     *
30
     * @throws TDBMException
31
     */
32
    public function __construct($iterator, callable $callable)
33
    {
34
        if (is_array($iterator)) {
35
            $this->iterator = new \ArrayIterator($iterator);
36
        } elseif ($iterator instanceof Iterator) {
37
            $this->iterator = $iterator;
38
        } elseif ($iterator instanceof IteratorAggregate) {
39
            while (!$iterator instanceof Iterator) {
40
                $iterator = $iterator->getIterator();
0 ignored issues
show
Bug introduced by
The method getIterator() does not exist on Traversable. It seems like you code against a sub-type of Traversable such as IteratorAggregate or IntlCodePointBreakIterator or IntlRuleBasedBreakIterator or SplFixedArray. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

40
                /** @scrutinizer ignore-call */ 
41
                $iterator = $iterator->getIterator();
Loading history...
41
            }
42
            $this->iterator = $iterator;
43
        } else {
44
            throw new TDBMException('$iterator parameter must be an instance of Iterator');
45
        }
46
47
        if ($callable instanceof \Closure) {
48
            // make sure there's one argument
49
            $reflection = new \ReflectionObject($callable);
50
            if ($reflection->hasMethod('__invoke')) {
51
                $method = $reflection->getMethod('__invoke');
52
                if ($method->getNumberOfParameters() !== 1) {
53
                    throw new TDBMException('$callable must accept one and only one parameter.');
54
                }
55
            }
56
        }
57
58
        $this->callable = $callable;
59
    }
60
61
    /**
62
     * Alters the current item with $this->callable and returns a new item.
63
     * Be careful with your types as we can't do static type checking here!
64
     *
65
     * @return mixed
66
     */
67
    public function current(): mixed
68
    {
69
        $callable = $this->callable;
70
71
        return $callable($this->iterator->current());
72
    }
73
74
    public function next(): void
75
    {
76
        $this->iterator->next();
77
    }
78
79
    /**
80
     * @return mixed
81
     */
82
    public function key(): mixed
83
    {
84
        return $this->iterator->key();
85
    }
86
87
    public function valid(): bool
88
    {
89
        return $this->iterator->valid();
90
    }
91
92
    public function rewind(): void
93
    {
94
        $this->iterator->rewind();
95
    }
96
97
    /**
98
     * Casts the iterator to a PHP array.
99
     *
100
     * @return mixed[]
101
     */
102
    public function toArray(): array
103
    {
104
        return iterator_to_array($this);
105
    }
106
107
    public function jsonSerialize(): mixed
108
    {
109
        return $this->toArray();
110
    }
111
}
112