Completed
Push — master ( dab7a1...e40ae1 )
by Matthew
02:03
created

BaseCollection::toJson()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PublishingKit\Utilities\Collections;
6
7
use PublishingKit\Utilities\Contracts\Collectable;
8
use PublishingKit\Utilities\Traits\Macroable;
9
use JsonSerializable;
10
use Serializable;
11
use ArrayIterator;
12
use IteratorIterator;
13
use Traversable;
14
use ArrayAccess;
15
16
abstract class BaseCollection implements Collectable, JsonSerializable, Serializable, ArrayAccess
17
{
18
    use Macroable;
0 ignored issues
show
Bug introduced by
The trait PublishingKit\Utilities\Traits\Macroable requires the property $name which is not provided by PublishingKit\Utilities\Collections\BaseCollection.
Loading history...
19
20
    /**
21
     * @var mixed
22
     */
23
    protected $source;
24
25
    /**
26
     * Constructor
27
     *
28
     * @param mixed $source Items to collect.
29
     * @return void
30
     */
31 267
    public function __construct($source = [])
32
    {
33 267
        if (is_callable($source) || $source instanceof self) {
34 183
            $this->source = $source;
35 213
        } elseif (is_iterable($source)) {
36 207
            $this->source = $source;
37 9
        } elseif (is_null($source)) {
38 3
            $this->source = static::empty();
39
        } else {
40 6
            $this->source = $this->getArrayableItems($source);
41
        }
42 267
    }
43
44
    /**
45
     * Create collection
46
     *
47
     * @param mixed $items Items to collect.
48
     * @return Collectable
49
     */
50 15
    public static function make($items): Collectable
51
    {
52 15
        return new static($items);
53
    }
54
55
    /**
56
     * {@inheritDoc}
57
     */
58 6
    public static function empty()
59
    {
60 6
        return new static([]);
61
    }
62
63 6
    public function __debugInfo()
64
    {
65 6
        return $this->toArray();
66
    }
67
68
    /**
69
     * {@inheritDoc}
70
     */
71 12
    public function toJson()
72
    {
73 12
        return json_encode($this->toArray());
74
    }
75
76
    /**
77
     * Serialize collection to JSON
78
     *
79
     * @return string|false
80
     */
81 6
    public function jsonSerialize()
82
    {
83 6
        return $this->toJson();
84
    }
85
86
    /**
87
     * {@inheritDoc}
88
     */
89 6
    public function serialize()
90
    {
91 6
        return serialize($this->toArray());
92
    }
93
94
    /**
95
     * {@inheritDoc}
96
     */
97 6
    public function unserialize($serialized)
98
    {
99 6
        $this->source = unserialize($serialized);
100 6
    }
101
102
    /**
103
     * {@inheritDoc}
104
     */
105 159
    public function getIterator()
106
    {
107 159
        return $this->makeIterator($this->source);
108
    }
109
110
    /**
111
     * Make an iterator from the given source.
112
     *
113
     * @param  mixed  $source
114
     * @return \Traversable
115
     */
116 159
    protected function makeIterator($source)
117
    {
118 159
        if (is_array($source)) {
119 120
            return new ArrayIterator($source);
120
        }
121 144
        if (is_iterable($source)) {
122 6
            return new IteratorIterator($source);
123
        }
124 138
        return $source();
125
    }
126
127
    /**
128
     * {@inheritDoc}
129
     *
130
     * @return iterable
131
     */
132 138
    public function all(): iterable
133
    {
134 138
        if (is_array($this->source)) {
135 9
            return $this->source;
136
        }
137 129
        return iterator_to_array($this->getIterator());
138
    }
139
140
    /**
141
     * Results array of items from Collection or Arrayable.
142
     *
143
     * @param mixed  $items
144
     *
145
     * @return iterable
146
     */
147 15
    protected function getArrayableItems($items): iterable
148
    {
149 15
        if (is_array($items)) {
150 3
            return $items;
151 12
        } elseif ($items instanceof Collectable) {
152 3
            return $items->toArray();
153 9
        } elseif ($items instanceof JsonSerializable) {
154 3
            return (array) $items->jsonSerialize();
155 6
        } elseif ($items instanceof Traversable) {
156 3
            return iterator_to_array($items);
157
        }
158 3
        return (array) $items;
159
    }
160
161
    /**
162
     * Get the collection of items as a plain array.
163
     *
164
     * @return iterable
165
     */
166 123
    public function toArray(): iterable
167
    {
168
        return $this->map(function ($value) /* @return mixed */ {
169 123
            return $value instanceof Collectable ? $value->toArray() : $value;
170 123
        })->all();
171
    }
172
173
    /**
174
     * {@inheritDoc}
175
     */
176 24
    public function count()
177
    {
178 24
        return iterator_count($this->getIterator());
179
    }
180
181
    /**
182
     * {@inheritDoc}
183
     */
184 3
    public function pipe(callable $callback)
185
    {
186 3
        return $callback($this);
187
    }
188
189
    /**
190
     * {@inheritDoc}
191
     */
192 123
    public function map(callable $callback)
193
    {
194
        return new static(function () use ($callback) {
195 123
            foreach ($this as $key => $value) {
196 123
                yield $key => $callback($value, $key);
197
            }
198 123
        });
199
    }
200
201
    /**
202
     * {@inheritDoc}
203
     */
204 15
    public function filter(callable $callback = null)
205
    {
206 15
        if (is_null($callback)) {
207
            $callback = function ($value): bool {
208 3
                return (bool) $value;
209 3
            };
210
        }
211
        return new static(function () use ($callback) {
212 15
            foreach ($this as $key => $value) {
213 15
                if ($callback($value, $key)) {
214 15
                    yield $key => $value;
215
                }
216
            }
217 15
        });
218
    }
219
220
    /**
221
     * {@inheritDoc}
222
     */
223 6
    public function reject(callable $callback)
224
    {
225
        return $this->filter(function ($item) use ($callback) {
226 6
            return !$callback($item);
227 6
        });
228
    }
229
230
    /**
231
     * {@inheritDoc}
232
     */
233 6
    public function reduce(callable $callback, $initial = 0)
234
    {
235 6
        $result = $initial;
236 6
        foreach ($this as $value) {
237 6
            $result = $callback($result, $value);
238
        }
239 6
        return $result;
240
    }
241
242
    /**
243
     * Reduce operation that returns a collection
244
     *
245
     * @param callable $callback The callback to use.
246
     * @param mixed   $initial  The initial value.
247
     * @return Collection
248
     */
249 3
    public function reduceToCollection(callable $callback, $initial = 0): Collection
250
    {
251 3
        $accumulator = $initial;
252 3
        foreach ($this->source as $item) {
253 3
            $accumulator = $callback($accumulator, $item);
254
        }
255 3
        return new static($accumulator);
256
    }
257
258
    /**
259
     * {@inheritDoc}
260
     */
261 6
    public function pluck($name)
262
    {
263
        return $this->map(function ($item) use ($name) {
264 6
            return $item[$name];
265 6
        });
266
    }
267
268
    /**
269
     * {@inheritDoc}
270
     */
271 6
    public function each(callable $callback)
272
    {
273 6
        foreach ($this->source as $item) {
274 6
            $callback($item);
275
        }
276 6
    }
277
278
    /**
279
     * Does item exist?
280
     *
281
     * @param mixed $offset The offset.
282
     * @return boolean
283
     */
284 6
    public function offsetExists($offset)
285
    {
286 6
        return isset($this->source[$offset]);
287
    }
288
289
    /**
290
     * Get offset
291
     *
292
     * @param mixed $offset The offset.
293
     * @return mixed
294
     */
295 27
    public function offsetGet($offset)
296
    {
297 27
        return isset($this->source[$offset]) ? $this->source[$offset] : null;
298
    }
299
300
    /**
301
     * Set offset
302
     *
303
     * @param mixed $offset The offset.
304
     * @param mixed $value  The value to set.
305
     * @return void
306
     */
307 12
    public function offsetSet($offset, $value): void
308
    {
309 12
        if (is_null($offset)) {
310 6
            $this->source[] = $value;
311 6
            return;
312
        }
313 6
        $this->source[$offset] = $value;
314 6
    }
315
316
    /**
317
     * Unset offset
318
     *
319
     * @param mixed $offset The offset.
320
     * @return void
321
     */
322 6
    public function offsetUnset($offset)
323
    {
324 6
        unset($this->source[$offset]);
325 6
    }
326
}
327