Passed
Push — master ( e65a8a...7854bb )
by Tomáš
02:15
created

Collection::add()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 7
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types = 1);
2
3
namespace Apicart\Utils\Arrays;
4
5
use ArrayAccess;
6
use Countable;
7
use Iterator;
8
use IteratorAggregate;
9
use RecursiveArrayIterator;
10
11
final class Collection implements ArrayAccess, Countable, IteratorAggregate
12
{
13
14
	/**
15
	 * @var callable
16
	 */
17
	private $callable;
18
19
	/**
20
	 * @var array
21
	 */
22
	private $loadedData = null;
23
24
25 11
	public function __construct(callable $dataProvider)
26
	{
27 11
		$this->callable = $dataProvider;
28 11
	}
29
30
31
	public function createFrom(callable $dataProvider): self
32
	{
33
		return new static($dataProvider);
34
	}
35
36
37
	/**
38
	 * @return mixed|null
39
	 */
40 1
	public function column(int $index = 0)
41
	{
42 1
		$firstRow = $this->first();
43 1
		if (is_array($firstRow) === true) {
44
			$values = array_values($firstRow);
45
46
			return $values[$index] ?? null;
47
		}
48
49 1
		return null;
50
	}
51
52
53
	/**
54
	 * @return mixed|bool
55
	 */
56 2
	public function first()
57
	{
58 2
		$this->initialize();
59
60 2
		return reset($this->loadedData);
61
	}
62
63
64
	/**
65
	 * @return mixed|bool
66
	 */
67 1
	public function last()
68
	{
69 1
		$this->initialize();
70
71 1
		return end($this->loadedData);
72
	}
73
74
75
	/**
76
	 * @return int|string|null
77
	 */
78
	public function key()
79
	{
80
		$this->initialize();
81
82
		return key($this->loadedData);
83
	}
84
85
86
	/**
87
	 * @return mixed|bool
88
	 */
89
	public function next()
90
	{
91
		$this->initialize();
92
93
		return next($this->loadedData);
94
	}
95
96
97
	/**
98
	 * @return mixed|bool
99
	 */
100
	public function current()
101
	{
102
		$this->initialize();
103
104
		return current($this->loadedData);
105
	}
106
107
108
	/**
109
	 * @param int|string $key
110
	 * @return mixed|null
111
	 */
112 1
	public function remove($key)
113
	{
114 1
		$this->initialize();
115
116 1
		if (! isset($this->loadedData[$key]) && ! $this->contains($key)) {
117
			return null;
118
		}
119
120 1
		$removed = $this->loadedData[$key];
121 1
		unset($this->loadedData[$key]);
122
123 1
		return $removed;
124
	}
125
126
127
	/**
128
	 * @param mixed $element
129
	 * @return bool|int|string
130
	 */
131
	public function indexOf($element)
132
	{
133
		return array_search($element, $this->toArray(), true);
134
	}
135
136
137
	/**
138
	 * @param int|string $key
139
	 * @return mixed|null
140
	 */
141 2
	public function get($key)
142
	{
143 2
		$this->initialize();
144
145 2
		return $this->loadedData[$key] ?? null;
146
	}
147
148
149
	public function getKeys(): array
150
	{
151
		$this->initialize();
152
153
		return array_keys($this->loadedData);
154
	}
155
156
157
	public function getValues(): array
158
	{
159
		$this->initialize();
160
161
		return array_values($this->loadedData);
162
	}
163
164
165
	/**
166
	 * @param int|string $key
167
	 * @param mixed $value
168
	 */
169 1
	public function set($key, $value): void
170
	{
171 1
		$this->initialize();
172
173 1
		$this->loadedData[$key] = $value;
174 1
	}
175
176
177
	/**
178
	 * @param mixed $element
179
	 */
180
	public function add($element): bool
181
	{
182
		$this->initialize();
183
184
		$this->loadedData[] = $element;
185
186
		return true;
187
	}
188
189
190
	public function isEmpty(): bool
191
	{
192
		return $this->toArray() === [];
193
	}
194
195
196
	public function clear(): void
197
	{
198
		$this->initialize();
199
200
		$this->loadedData = [];
201
	}
202
203
204
	/**
205
	 * {@inheritdoc}
206
	 */
207 1
	public function getIterator(): Iterator
208
	{
209 1
		return new RecursiveArrayIterator($this->toArray());
210
	}
211
212
213
	/**
214
	 * @param mixed $offset
215
	 */
216 2
	public function offsetExists($offset): bool
217
	{
218 2
		return $this->contains($offset);
219
	}
220
221
222
	/**
223
	 * @param mixed $offset
224
	 * @return mixed
225
	 */
226 2
	public function offsetGet($offset)
227
	{
228 2
		return $this->get($offset);
229
	}
230
231
232
	/**
233
	 * @param mixed $offset
234
	 * @param mixed $value
235
	 */
236 1
	public function offsetSet($offset, $value): void
237
	{
238 1
		$this->set($offset, $value);
239 1
	}
240
241
242
	/**
243
	 * @param mixed $offset
244
	 */
245 1
	public function offsetUnset($offset): void
246
	{
247 1
		$this->remove($offset);
248 1
	}
249
250
251
	/**
252
	 * {@inheritdoc}
253
	 */
254 1
	public function count(): int
255
	{
256 1
		return count($this->toArray());
257
	}
258
259
260 4
	public function toArray(): array
261
	{
262 4
		$this->initialize();
263
264 4
		return $this->loadedData;
265
	}
266
267
268 11
	private function initialize(): void
269
	{
270 11
		if ($this->loadedData === null) {
271 11
			$data = call_user_func($this->callable);
272 11
			$this->loadedData = is_array($data) ? $data : [$data];
273
		}
274 11
	}
275
276
277
	/**
278
	 * @param int|string $key
279
	 */
280 2
	private function contains($key): bool
281
	{
282 2
		$this->initialize();
283
284 2
		return isset($this->loadedData[$key]) || array_key_exists($key, $this->loadedData);
285
	}
286
287
}
288