PluginProbe
Elementor Website Builder – more than just a page builder / 3.6.0-dev1
Elementor Website Builder – more than just a page builder v3.6.0-dev1
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 / trunk / core / utils / collection.php

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

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