Completed
Push — master ( a25acc...c0f25b )
by Tristan
02:13
created

Collection::hasCount()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 9
rs 9.6666
cc 3
eloc 5
nc 3
nop 2
1
<?php
2
3
namespace Enzyme\Collection;
4
5
use Closure;
6
7
class Collection extends BaseCollection
8
{
9
    /**
10
     * Get a PHP style array from the current collection.
11
     *
12
     * @return array
13
     */
14
    public function toArray()
15
    {
16
        return $this->items;
17
    }
18
19
    /**
20
     * Whether the collection has the specified key, and/or value associated
21
     * with the specified key.
22
     *
23
     * @param string $key
24
     * @param mixed  $value
25
     *
26
     * @return bool
27
     */
28
    public function has($key, $value = null)
29
    {
30
        $key_exists = self::keyExists($key, $this->items);
31
32
        return null !== $value
33
            ? $value === $this->get($key)
34
            : $key_exists;
35
    }
36
37
    /**
38
     * Get the value associated with the specified key.
39
     *
40
     * @param string $key
41
     *
42
     * @throws \Enzyme\Collection\CollectionException If the key does not exist.
43
     *
44
     * @return mixed
45
     */
46
    public function get($key)
47
    {
48
        if (false === self::keyExists($key, $this->items)) {
49
            throw new CollectionException(
50
                "An element with the key [${key}] does not exist."
51
            );
52
        }
53
54
        return $this->items[$key];
55
    }
56
57
    /**
58
     * Get the value associated with the specified key or return a default value
59
     * instead if it does not exist.
60
     *
61
     * @param string $key
62
     * @param mixed  $default
63
     *
64
     * @return mixed
65
     */
66
    public function getOrDefault($key, $default = null)
67
    {
68
        try {
69
            return $this->get($key);
70
        } catch (CollectionException $e) {
71
            return $default;
72
        }
73
    }
74
75
    /**
76
     * Execute the given callback function for each element in this collection.
77
     *
78
     * @param Closure $fn
79
     */
80
    public function each(Closure $fn)
81
    {
82
        foreach ($this->items as $key => $value) {
83
            if (false === $fn($value, $key)) {
84
                break;
85
            }
86
        }
87
    }
88
89
    /**
90
     * Execute the given callback function for each element in this collection
91
     * and save the results to a new collection.
92
     *
93
     * @param Closure $fn
94
     *
95
     * @return \Enzyme\Collection\Collection
96
     */
97 View Code Duplication
    public function map(Closure $fn)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
98
    {
99
        $results = [];
100
        foreach ($this->items as $key => $value) {
101
            $results[] = $fn($value, $key);
102
        }
103
104
        return new static($results);
105
    }
106
107
    /**
108
     * Pluck out all values in this collection which have the specified key.
109
     *
110
     * @param string $pluck_key
111
     * @param bool   $deep      Whether to traverse into sub-arrays.
112
     *
113
     * @return \Enzyme\Collection\Collection
114
     */
115
    public function pluck($pluck_key, $deep = true)
116
    {
117
        return self::pluckKey($this->items, $pluck_key, $deep);
118
    }
119
120
    /**
121
     * Get the number of elements in this collection.
122
     *
123
     * @return int
124
     */
125
    public function count()
126
    {
127
        return count($this->items);
128
    }
129
130
    /**
131
     * Whether this collection is empty.
132
     *
133
     * @return bool
134
     */
135
    public function isEmpty()
136
    {
137
        return $this->count() < 1;
138
    }
139
140
    /**
141
     * Get the value of the first element in this collection.
142
     *
143
     * @throws \Enzyme\Collection\CollectionException If the collection is empty.
144
     *
145
     * @return mixed
146
     */
147
    public function first()
148
    {
149
        if (true === $this->isEmpty()) {
150
            throw new CollectionException(
151
                'Cannot get first item as the collection is empty.'
152
            );
153
        }
154
155
        return reset($this->items);
156
    }
157
158
    /**
159
     * Get the value of the first element in this collection or return the
160
     * default value specified if the collection is empty.
161
     *
162
     * @param mixed $default
163
     *
164
     * @return mixed
165
     */
166
    public function firstOrDefault($default = null)
167
    {
168
        try {
169
            return $this->first();
170
        } catch (CollectionException $e) {
171
            return $default;
172
        }
173
    }
174
175
    /**
176
     * Get the value of the last element in this collection.
177
     *
178
     * @throws \Enzyme\Collection\CollectionException If the collection is empty.
179
     *
180
     * @return mixed
181
     */
182
    public function last()
183
    {
184
        if (true === $this->isEmpty()) {
185
            throw new CollectionException(
186
                'Cannot get last element as collection is empty.'
187
            );
188
        }
189
190
        end($this->items);
191
        $key = key($this->items);
192
        reset($this->items);
193
194
        return $this->items[$key];
195
    }
196
197
    /**
198
     * Get the value of the last element in this collection or return the
199
     * default value specified if the collection is empty.
200
     *
201
     * @param mixed $default
202
     *
203
     * @return mixed
204
     */
205
    public function lastOrDefault($default = null)
206
    {
207
        try {
208
            return $this->first();
209
        } catch (CollectionException $e) {
210
            return $default;
211
        }
212
    }
213
214
    /**
215
     * Get a new collection of only the elements in the current collection
216
     * that have the specified keys.
217
     *
218
     * @param array $keys
219
     *
220
     * @return \Enzyme\Collection\Collection
221
     */
222
    public function only(array $keys)
223
    {
224
        return $this->filter(function ($value, $key) use ($keys) {
225
            return true === self::keyExists($key, array_flip($keys));
226
        });
227
    }
228
229
    /**
230
     * Get a new collection of all the elements in the current collection
231
     * except those that have the specified keys.
232
     *
233
     * @param array $keys
234
     *
235
     * @return \Enzyme\Collection\Collection
236
     */
237
    public function except(array $keys)
238
    {
239
        return $this->filter(function ($value, $key) use ($keys) {
240
            return false === self::keyExists($key, array_flip($keys));
241
        });
242
    }
243
244
    /**
245
     * Return a new collection with the current collection's elements plus the
246
     * given value pushed onto the end of the array.
247
     *
248
     * @param mixed $value
249
     *
250
     * @return \Enzyme\Collection\Collection
251
     */
252
    public function push($value)
253
    {
254
        $items = $this->items;
255
        $items[] = $value;
256
257
        return new static($items);
258
    }
259
260
    /**
261
     * Return a new collection with the current collection's elements plus the
262
     * given key and value pushed onto the end of the array.
263
     *
264
     * @param string $key
265
     * @param mixed  $value
266
     *
267
     * @return \Enzyme\Collection\Collection
268
     */
269
    public function pushWithKey($key, $value)
270
    {
271
        $items = $this->items;
272
        $items[$key] = $value;
273
274
        return new static($items);
275
    }
276
277
    /**
278
     * Return a new collection with the current collection's elements plus the
279
     * given array pushed onto the end of the array.
280
     *
281
     * @param array $data
282
     *
283
     * @return \Enzyme\Collection\Collection
284
     */
285
    public function pushArray(array $data)
286
    {
287
        $items = $this->items;
288
        foreach ($data as $key => $value) {
289
            if (true === is_int($key)) {
290
                $items[] = $value;
291
            } else {
292
                $items[$key] = $value;
293
            }
294
        }
295
296
        return new static($items);
297
    }
298
299
    /**
300
     * Return a new collection with a subset of all the current collection's
301
     * elements that pass the given callback functions truth test.
302
     *
303
     * @param Closure $fn
304
     *
305
     * @return \Enzyme\Collection\Collection
306
     */
307 View Code Duplication
    public function filter(Closure $fn)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
308
    {
309
        $results = [];
310
        foreach ($this->items as $key => $value) {
311
            if (true === $fn($value, $key)) {
312
                $results[$key] = $value;
313
            }
314
        }
315
316
        // Pushing this new array will normalize numeric keys if they exist.
317
        // After filtering, they may not start at zero and sequentially
318
        // go upwards, which is generally not expected.
319
        return (new static())->pushArray($results);
320
    }
321
322
    /**
323
     * Sort the collection using the provided callback function. Same expected
324
     * parameters and the PHP usort function.
325
     *
326
     * @param Closure $fn
327
     *
328
     * @return \Enzyme\Collection\Collection
329
     */
330
    public function sort(Closure $fn)
331
    {
332
        $sorted = $this->items;
333
        $result = usort($sorted, $fn);
334
335
        if (false === $result) {
336
            throw new CollectionException(
337
                'The collection could be not sorted.'
338
            );
339
        }
340
341
        return new static($sorted);
342
    }
343
344
    /**
345
     * Whether this collection has the specified number of elements within the
346
     * given range or equal too or above the minimum value specified.
347
     *
348
     * @param int $min
349
     * @param int $max Default is null.
350
     *
351
     * @return bool
352
     */
353
    public function hasCount($min, $max = null)
354
    {
355
        if (null === $max) {
356
            return $this->count() >= $min;
357
        }
358
359
        return $this->count() >= $min
360
            && $this->count() <= $max;
361
    }
362
363
    /**
364
     * Checks whether the specified key exists in the given collection.
365
     *
366
     * @param string $key
367
     * @param array  $collection
368
     *
369
     * @return bool
370
     */
371
    protected static function keyExists($key, array $collection)
372
    {
373
        return true === isset($collection[$key]);
374
    }
375
376
    /**
377
     * Pluck all the values that have the specified key from the given
378
     * collection.
379
     *
380
     * @param array  $collection
381
     * @param string $pluck_key
382
     * @param bool   $deep       Whether to traverse into sub-arrays.
383
     *
384
     * @return \Enzyme\Collection\Collection
385
     */
386
    protected static function pluckKey(array $collection, $pluck_key, $deep)
387
    {
388
        $results = [];
389
        foreach ($collection as $key => $value) {
390
            if (true === $deep && true === is_array($value)) {
391
                $deeper_results = self::pluckKey(
392
                    $value,
393
                    $pluck_key,
394
                    $deep
395
                )->toArray();
396
397
                foreach ($deeper_results as $deep_value) {
398
                    $results[] = $deep_value;
399
                }
400
401
                continue;
402
            }
403
404
            if ($key === $pluck_key) {
405
                $results[] = $value;
406
            }
407
        }
408
409
        return new static($results);
410
    }
411
}
412