AbstractCollection::isTraversable()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 8
cts 8
cp 1
rs 9.7666
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 3
1
<?php
2
declare(strict_types=1);
3
4
namespace KGzocha\Searcher;
5
6
/**
7
 * @author Krzysztof Gzocha <[email protected]>
8
 */
9
abstract class AbstractCollection implements \Countable, \IteratorAggregate
10
{
11
    /**
12
     * @var array
13
     */
14
    private $items;
15
16
    /**
17
     * @param \Traversable|array $items
18
     */
19 75
    public function __construct($items = [])
20
    {
21 75
        $this->items = [];
22 75
        $this->isTraversable($items);
23 54
        $this->checkItems($items);
24
25 44
        $this->items = $items;
26 44
    }
27
28
    /**
29
     * @param object $item
30
     *
31
     * @return bool
32
     */
33
    abstract protected function isItemValid($item): bool;
34
35
    /**
36
     * {@inheritdoc}
37
     */
38 10
    public function getIterator(): \Iterator
39
    {
40 10
        foreach ($this->items as $key => $item) {
41 8
            yield $key => $item;
42
        }
43 10
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48 23
    public function count()
49
    {
50 23
        return count($this->items);
51
    }
52
53
    /**
54
     * @param mixed $item
55
     *
56
     * @return self
57
     */
58 6
    protected function addItem($item): AbstractCollection
59
    {
60 6
        $this->items[] = $item;
61
62 6
        return $this;
63
    }
64
65
    /**
66
     * @param string $name
67
     * @param mixed  $item
68
     *
69
     * @return self
70
     */
71 11
    protected function addNamedItem(string $name, $item): AbstractCollection
72
    {
73 11
        $this->items[$name] = $item;
74
75 11
        return $this;
76
    }
77
78
    /**
79
     * @return array
80
     */
81 27
    protected function getItems()
82
    {
83 27
        return $this->items;
84
    }
85
86
    /**
87
     * @param string $name
88
     *
89
     * @return mixed|null
90
     */
91 3
    protected function getNamedItem(string $name)
92
    {
93 3
        if (array_key_exists($name, $this->items)) {
94 2
            return $this->items[$name];
95
        }
96
97 1
        return null;
98
    }
99
100
    /**
101
     * @param mixed $items
102
     *
103
     * @throws \InvalidArgumentException
104
     */
105 75
    private function isTraversable($items)
106
    {
107 75
        if (is_array($items)) {
108 52
            return;
109
        }
110
111 25
        if ($items instanceof \Traversable) {
112 4
            return;
113
        }
114
115 21
        throw new \InvalidArgumentException(sprintf(
116 21
            'Argument passed to collection %s needs to be an array or traversable object',
117 21
            get_class($this)
118
        ));
119
    }
120
121
    /**
122
     * @param array|\Traversable $items
123
     *
124
     * @throws \InvalidArgumentException
125
     */
126 54
    private function checkItems($items)
127
    {
128 54
        foreach ($items as $item) {
129 40
            if ($this->isItemValid($item)) {
130 30
                continue;
131
            }
132
133 11
            throw new \InvalidArgumentException(sprintf(
134 11
                'At least one item in collection "%s" is invalid.',
135 11
                get_class($this)
136
            ));
137
        }
138 44
    }
139
}
140