1
|
|
|
<?php |
|
|
|
|
2
|
|
|
|
3
|
|
|
use Illuminate\Support\Collection; |
4
|
|
|
use Illuminate\Support\Debug\Dumper; |
5
|
|
|
|
6
|
|
|
if (! Collection::hasMacro('dd')) { |
7
|
|
|
/* |
8
|
|
|
* Dump the contents of the collection and terminate the script. |
9
|
|
|
*/ |
10
|
|
|
Collection::macro('dd', function () { |
11
|
|
|
dd($this); |
12
|
|
|
}); |
13
|
|
|
} |
14
|
|
|
|
15
|
|
|
if (! Collection::hasMacro('dump')) { |
16
|
|
|
/* |
17
|
|
|
* Dump the arguments given followed by the collection. |
18
|
|
|
*/ |
19
|
|
|
Collection::macro('dump', function () { |
20
|
|
|
Collection::make(func_get_args()) |
21
|
|
|
->push($this) |
|
|
|
|
22
|
|
|
->each(function ($item) { |
23
|
|
|
(new Dumper)->dump($item); |
24
|
|
|
}); |
25
|
|
|
|
26
|
|
|
return $this; |
27
|
|
|
}); |
28
|
|
|
} |
29
|
|
|
|
30
|
|
View Code Duplication |
if (! Collection::hasMacro('ifEmpty')) { |
|
|
|
|
31
|
|
|
/* |
32
|
|
|
* Execute a callable if the collection is empty, then return the collection. |
33
|
|
|
* |
34
|
|
|
* @param callable $callback |
35
|
|
|
* |
36
|
|
|
* @return \Illuminate\Support\Collection |
37
|
|
|
*/ |
38
|
|
|
Collection::macro('ifEmpty', function (callable $callback): Collection { |
39
|
|
|
if ($this->isEmpty()) { |
40
|
|
|
$callback($this); |
|
|
|
|
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
return $this; |
44
|
|
|
}); |
45
|
|
|
} |
46
|
|
|
|
47
|
|
View Code Duplication |
if (! Collection::hasMacro('ifAny')) { |
|
|
|
|
48
|
|
|
/* |
49
|
|
|
* Execute a callable if the collection isn't empty, then return the collection. |
50
|
|
|
* |
51
|
|
|
* @param callable callback |
52
|
|
|
|
53
|
|
|
* @return \Illuminate\Support\Collection |
54
|
|
|
*/ |
55
|
|
|
Collection::macro('ifAny', function (callable $callback): Collection { |
56
|
|
|
if (! $this->isEmpty()) { |
57
|
|
|
$callback($this); |
|
|
|
|
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
return $this; |
61
|
|
|
}); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
View Code Duplication |
if (! Collection::hasMacro('range')) { |
|
|
|
|
65
|
|
|
/* |
66
|
|
|
* Create a new collection instance with a range of numbers. `range` |
67
|
|
|
* accepts the same parameters as PHP's standard `range` function. |
68
|
|
|
* |
69
|
|
|
* @see range |
70
|
|
|
* |
71
|
|
|
* @param mixed $start |
72
|
|
|
* @param mixed $end |
73
|
|
|
* @param int|float $step |
74
|
|
|
* |
75
|
|
|
* @return \Illuminate\Support\Collection |
76
|
|
|
*/ |
77
|
|
|
Collection::macro('range', function ($start, $end, $step = 1): Collection { |
78
|
|
|
return new Collection(range($start, $end, $step)); |
79
|
|
|
}); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
View Code Duplication |
if (! Collection::hasMacro('withSize')) { |
|
|
|
|
83
|
|
|
/* |
84
|
|
|
* Create a new collection with the specified amount of items |
85
|
|
|
* |
86
|
|
|
* @param int $size |
87
|
|
|
* |
88
|
|
|
* @return \Illuminate\Support\Collection |
89
|
|
|
*/ |
90
|
|
|
Collection::macro('withSize', function (int $size): Collection { |
91
|
|
|
if ($size < 1) { |
92
|
|
|
return new Collection(); |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
return new Collection(range(1, $size)); |
96
|
|
|
}); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
if (! Collection::hasMacro('none')) { |
100
|
|
|
/* |
101
|
|
|
* Check whether a collection doesn't contain any occurrences of a given |
102
|
|
|
* item, key-value pair, or passing truth test. `none` accepts the same |
103
|
|
|
* parameters as the `contains` collection method. |
104
|
|
|
* |
105
|
|
|
* @see \Illuminate\Support\Collection::contains |
106
|
|
|
* |
107
|
|
|
* @param mixed $key |
108
|
|
|
* @param mixed $value |
109
|
|
|
* |
110
|
|
|
* @return bool |
111
|
|
|
*/ |
112
|
|
|
Collection::macro('none', function ($key, $value = null): bool { |
113
|
|
|
if (func_num_args() === 2) { |
114
|
|
|
return ! $this->contains($key, $value); |
|
|
|
|
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
return ! $this->contains($key); |
118
|
|
|
}); |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
if (! Collection::hasMacro('validate')) { |
122
|
|
|
/* |
123
|
|
|
* Returns true if $callback returns true for every item. If $callback |
124
|
|
|
* is a string or an array, regard it as a validation rule. |
125
|
|
|
* |
126
|
|
|
* @param string|callable $callback |
127
|
|
|
* |
128
|
|
|
* @return bool |
129
|
|
|
*/ |
130
|
|
|
Collection::macro('validate', function ($callback): bool { |
131
|
|
|
if (is_string($callback) || is_array($callback)) { |
132
|
|
|
$validationRule = $callback; |
133
|
|
|
|
134
|
|
|
$callback = function ($item) use ($validationRule) { |
135
|
|
|
if (! is_array($item)) { |
136
|
|
|
$item = ['default' => $item]; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
if (! is_array($validationRule)) { |
140
|
|
|
$validationRule = ['default' => $validationRule]; |
|
|
|
|
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
return app('validator')->make($item, $validationRule)->passes(); |
144
|
|
|
}; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
foreach ($this->items as $item) { |
|
|
|
|
148
|
|
|
if (! $callback($item)) { |
149
|
|
|
return false; |
150
|
|
|
} |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
return true; |
154
|
|
|
}); |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
if (! Collection::hasMacro('groupByModel')) { |
158
|
|
|
/* |
159
|
|
|
* Group a collection by an Eloquent model. |
160
|
|
|
* |
161
|
|
|
* @param string|callable $callback |
162
|
|
|
* @param string $keyName |
163
|
|
|
* |
164
|
|
|
* @return \Illuminate\Support\Collection |
165
|
|
|
*/ |
166
|
|
|
Collection::macro('groupByModel', function ($callback, $keyName = 'model') { |
167
|
|
|
$callback = is_callable($callback) ? $callback : function ($item) use ($callback) { |
168
|
|
|
return $item[$callback]; |
169
|
|
|
}; |
170
|
|
|
|
171
|
|
|
return Collection::make($this->items)->map(function ($item) use ($callback) { |
|
|
|
|
172
|
|
|
return ['key' => $callback($item), 'item' => $item]; |
173
|
|
|
})->groupBy(function (array $keyedItem) { |
174
|
|
|
return $keyedItem['key']->getKey(); |
175
|
|
|
})->map(function (Collection $group) use ($keyName) { |
176
|
|
|
return $group->reduce(function (array $result, array $group) use ($keyName) { |
177
|
|
|
$result[$keyName] = $group['key']; |
178
|
|
|
$result['items'][] = $group['item']; |
179
|
|
|
|
180
|
|
|
return $result; |
181
|
|
|
}, []); |
182
|
|
|
})->map(function (array $group) { |
183
|
|
|
$group['items'] = Collection::make($group['items']); |
184
|
|
|
|
185
|
|
|
return $group; |
186
|
|
|
})->values(); |
187
|
|
|
}); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
if (! Collection::hasMacro('fromPairs')) { |
191
|
|
|
/* |
192
|
|
|
* Transform a collection into an associative array form collection item. |
193
|
|
|
* |
194
|
|
|
* @return \Illuminate\Support\Collection |
195
|
|
|
*/ |
196
|
|
|
Collection::macro('fromPairs', function () { |
197
|
|
|
return $this->reduce(function ($assoc, array $keyValuePair): Collection { |
|
|
|
|
198
|
|
|
list($key, $value) = $keyValuePair; |
199
|
|
|
$assoc[$key] = $value; |
200
|
|
|
|
201
|
|
|
return $assoc; |
202
|
|
|
}, new static); |
203
|
|
|
}); |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
if (! Collection::hasMacro('toPairs')) { |
207
|
|
|
/* |
208
|
|
|
* Transform a collection into an an array with pairs. |
209
|
|
|
* |
210
|
|
|
* @return \Illuminate\Support\Collection |
211
|
|
|
*/ |
212
|
|
|
Collection::macro('toPairs', function () { |
213
|
|
|
return $this->keys()->map(function ($key) { |
|
|
|
|
214
|
|
|
return [$key, $this->items[$key]]; |
|
|
|
|
215
|
|
|
}); |
216
|
|
|
}); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
if (! Collection::hasMacro('transpose')) { |
220
|
|
|
/* |
221
|
|
|
* Transpose an array. |
222
|
|
|
* |
223
|
|
|
* @return \Illuminate\Support\Collection |
224
|
|
|
* |
225
|
|
|
* @throws \LengthException |
226
|
|
|
*/ |
227
|
|
|
Collection::macro('transpose', function (): Collection { |
228
|
|
|
$values = $this->values(); |
|
|
|
|
229
|
|
|
|
230
|
|
|
$expectedLength = count($this->first()); |
231
|
|
|
$diffLength = count(array_intersect_key(...$values)); |
232
|
|
|
|
233
|
|
|
if ($expectedLength !== $diffLength) { |
234
|
|
|
throw new \LengthException("Element's length must be equal."); |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
$items = array_map(function (...$items) { |
238
|
|
|
return new static($items); |
239
|
|
|
}, ...$values); |
240
|
|
|
|
241
|
|
|
return new static($items); |
242
|
|
|
}); |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
if (! Collection::hasMacro('collect')) { |
246
|
|
|
/* |
247
|
|
|
* Get a new collection from the collection by key. |
248
|
|
|
* |
249
|
|
|
* @param mixed $key |
250
|
|
|
* @param mixed $default |
251
|
|
|
* |
252
|
|
|
* @return static |
253
|
|
|
*/ |
254
|
|
|
Collection::macro('collect', function ($key, $default = null) { |
255
|
|
|
return new static($this->get($key, $default)); |
|
|
|
|
256
|
|
|
}); |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
if (! Collection::hasMacro('after')) { |
260
|
|
|
/* |
261
|
|
|
* Get the next item from the collection. |
262
|
|
|
* |
263
|
|
|
* @param mixed $currentItem |
264
|
|
|
* @param mixed $fallback |
265
|
|
|
* |
266
|
|
|
* @return mixed |
267
|
|
|
*/ |
268
|
|
|
Collection::macro('after', function ($currentItem, $fallback = null) { |
269
|
|
|
$currentKey = $this->search($currentItem, true); |
|
|
|
|
270
|
|
|
|
271
|
|
|
if ($currentKey === false) { |
272
|
|
|
return $fallback; |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
$currentOffset = $this->keys()->search($currentKey, true); |
276
|
|
|
|
277
|
|
|
$next = $this->slice($currentOffset, 2); |
278
|
|
|
|
279
|
|
|
if ($next->count() < 2) { |
280
|
|
|
return $fallback; |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
return $next->last(); |
284
|
|
|
}); |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
if (! Collection::hasMacro('before')) { |
288
|
|
|
/* |
289
|
|
|
* Get the previous item from the collection. |
290
|
|
|
* |
291
|
|
|
* @param mixed $currentItem |
292
|
|
|
* @param mixed $fallback |
293
|
|
|
* |
294
|
|
|
* @return mixed |
295
|
|
|
*/ |
296
|
|
|
Collection::macro('before', function ($currentItem, $fallback = null) { |
297
|
|
|
return $this->reverse()->after($currentItem, $fallback); |
|
|
|
|
298
|
|
|
}); |
299
|
|
|
} |
300
|
|
|
|
301
|
|
|
if (!Collection::hasMacro('exists')) { |
302
|
|
|
/* |
303
|
|
|
* Check if value exists in collection. |
304
|
|
|
* |
305
|
|
|
* @param string $item |
306
|
|
|
* @param bool $strict |
307
|
|
|
* |
308
|
|
|
* @return string|bool |
309
|
|
|
*/ |
310
|
|
|
Collection::macro('exists', function ($item, $strict = false) { |
311
|
|
|
function inArrayRecursive($needle, $haystack, $strict = false, $path = []) |
312
|
|
|
{ |
313
|
|
|
foreach ($haystack as $key => $value) { |
314
|
|
|
if ($strict ? $value === $needle : $value == $needle) { |
315
|
|
|
return implode('.', $path); |
316
|
|
|
} else { |
317
|
|
|
if (is_array($value)) { |
318
|
|
|
$path[] = $key; |
319
|
|
|
return inArrayRecursive($needle, $value, $strict, $path); |
320
|
|
|
} |
321
|
|
|
} |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
return false; |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
return inArrayRecursive($item, $this->items, $strict, []); |
|
|
|
|
328
|
|
|
}); |
329
|
|
|
} |
330
|
|
|
|
331
|
|
|
if (! Collection::hasMacro('forgetAll')) { |
332
|
|
|
|
333
|
|
|
/* |
334
|
|
|
* The forgetAll method removes an item from the collection by its key(s). |
335
|
|
|
* |
336
|
|
|
* @param mixed $keys |
337
|
|
|
* |
338
|
|
|
* @return void |
339
|
|
|
*/ |
340
|
|
|
Collection::macro('forgetAll', function ($keys) { |
341
|
|
|
Arr::forget($this->items, $keys); |
|
|
|
|
342
|
|
|
}); |
343
|
|
|
} |
344
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.