Collection::only()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
cc 2
eloc 3
nc 2
nop 1
crap 2
1
<?php
2
3
namespace Raidros\Collection;
4
5
use Raidros\Collection\Exceptions\CollectionItemNotFoundException;
6
use Raidros\Collection\Exceptions\InvalidCollectionItemInstanceException;
7
8
class Collection
9
{
10
    /**
11
     * Collection items.
12
     *
13
     * @var array
14
     */
15
    private $items = [];
16
17
    /**
18
     * Implementation namespace.
19
     *
20
     * @var string
21
     */
22
    private $classname;
23
24
    /**
25
     * Create a new collection instance.
26
     *
27
     * @param string|null $classname
28
     * @param array       $items
29
     */
30 72
    public function __construct($classname = null, array $items = [])
31
    {
32 72
        $this->items = $items;
33 72
        $this->classname = $classname;
34 72
    }
35
36
    /**
37
     * Add a new item to collection.
38
     *
39
     * @param string $name
40
     * @param mixed  $value
41
     *
42
     * @return self
43
     */
44 72
    public function put($name, $value)
45
    {
46 72
        if (is_object($value) && !$this->isValidObjectInstance($value)) {
47 12
            throw new InvalidCollectionItemInstanceException(sprintf('%s must implement %s', $name, $this->classname));
48
        }
49
50 60
        $this->items[$name] = $value;
51
52 60
        return $this->items[$name];
53
    }
54
55
    /**
56
     * Verify's if the given object has a valid instance.
57
     *
58
     * @param object $object
59
     *
60
     * @return bool
61
     */
62 69
    private function isValidObjectInstance($object)
63
    {
64 69
        if (!is_null($this->classname) && !$this->isInstanceOrSubclassOf($object)) {
65 12
            return false;
66
        }
67
68 57
        return true;
69
    }
70
71
    /**
72
     * Check object instance.
73
     *
74
     * @param object $object
75
     *
76
     * @return bool
77
     */
78 69
    private function isInstanceOrSubclassOf($object)
79
    {
80 69
        return $object instanceof $this->classname || is_subclass_of($object, $this->classname);
81
    }
82
83
    /**
84
     * Get all items from collection.
85
     *
86
     * @return array
87
     */
88 15
    public function all()
89
    {
90 15
        return $this->items;
91
    }
92
93
    /**
94
     * Find collection item by name.
95
     *
96
     * @param string $name
97
     *
98
     * @return mixed|null
99
     */
100 33
    public function find($name)
101
    {
102 33
        if ($this->has($name)) {
103 21
            return $this->items[$name];
104
        }
105 12
    }
106
107
    /**
108
     * Check if the given item exists on collection.
109
     *
110
     * @param string $name
111
     *
112
     * @return bool
113
     */
114 42
    public function has($name)
115
    {
116 42
        return array_key_exists($name, $this->items);
117
    }
118
119
    /**
120
     * Find a specific collection item or throw's an exception.
121
     *
122
     * @param string $name
123
     *
124
     * @return mixed
125
     */
126 12
    public function findOrFail($name)
127
    {
128 12
        $result = $this->find($name);
129
130 12
        if (is_null($result)) {
131 3
            throw new CollectionItemNotFoundException(sprintf('Collection item "%s" not found', $name));
132
        }
133
134 9
        return $result;
135
    }
136
137
    /**
138
     * Run a callback over each item.
139
     *
140
     * @param callable $callback
141
     *
142
     * @return self
143
     */
144 3
    public function each(callable $callback)
145
    {
146 3
        if ($this->count()) {
147 3
            array_walk($this->items, $callback);
148 3
        }
149
150 3
        return $this;
151
    }
152
153
    /**
154
     * Remove an item from collection.
155
     *
156
     * @param string $name
157
     *
158
     * @return self
159
     */
160 9
    public function remove($name)
161
    {
162 9
        if ($this->has($name)) {
163 9
            unset($this->items[$name]);
164 9
        }
165
166 9
        return $this;
167
    }
168
169
    /**
170
     * Count total of items on collection.
171
     *
172
     * @return int
173
     */
174 6
    public function count()
175
    {
176 6
        return count($this->items);
177
    }
178
179
    /**
180
     * Get all items except for those with the specified keys.
181
     *
182
     * @param mixed $key
183
     *
184
     * @return static
185
     */
186 3
    public function except($key)
187
    {
188 3
        $keys = is_array($key) ? $key : func_get_args();
189
190 3
        return new static($this->classname, array_diff_key($this->items, $this->filterByKeys($keys)));
191
    }
192
193
    /**
194
     * Filter items by key name.
195
     *
196
     * @param array $keys
197
     *
198
     * @return array
199
     */
200 6
    private function filterByKeys(array $keys)
201
    {
202 6
        $results = [];
203
204 6
        foreach ($this->items as $key => $value) {
205 6
            if (!in_array($key, $keys)) {
206 6
                continue;
207
            }
208
209 6
            $results[$key] = $value;
210 6
        }
211
212 6
        return $results;
213
    }
214
215
    /**
216
     * Run a map over each item in the collection.
217
     *
218
     * @param callable $callback
219
     *
220
     * @return static
221
     */
222 3
    public function map(callable $callback)
223
    {
224 3
        $keys = array_keys($this->items);
225 3
        $items = array_map($callback, $this->items, $keys);
226
227 3
        return new static($this->classname, array_combine($keys, $items));
228
    }
229
230
    /**
231
     * Get all items with the specified keys.
232
     *
233
     * @param mixed $key
234
     *
235
     * @return static
236
     */
237 3
    public function only($key)
238
    {
239 3
        $keys = is_array($key) ? $key : func_get_args();
240
241 3
        return new static($this->classname, $this->filterByKeys($keys));
242
    }
243
244
    /**
245
     * Filter the elements in the collection using a callback function.
246
     *
247
     * @param callable|null $callback
248
     *
249
     * @return static
250
     */
251 3
    public function filter(callable $callback = null)
252
    {
253 3
        if (is_null($callback)) {
254 3
            return new static($this->classname, array_filter($this->items));
255
        }
256
257 3
        return new static($this->classname, array_filter($this->items, $callback));
258
    }
259
}
260