Completed
Push — master ( 84bd76...5b8795 )
by Matthew
02:46
created

LazyCollection   A

Complexity

Total Complexity 37

Size/Duplication

Total Lines 232
Duplicated Lines 0 %

Test Coverage

Coverage 97.37%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 59
dl 0
loc 232
ccs 74
cts 76
cp 0.9737
rs 9.44
c 1
b 0
f 0
wmc 37

20 Methods

Rating   Name   Duplication   Size   Complexity  
A all() 0 6 2
A serialize() 0 3 1
A each() 0 4 2
A empty() 0 3 1
A makeIterator() 0 9 3
A toJson() 0 3 1
A pluck() 0 4 1
A reject() 0 4 1
A reduce() 0 7 2
A count() 0 3 1
A make() 0 3 1
A unserialize() 0 3 1
A toArray() 0 5 2
A getIterator() 0 3 1
A jsonSerialize() 0 3 1
A __construct() 0 8 4
A map() 0 5 2
A filter() 0 11 4
A getArrayableItems() 0 12 5
A __debugInfo() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PublishingKit\Utilities\Collections;
6
7
use Countable;
8
use IteratorAggregate;
9
use ArrayIterator;
10
use JsonSerializable;
11
use Generator;
12
use Traversable;
13
use Serializable;
14
use PublishingKit\Utilities\Contracts\Collectable;
15
use PublishingKit\Utilities\Traits\Macroable;
16
17
class LazyCollection implements Collectable, Countable, IteratorAggregate, JsonSerializable, Serializable
18
{
19
    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\LazyCollection.
Loading history...
20
21
    /**
22
     * @var callable|static
23
     */
24
    private $source;
25
26
    /**
27
     * Create a new lazy collection instance.
28
     *
29
     * @param  mixed  $source
30
     * @return void
31
     */
32 75
    public function __construct($source = null)
33
    {
34 75
        if (is_callable($source) || $source instanceof self) {
35 75
            $this->source = $source;
36 24
        } elseif (is_null($source)) {
37 3
            $this->source = static::empty();
38
        } else {
39 24
            $this->source = $this->getArrayableItems($source);
40
        }
41 75
    }
42
43
    /**
44
     * {@inheritDoc}
45
     *
46
     * @return self
47
     */
48 3
    public static function make(callable $callback): self
49
    {
50 3
        return new static($callback);
51
    }
52
53
    /**
54
     * Create a new instance with no items.
55
     *
56
     * @return static
57
     */
58 3
    public static function empty()
59
    {
60 3
        return new static([]);
61
    }
62
63
    /**
64
     * Results array of items from Collection or Arrayable.
65
     *
66
     * @param  mixed  $items
67
     * @return array
68
     */
69 24
    protected function getArrayableItems($items)
70
    {
71 24
        if (is_array($items)) {
72 15
            return $items;
73 9
        } elseif ($items instanceof Collectable) {
74 3
            return $items->toArray();
75 6
        } elseif ($items instanceof JsonSerializable) {
76 3
            return (array) $items->jsonSerialize();
77 3
        } elseif ($items instanceof Traversable) {
78 3
            return iterator_to_array($items);
79
        }
80
        return (array) $items;
81
    }
82
83
    /**
84
     * {@inheritDoc}
85
     */
86 3
    public function toJson()
87
    {
88 3
        return json_encode($this->toArray());
89
    }
90
91
    /**
92
     * Get the collection of items as a plain array.
93
     *
94
     * @return array
95
     */
96 27
    public function toArray()
97
    {
98
        return $this->map(function ($value) {
99 27
            return $value instanceof Collectable ? $value->toArray() : $value;
100 27
        })->all();
101
    }
102
103
    /**
104
     * @return array
105
     *
106
     * @psalm-return array<int|mixed, mixed>
107
     */
108 36
    public function all(): array
109
    {
110 36
        if (is_array($this->source)) {
111 3
            return $this->source;
112
        }
113 33
        return iterator_to_array($this->getIterator());
114
    }
115
116
    /**
117
     * {@inheritDoc}
118
     */
119 27
    public function map(callable $callback)
120
    {
121
        return new static(function () use ($callback) {
122 27
            foreach ($this as $key => $value) {
123 27
                yield $key => $callback($value, $key);
124
            }
125 27
        });
126
    }
127
128
    /**
129
     * {@inheritDoc}
130
     */
131 9
    public function filter(callable $callback = null)
132
    {
133 9
        if (is_null($callback)) {
134
            $callback = function ($value): bool {
135 3
                return (bool) $value;
136 3
            };
137
        }
138
        return new static(function () use ($callback) {
139 9
            foreach ($this as $key => $value) {
140 9
                if ($callback($value, $key)) {
141 9
                    yield $key => $value;
142
                }
143
            }
144 9
        });
145
    }
146
147
    /**
148
     * {@inheritDoc}
149
     */
150 3
    public function reject(callable $callback)
151
    {
152
        return $this->filter(function ($item) use ($callback) {
153 3
            return !$callback($item);
154 3
        });
155
    }
156
157
    /**
158
     * {@inheritDoc}
159
     */
160 3
    public function reduce(callable $callback, $initial = 0)
161
    {
162 3
        $result = $initial;
163 3
        foreach ($this as $value) {
164 3
            $result = $callback($result, $value);
165
        }
166 3
        return $result;
167
    }
168
169
    /**
170
     * {@inheritDoc}
171
     */
172 3
    public function pluck($name)
173
    {
174
        return $this->map(function ($item) use ($name) {
175 3
            return $item[$name];
176 3
        });
177
    }
178
179
    /**
180
     * {@inheritDoc}
181
     */
182 3
    public function each(callable $callback)
183
    {
184 3
        foreach ($this->source as $item) {
185 3
            $callback($item);
186
        }
187 3
    }
188
189
    /**
190
     * {@inheritDoc}
191
     */
192 3
    public function count()
193
    {
194 3
        return iterator_count($this->getIterator());
195
    }
196
197
    /**
198
     * {@inheritDoc}
199
     */
200 42
    public function getIterator()
201
    {
202 42
        return $this->makeIterator($this->source);
203
    }
204
205
    /**
206
     * {@inheritDoc}
207
     */
208 3
    public function jsonSerialize()
209
    {
210 3
        return json_encode($this->toArray());
211
    }
212
213
    /**
214
     * Make an iterator from the given source.
215
     *
216
     * @param  mixed  $source
217
     * @return \Traversable
218
     */
219 42
    protected function makeIterator($source)
220
    {
221 42
        if ($source instanceof IteratorAggregate) {
222
            return $source->getIterator();
223
        }
224 42
        if (is_array($source)) {
225 6
            return new ArrayIterator($source);
226
        }
227 42
        return $source();
228
    }
229
230
    /**
231
     * {@inheritDoc}
232
     */
233 3
    public function serialize()
234
    {
235 3
        return serialize($this->toArray());
236
    }
237
238
    /**
239
     * {@inheritDoc}
240
     */
241 3
    public function unserialize($serialized)
242
    {
243 3
        $this->source = unserialize($serialized);
244 3
    }
245
246 3
    public function __debugInfo()
247
    {
248 3
        return $this->toArray();
249
    }
250
}
251