PluginProbe
Elementor Website Builder – more than just a page builder / 3.21.3
Elementor Website Builder – more than just a page builder v3.21.3
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.21.3, at core/utils/collection.php

527 lines 9.2 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 $this
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 * @param callable|string|int $value
315 *
316 * @return bool
317 */
318 public function contains( $value ) {
319 $callback = $value instanceof \Closure
320 ? $value
321 : function ( $item ) use ( $value ) {
322 return $item === $value;
323 };
324
325 foreach ( $this->all() as $key => $item ) {
326 if ( $callback( $item, $key ) ) {
327 return true;
328 }
329 }
330
331 return false;
332 }
333
334 /**
335 * Make sure all the values inside the array are uniques.
336 *
337 * @param null|string|string[] $keys
338 *
339 * @return $this
340 */
341 public function unique( $keys = null ) {
342 if ( ! $keys ) {
343 return new static(
344 array_unique( $this->items )
345 );
346 }
347
348 if ( ! is_array( $keys ) ) {
349 $keys = [ $keys ];
350 }
351
352 $exists = [];
353
354 return $this->filter( function ( $item ) use ( $keys, &$exists ) {
355 $value = null;
356
357 foreach ( $keys as $key ) {
358 $current_value = $this->get_item_value( $item, $key );
359
360 $value .= "{$key}:{$current_value};";
361 }
362
363 // If no value for the specific key return the item.
364 if ( null === $value ) {
365 return true;
366 }
367
368 // If value is not exists, add to the exists array and return the item.
369 if ( ! in_array( $value, $exists, true ) ) {
370 $exists[] = $value;
371
372 return true;
373 }
374
375 return false;
376 } );
377 }
378
379 /**
380 * @return array
381 */
382 public function keys() {
383 return array_keys( $this->items );
384 }
385
386 /**
387 * @return bool
388 */
389 public function is_empty() {
390 return empty( $this->items );
391 }
392
393 /**
394 * @return array
395 */
396 public function all() {
397 return $this->items;
398 }
399
400 /**
401 * @return array
402 */
403 public function values() {
404 return array_values( $this->all() );
405 }
406
407 /**
408 * Support only one level depth.
409 *
410 * @return $this
411 */
412 public function flatten() {
413 $result = [];
414
415 foreach ( $this->all() as $item ) {
416 $item = $item instanceof Collection ? $item->all() : $item;
417
418 if ( ! is_array( $item ) ) {
419 $result[] = $item;
420 } else {
421 $values = array_values( $item );
422
423 foreach ( $values as $value ) {
424 $result[] = $value;
425 }
426 }
427 }
428
429 return new static( $result );
430 }
431
432 /**
433 * @param ...$values
434 *
435 * @return $this
436 */
437 public function push( ...$values ) {
438 foreach ( $values as $value ) {
439 $this->items[] = $value;
440 }
441
442 return $this;
443 }
444
445 public function prepend( ...$values ) {
446 $this->items = array_merge( $values, $this->items );
447
448 return $this;
449 }
450
451 /**
452 * @param mixed $offset
453 *
454 * @return bool
455 */
456 #[\ReturnTypeWillChange]
457 public function offsetExists( $offset ) {
458 return isset( $this->items[ $offset ] );
459 }
460
461 /**
462 * @param mixed $offset
463 *
464 * @return mixed
465 */
466 #[\ReturnTypeWillChange]
467 public function offsetGet( $offset ) {
468 return $this->items[ $offset ];
469 }
470
471 /**
472 * @param mixed $offset
473 * @param mixed $value
474 */
475 #[\ReturnTypeWillChange]
476 public function offsetSet( $offset, $value ) {
477 if ( is_null( $offset ) ) {
478 $this->items[] = $value;
479 } else {
480 $this->items[ $offset ] = $value;
481 }
482 }
483
484 /**
485 * @param mixed $offset
486 */
487 #[\ReturnTypeWillChange]
488 public function offsetUnset( $offset ) {
489 unset( $this->items[ $offset ] );
490 }
491
492 /**
493 * @return \ArrayIterator|\Traversable
494 */
495 #[\ReturnTypeWillChange]
496 public function getIterator() {
497 return new \ArrayIterator( $this->items );
498 }
499
500 /**
501 * @return int|void
502 */
503 #[\ReturnTypeWillChange]
504 public function count() {
505 return count( $this->items );
506 }
507
508 /**
509 * @param $item
510 * @param $key
511 * @param null $default
512 *
513 * @return mixed|null
514 */
515 private function get_item_value( $item, $key, $default = null ) {
516 $value = $default;
517
518 if ( is_object( $item ) && isset( $item->{$key} ) ) {
519 $value = $item->{$key};
520 } elseif ( is_array( $item ) && isset( $item[ $key ] ) ) {
521 $value = $item[ $key ];
522 }
523
524 return $value;
525 }
526 }
527