Completed
Push — master ( 53b748...dab7a1 )
by Matthew
03:13
created

BaseCollection::each()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

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