Collection::next()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 1
nop 0
dl 0
loc 7
ccs 0
cts 4
cp 0
crap 6
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|null
55
	 */
56 2
	public function first()
57
	{
58 2
		$this->initialize();
59
60 2
		$first = reset($this->loadedData);
61
62 2
		return $first ?: null;
63
	}
64
65
66
	/**
67
	 * @return mixed|bool
68
	 */
69 1
	public function last()
70
	{
71 1
		$this->initialize();
72
73 1
		$last = end($this->loadedData);
74
75 1
		return $last ?: null;
76
	}
77
78
79
	/**
80
	 * @return int|string|null
81
	 */
82
	public function key()
83
	{
84
		$this->initialize();
85
86
		return key($this->loadedData);
87
	}
88
89
90
	/**
91
	 * @return mixed|null
92
	 */
93
	public function next()
94
	{
95
		$this->initialize();
96
97
		$next = next($this->loadedData);
98
99
		return $next ?: null;
100
	}
101
102
103
	/**
104
	 * @return mixed|null
105
	 */
106
	public function current()
107
	{
108
		$this->initialize();
109
110
		$current = current($this->loadedData);
111
112
		return $current ?: null;
113
	}
114
115
116
	/**
117
	 * @param int|string $key
118
	 * @return mixed|null
119
	 */
120 1
	public function remove($key)
121
	{
122 1
		$this->initialize();
123
124 1
		if (! isset($this->loadedData[$key]) && ! $this->contains($key)) {
125
			return null;
126
		}
127
128 1
		$removed = $this->loadedData[$key];
129 1
		unset($this->loadedData[$key]);
130
131 1
		return $removed;
132
	}
133
134
135
	/**
136
	 * @param mixed $element
137
	 * @return bool|int|string
138
	 */
139
	public function indexOf($element)
140
	{
141
		return array_search($element, $this->toArray(), true);
142
	}
143
144
145
	/**
146
	 * @param int|string $key
147
	 * @return mixed|null
148
	 */
149 2
	public function get($key)
150
	{
151 2
		$this->initialize();
152
153 2
		return $this->loadedData[$key] ?? null;
154
	}
155
156
157
	public function getKeys(): array
158
	{
159
		$this->initialize();
160
161
		return array_keys($this->loadedData);
162
	}
163
164
165
	public function getValues(): array
166
	{
167
		$this->initialize();
168
169
		return array_values($this->loadedData);
170
	}
171
172
173
	/**
174
	 * @param int|string $key
175
	 * @param mixed $value
176
	 */
177 1
	public function set($key, $value): void
178
	{
179 1
		$this->initialize();
180
181 1
		$this->loadedData[$key] = $value;
182 1
	}
183
184
185
	/**
186
	 * @param mixed $element
187
	 */
188
	public function add($element): bool
189
	{
190
		$this->initialize();
191
192
		$this->loadedData[] = $element;
193
194
		return true;
195
	}
196
197
198
	public function isEmpty(): bool
199
	{
200
		return $this->toArray() === [];
201
	}
202
203
204
	public function clear(): void
205
	{
206
		$this->initialize();
207
208
		$this->loadedData = [];
209
	}
210
211
212
	/**
213
	 * {@inheritdoc}
214
	 */
215 1
	public function getIterator(): Iterator
216
	{
217 1
		return new RecursiveArrayIterator($this->toArray());
218
	}
219
220
221
	/**
222
	 * @param mixed $offset
223
	 */
224 2
	public function offsetExists($offset): bool
225
	{
226 2
		return $this->contains($offset);
227
	}
228
229
230
	/**
231
	 * @param mixed $offset
232
	 * @return mixed
233
	 */
234 2
	public function offsetGet($offset)
235
	{
236 2
		return $this->get($offset);
237
	}
238
239
240
	/**
241
	 * @param mixed $offset
242
	 * @param mixed $value
243
	 */
244 1
	public function offsetSet($offset, $value): void
245
	{
246 1
		$this->set($offset, $value);
247 1
	}
248
249
250
	/**
251
	 * @param mixed $offset
252
	 */
253 1
	public function offsetUnset($offset): void
254
	{
255 1
		$this->remove($offset);
256 1
	}
257
258
259
	/**
260
	 * {@inheritdoc}
261
	 */
262 1
	public function count(): int
263
	{
264 1
		return count($this->toArray());
265
	}
266
267
268 4
	public function toArray(): array
269
	{
270 4
		$this->initialize();
271
272 4
		return $this->loadedData;
273
	}
274
275
276 11
	private function initialize(): void
277
	{
278 11
		if ($this->loadedData === null) {
279 11
			$data = call_user_func($this->callable);
280 11
			$this->loadedData = is_array($data) ? $data : [$data];
281
		}
282 11
	}
283
284
285
	/**
286
	 * @param int|string $key
287
	 */
288 2
	private function contains($key): bool
289
	{
290 2
		$this->initialize();
291
292 2
		return isset($this->loadedData[$key]) || array_key_exists($key, $this->loadedData);
293
	}
294
295
}
296