PluginProbe
Elementor Website Builder – more than just a page builder / 3.14.0-beta4
Elementor Website Builder – more than just a page builder v3.14.0-beta4
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / core / utils / collection.php

collection.php in Elementor Website Builder – more than just a page builder 3.14.0-beta4, at core/utils/collection.php

506 lines 8.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Inspired by Laravel Collection.
4 * @link https://github.com/illuminate/collections
5 */
6 namespace Elementor\Core\Utils;
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit; // Exit if accessed directly.
10 }
11
12 class Collection implements \ArrayAccess, \Countable, \IteratorAggregate {
13 /**
14 * The items contained in the collection.
15 *
16 * @var array
17 */
18 protected $items;
19
20 /**
21 * Collection constructor.
22 *
23 * @param array $items
24 */
25 public function __construct( array $items ) {
26 $this->items = $items;
27 }
28
29 /**
30 * @param array $items
31 *
32 * @return static
33 */
34 public static function make( array $items ) {
35 return new static( $items );
36 }
37
38 /**
39 * @param callable|null $callback
40 *
41 * @return $this
42 */
43 public function filter( callable $callback = null ) {
44 if ( ! $callback ) {
45 return new static( array_filter( $this->items ) );
46 }
47
48 return new static( array_filter( $this->items, $callback, ARRAY_FILTER_USE_BOTH ) );
49 }
50
51 /**
52 * @param $items
53 *
54 * @return $this
55 */
56 public function merge( $items ) {
57 if ( $items instanceof Collection ) {
58 $items = $items->all();
59 }
60
61 return new static( array_merge( $this->items, $items ) );
62 }
63
64 /**
65 * Union the collection with the given items.
66 *
67 * @param array $items
68 *
69 * @return $this
70 */
71 public function union( array $items ) {
72 return new static( $this->all() + $items );
73 }
74
75 /**
76 * Merge array recursively
77 *
78 * @param $items
79 *
80 * @return $this
81 */
82 public function merge_recursive( $items ) {
83 if ( $items instanceof Collection ) {
84 $items = $items->all();
85 }
86
87 return new static( array_merge_recursive( $this->items, $items ) );
88 }
89
90 /**
91 * Replace array recursively
92 *
93 * @param $items
94 *
95 * @return $this
96 */
97 public function replace_recursive( $items ) {
98 if ( $items instanceof Collection ) {
99 $items = $items->all();
100 }
101
102 return new static( array_replace_recursive( $this->items, $items ) );
103 }
104
105 /**
106 * Implode the items
107 *
108 * @param $glue
109 *
110 * @return string
111 */
112 public function implode( $glue ) {
113 return implode( $glue, $this->items );
114 }
115
116 /**
117 * Run a map over each of the items.
118 *
119 * @param callable $callback
120 * @return $this
121 */
122 public function map( callable $callback ) {
123 $keys = array_keys( $this->items );
124
125 $items = array_map( $callback, $this->items, $keys );
126
127 return new static( array_combine( $keys, $items ) );
128 }
129
130 /**
131 * Run a callback over each of the items.
132 *
133 * @param callable $callback
134 * @return void
135 */
136 public function each( callable $callback ) {
137 foreach ( $this->items as $key => $value ) {
138 if ( false === $callback( $value, $key ) ) {
139 break;
140 }
141 }
142
143 return $this;
144 }
145
146 /**
147 * @param callable $callback
148 * @param null $initial
149 *
150 * @return mixed|null
151 */
152 public function reduce( callable $callback, $initial = null ) {
153 $result = $initial;
154
155 foreach ( $this->all() as $key => $value ) {
156 $result = $callback( $result, $value, $key );
157 }
158
159 return $result;
160 }
161
162 /**
163 * @param callable $callback
164 *
165 * @return $this
166 */
167 public function map_with_keys( callable $callback ) {
168 $result = [];
169
170 foreach ( $this->items as $key => $value ) {
171 $assoc = $callback( $value, $key );
172
173 foreach ( $assoc as $map_key => $map_value ) {
174 $result[ $map_key ] = $map_value;
175 }
176 }
177
178 return new static( $result );
179 }
180
181 /**
182 * Get all items except for those with the specified keys.
183 *
184 * @param array $keys
185 *
186 * @return $this
187 */
188 public function except( array $keys ) {
189 return $this->filter( function ( $value, $key ) use ( $keys ) {
190 return ! in_array( $key, $keys, true );
191 } );
192 }
193
194 /**
195 * Get the items with the specified keys.
196 *
197 * @param array $keys
198 *
199 * @return $this
200 */
201 public function only( array $keys ) {
202 return $this->filter( function ( $value, $key ) use ( $keys ) {
203 return in_array( $key, $keys, true );
204 } );
205 }
206
207 /**
208 * Run over the collection to get specific prop from the collection item.
209 *
210 * @param $key
211 *
212 * @return $this
213 */
214 public function pluck( $key ) {
215 $result = [];
216
217 foreach ( $this->items as $item ) {
218 $result[] = $this->get_item_value( $item, $key );
219 }
220
221 return new static( $result );
222 }
223
224 /**
225 * Group the collection items by specific key in each collection item.
226 *
227 * @param $group_by
228 *
229 * @return $this
230 */
231 public function group_by( $group_by ) {
232 $result = [];
233
234 foreach ( $this->items as $item ) {
235 $group_key = $this->get_item_value( $item, $group_by, 0 );
236
237 $result[ $group_key ][] = $item;
238 }
239
240 return new static( $result );
241 }
242
243 /**
244 * Sort keys
245 *
246 * @param false $descending
247 *
248 * @return $this
249 */
250 public function sort_keys( $descending = false ) {
251 $items = $this->items;
252
253 if ( $descending ) {
254 krsort( $items );
255 } else {
256 ksort( $items );
257 }
258
259 return new static( $items );
260 }
261
262 /**
263 * Get specific item from the collection.
264 *
265 * @param $key
266 * @param null $default
267 *
268 * @return mixed|null
269 */
270 public function get( $key, $default = null ) {
271 if ( ! array_key_exists( $key, $this->items ) ) {
272 return $default;
273 }
274
275 return $this->items[ $key ];
276 }
277
278 /**
279 * Get the first item.
280 *
281 * @param null $default
282 *
283 * @return mixed|null
284 */
285 public function first( $default = null ) {
286 if ( $this->is_empty() ) {
287 return $default;
288 }
289
290 foreach ( $this->items as $item ) {
291 return $item;
292 }
293 }
294
295 /**
296 * Find an element from the items.
297 *
298 * @param callable $callback
299 * @param null $default
300 *
301 * @return mixed|null
302 */
303 public function find( callable $callback, $default = null ) {
304 foreach ( $this->all() as $key => $item ) {
305 if ( $callback( $item, $key ) ) {
306 return $item;
307 }
308 }
309
310 return $default;
311 }
312
313 /**
314 * Make sure all the values inside the array are uniques.
315 *
316 * @param null|string|string[] $keys
317 *
318 * @return $this
319 */
320 public function unique( $keys = null ) {
321 if ( ! $keys ) {
322 return new static(
323 array_unique( $this->items )
324 );
325 }
326
327 if ( ! is_array( $keys ) ) {
328 $keys = [ $keys ];
329 }
330
331 $exists = [];
332
333 return $this->filter( function ( $item ) use ( $keys, &$exists ) {
334 $value = null;
335
336 foreach ( $keys as $key ) {
337 $current_value = $this->get_item_value( $item, $key );
338
339 $value .= "{$key}:{$current_value};";
340 }
341
342 // If no value for the specific key return the item.
343 if ( null === $value ) {
344 return true;
345 }
346
347 // If value is not exists, add to the exists array and return the item.
348 if ( ! in_array( $value, $exists, true ) ) {
349 $exists[] = $value;
350
351 return true;
352 }
353
354 return false;
355 } );
356 }
357
358 /**
359 * @return array
360 */
361 public function keys() {
362 return array_keys( $this->items );
363 }
364
365 /**
366 * @return bool
367 */
368 public function is_empty() {
369 return empty( $this->items );
370 }
371
372 /**
373 * @return array
374 */
375 public function all() {
376 return $this->items;
377 }
378
379 /**
380 * @return array
381 */
382 public function values() {
383 return array_values( $this->all() );
384 }
385
386 /**
387 * Support only one level depth.
388 *
389 * @return $this
390 */
391 public function flatten() {
392 $result = [];
393
394 foreach ( $this->all() as $item ) {
395 $item = $item instanceof Collection ? $item->all() : $item;
396
397 if ( ! is_array( $item ) ) {
398 $result[] = $item;
399 } else {
400 $values = array_values( $item );
401
402 foreach ( $values as $value ) {
403 $result[] = $value;
404 }
405 }
406 }
407
408 return new static( $result );
409 }
410
411 /**
412 * @param ...$values
413 *
414 * @return $this
415 */
416 public function push( ...$values ) {
417 foreach ( $values as $value ) {
418 $this->items[] = $value;
419 }
420
421 return $this;
422 }
423
424 public function prepend( ...$values ) {
425 $this->items = array_merge( $values, $this->items );
426
427 return $this;
428 }
429
430 /**
431 * @param mixed $offset
432 *
433 * @return bool
434 */
435 #[\ReturnTypeWillChange]
436 public function offsetExists( $offset ) {
437 return isset( $this->items[ $offset ] );
438 }
439
440 /**
441 * @param mixed $offset
442 *
443 * @return mixed
444 */
445 #[\ReturnTypeWillChange]
446 public function offsetGet( $offset ) {
447 return $this->items[ $offset ];
448 }
449
450 /**
451 * @param mixed $offset
452 * @param mixed $value
453 */
454 #[\ReturnTypeWillChange]
455 public function offsetSet( $offset, $value ) {
456 if ( is_null( $offset ) ) {
457 $this->items[] = $value;
458 } else {
459 $this->items[ $offset ] = $value;
460 }
461 }
462
463 /**
464 * @param mixed $offset
465 */
466 #[\ReturnTypeWillChange]
467 public function offsetUnset( $offset ) {
468 unset( $this->items[ $offset ] );
469 }
470
471 /**
472 * @return \ArrayIterator|\Traversable
473 */
474 #[\ReturnTypeWillChange]
475 public function getIterator() {
476 return new \ArrayIterator( $this->items );
477 }
478
479 /**
480 * @return int|void
481 */
482 #[\ReturnTypeWillChange]
483 public function count() {
484 return count( $this->items );
485 }
486
487 /**
488 * @param $item
489 * @param $key
490 * @param null $default
491 *
492 * @return mixed|null
493 */
494 private function get_item_value( $item, $key, $default = null ) {
495 $value = $default;
496
497 if ( is_object( $item ) && isset( $item->{$key} ) ) {
498 $value = $item->{$key};
499 } elseif ( is_array( $item ) && isset( $item[ $key ] ) ) {
500 $value = $item[ $key ];
501 }
502
503 return $value;
504 }
505 }
506