Completed
Branch master (901ac8)
by Rémi
11:17
created

CollectionProxy::__get()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 4
rs 10
1
<?php
2
3
namespace Analogue\ORM\System\Proxies;
4
5
use Analogue\ORM\EntityCollection;
6
use Analogue\ORM\System\Manager;
7
use CachingIterator;
8
use ProxyManager\Proxy\ProxyInterface;
9
10
class CollectionProxy extends EntityCollection implements ProxyInterface
11
{
12
    /**
13
     * Indicate if the relationship has been lazy loaded.
14
     *
15
     * @var bool
16
     */
17
    protected $relationshipLoaded = false;
18
19
    protected $addedItems = [];
20
21
    /**
22
     * Create a new collection.
23
     *
24
     * @param mixed  $entity
25
     * @param string $relation
26
     *
27
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
28
     */
29
    public function __construct($entity, $relation)
30
    {
31
        $this->parentEntity = $entity;
32
        $this->relationshipMethod = $relation;
33
    }
34
35
    /**
36
     * Return Items that has been added without lady loading
37
     * the underlying collection.
38
     *
39
     * @return array
40
     */
41
    public function getAddedItems()
42
    {
43
        return $this->addedItems;
44
    }
45
46
    /**
47
     * Force initialization of the proxy.
48
     *
49
     * @return bool true if the proxy could be initialized
50
     */
51
    public function initializeProxy() : bool
52
    {
53
        if ($this->isProxyInitialized()) {
54
            return true;
55
        }
56
57
        $relation = $this->relationshipMethod;
58
        $entity = $this->parentEntity;
59
60
        $entityMap = Manager::getMapper($entity)->getEntityMap();
61
62
        $this->items = $entityMap->$relation($entity)->getResults($relation)->all() + $this->addedItems;
63
64
        $this->relationshipLoaded = true;
65
66
        return true;
67
    }
68
69
    /**
70
     * Retrieves current initialization status of the proxy.
71
     *
72
     * @return bool
73
     */
74
    public function isProxyInitialized() : bool
75
    {
76
        return $this->relationshipLoaded;
77
    }
78
79
    /**
80
     * Get all of the items in the collection.
81
     *
82
     * @return array
83
     */
84
    public function all()
85
    {
86
        $this->initializeProxy();
87
88
        return parent::all();
89
    }
90
91
    /**
92
     * Get the average value of a given key.
93
     *
94
     * @param callable|string|null $callback
95
     *
96
     * @return mixed
97
     */
98
    public function avg($callback = null)
99
    {
100
        $this->initializeProxy();
101
102
        return parent::avg($callback);
103
    }
104
105
    /**
106
     * Get the median of a given key.
107
     *
108
     * @param null $key
109
     *
110
     * @return mixed|null
111
     */
112
    public function median($key = null)
113
    {
114
        $this->initializeProxy();
115
116
        return parent::median($key);
117
    }
118
119
    /**
120
     * Get the mode of a given key.
121
     *
122
     * @param mixed $key
123
     *
124
     * @return array
125
     */
126
    public function mode($key = null)
127
    {
128
        $this->initializeProxy();
129
130
        return parent::mode($key);
131
    }
132
133
    /**
134
     * Collapse the collection of items into a single array.
135
     *
136
     * @return static
137
     */
138
    public function collapse()
139
    {
140
        $this->initializeProxy();
141
142
        return parent::collapse();
143
    }
144
145
    /**
146
     * Determine if an item exists in the collection.
147
     *
148
     * @param mixed $key
149
     * @param mixed $value
150
     *
151
     * @return bool
152
     */
153
    public function contains($key, $operator = null, $value = null)
154
    {
155
        $this->initializeProxy();
156
157
        return parent::contains($key, $operator, $value);
158
    }
159
160
    /**
161
     * Determine if an item exists in the collection using strict comparison.
162
     *
163
     * @param mixed $key
164
     * @param mixed $value
165
     *
166
     * @return bool
167
     */
168
    public function containsStrict($key, $value = null)
169
    {
170
        $this->initializeProxy();
171
172
        return parent::containsStrict($key, $value);
173
    }
174
175
    /**
176
     * Get the items in the collection that are not present in the given items.
177
     *
178
     * @param mixed $items
179
     *
180
     * @return static
181
     */
182
    public function diff($items)
183
    {
184
        $this->initializeProxy();
185
186
        return parent::diff($items);
187
    }
188
189
    /**
190
     * Get the items in the collection whose keys are not present in the given items.
191
     *
192
     * @param mixed $items
193
     *
194
     * @return static
195
     */
196
    public function diffKeys($items)
197
    {
198
        $this->initializeProxy();
199
200
        return parent::diffKeys($items);
201
    }
202
203
    /**
204
     * Execute a callback over each item.
205
     *
206
     * @param callable $callback
207
     *
208
     * @return $this
209
     */
210
    public function each(callable $callback)
211
    {
212
        $this->initializeProxy();
213
214
        return parent::each($callback);
215
    }
216
217
    /**
218
     * Create a new collection consisting of every n-th element.
219
     *
220
     * @param int $step
0 ignored issues
show
Bug introduced by
There is no parameter named $step. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
221
     * @param int $offset
0 ignored issues
show
Bug introduced by
There is no parameter named $offset. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
222
     *
223
     * @return static
224
     */
225
    public function every($key, $operator = null, $value = null)
226
    {
227
        $this->initializeProxy();
228
229
        return parent::every($key, $operator, $value);
230
    }
231
232
    /**
233
     * Get all items except for those with the specified keys.
234
     *
235
     * @param mixed $keys
236
     *
237
     * @return static
238
     */
239
    public function except($keys)
240
    {
241
        $this->initializeProxy();
242
243
        return parent::except($keys);
244
    }
245
246
    /**
247
     * Run a filter over each of the items.
248
     *
249
     * @param callable|null $callback
250
     *
251
     * @return static
252
     */
253
    public function filter(callable $callback = null)
254
    {
255
        $this->initializeProxy();
256
257
        return parent::filter($callback);
258
    }
259
260
    /**
261
     * Filter items by the given key value pair.
262
     *
263
     * @param string $key
264
     * @param mixed  $operator
265
     * @param mixed  $value
266
     *
267
     * @return static
268
     */
269
    public function where($key, $operator, $value = null)
270
    {
271
        $this->initializeProxy();
272
273
        return parent::where($key, $operator, $value);
274
    }
275
276
    /**
277
     * Filter items by the given key value pair using strict comparison.
278
     *
279
     * @param string $key
280
     * @param mixed  $value
281
     *
282
     * @return static
283
     */
284
    public function whereStrict($key, $value)
285
    {
286
        $this->initializeProxy();
287
288
        return parent::whereStrict($key, $value);
289
    }
290
291
    /**
292
     * Filter items by the given key value pair.
293
     *
294
     * @param string $key
295
     * @param mixed  $values
296
     * @param bool   $strict
297
     *
298
     * @return static
299
     */
300
    public function whereIn($key, $values, $strict = false)
301
    {
302
        $this->initializeProxy();
303
304
        return parent::whereIn($key, $values, $strict);
305
    }
306
307
    /**
308
     * Filter items by the given key value pair using strict comparison.
309
     *
310
     * @param string $key
311
     * @param mixed  $values
312
     *
313
     * @return static
314
     */
315
    public function whereInStrict($key, $values)
316
    {
317
        $this->initializeProxy();
318
319
        return parent::whereInStrict($key, $values);
320
    }
321
322
    /**
323
     * Get the first item from the collection.
324
     *
325
     * @param callable|null $callback
326
     * @param mixed         $default
327
     *
328
     * @return mixed
329
     */
330
    public function first(callable $callback = null, $default = null)
331
    {
332
        // TODO Consider partial loading
333
        $this->initializeProxy();
334
335
        return parent::first($callback, $default);
336
    }
337
338
    /**
339
     * Get a flattened array of the items in the collection.
340
     *
341
     * @param int $depth
342
     *
343
     * @return static
344
     */
345
    public function flatten($depth = INF)
346
    {
347
        $this->initializeProxy();
348
349
        return parent::flatten($depth);
350
    }
351
352
    /**
353
     * Flip the items in the collection.
354
     *
355
     * @return static
356
     */
357
    public function flip()
358
    {
359
        $this->initializeProxy();
360
361
        return parent::flip();
362
    }
363
364
    /**
365
     * Remove an item from the collection by key.
366
     *
367
     * @param string|array $keys
368
     *
369
     * @return $this
370
     */
371
    public function forget($keys)
372
    {
373
        // TODO, we could consider these as
374
        // 'pending deletion', the same way that
375
        // we treat added items
376
        $this->initializeProxy();
377
378
        return parent::forget($keys);
379
    }
380
381
    /**
382
     * Get an item from the collection by key.
383
     *
384
     * @param mixed $key
385
     * @param mixed $default
386
     *
387
     * @return mixed
388
     */
389
    public function get($key, $default = null)
390
    {
391
        // TODO : We could also consider partial loading
392
        // here
393
        $this->initializeProxy();
394
395
        return parent::get($key, $default);
396
    }
397
398
    /**
399
     * Group an associative array by a field or using a callback.
400
     *
401
     * @param callable|string $groupBy
402
     * @param bool            $preserveKeys
403
     *
404
     * @return static
405
     */
406
    public function groupBy($groupBy, $preserveKeys = false)
407
    {
408
        $this->initializeProxy();
409
410
        return parent::groupBy($groupBy, $preserveKeys);
411
    }
412
413
    /**
414
     * Key an associative array by a field or using a callback.
415
     *
416
     * @param callable|string $keyBy
417
     *
418
     * @return static
419
     */
420
    public function keyBy($keyBy)
421
    {
422
        $this->initializeProxy();
423
424
        return parent::keyBy($keyBy);
425
    }
426
427
    /**
428
     * Determine if an item exists in the collection by key.
429
     *
430
     * @param mixed $key
431
     *
432
     * @return bool
433
     */
434
    public function has($key)
435
    {
436
        // TODO : we could do automagic here by directly
437
        // calling the database if the collection hasn't
438
        // been initialized yet.
439
        // Potential issue is that several calls to this
440
        // could cause a lot queries vs a single get query.
441
        $this->initializeProxy();
442
443
        return parent::has($key);
444
    }
445
446
    /**
447
     * Concatenate values of a given key as a string.
448
     *
449
     * @param string $value
450
     * @param string $glue
451
     *
452
     * @return string
453
     */
454
    public function implode($value, $glue = null)
455
    {
456
        $this->initializeProxy();
457
458
        return parent::implode($value, $glue);
459
    }
460
461
    /**
462
     * Intersect the collection with the given items.
463
     *
464
     * @param mixed $items
465
     *
466
     * @return static
467
     */
468
    public function intersect($items)
469
    {
470
        $this->initializeProxy();
471
472
        return parent::intersect($items);
473
    }
474
475
    /**
476
     * Determine if the collection is empty or not.
477
     *
478
     * @return bool
479
     */
480
    public function isEmpty()
481
    {
482
        $this->initializeProxy();
483
484
        return parent::isEmpty();
485
    }
486
487
    /**
488
     * Get the keys of the collection items.
489
     *
490
     * @return static
491
     */
492
    public function keys()
493
    {
494
        $this->initializeProxy();
495
496
        return parent::keys();
497
    }
498
499
    /**
500
     * Get the last item from the collection.
501
     *
502
     * @param callable|null $callback
503
     * @param mixed         $default
504
     *
505
     * @return mixed
506
     */
507
    public function last(callable $callback = null, $default = null)
508
    {
509
        // TODO : we could do partial loading there as well
510
        $this->initializeProxy();
511
512
        return parent::last($callback, $default);
513
    }
514
515
    /**
516
     * Get the values of a given key.
517
     *
518
     * @param string      $value
519
     * @param string|null $key
520
     *
521
     * @return static
522
     */
523
    public function pluck($value, $key = null)
524
    {
525
        // TODO : automagic call to QB if not initialized
526
        $this->initializeProxy();
527
528
        return parent::pluck($value, $key);
529
    }
530
531
    /**
532
     * Run a map over each of the items.
533
     *
534
     * @param callable $callback
535
     *
536
     * @return static
537
     */
538
    public function map(callable $callback)
539
    {
540
        $this->initializeProxy();
541
542
        return parent::map($callback);
543
    }
544
545
    /**
546
     * Run an associative map over each of the items.
547
     *
548
     * The callback should return an associative array with a single key/value pair.
549
     *
550
     * @param callable $callback
551
     *
552
     * @return static
553
     */
554
    public function mapWithKeys(callable $callback)
555
    {
556
        $this->initializeProxy();
557
558
        return parent::mapWithKeys($callback);
559
    }
560
561
    /**
562
     * Map a collection and flatten the result by a single level.
563
     *
564
     * @param callable $callback
565
     *
566
     * @return static
567
     */
568
    public function flatMap(callable $callback)
569
    {
570
        $this->initializeProxy();
571
572
        return parent::flatMap($callback);
573
    }
574
575
    /**
576
     * Get the max value of a given key.
577
     *
578
     * @param callable|string|null $callback
579
     *
580
     * @return mixed
581
     */
582
    public function max($callback = null)
583
    {
584
        $this->initializeProxy();
585
586
        return parent::max($callback);
587
    }
588
589
    /**
590
     * Merge the collection with the given items.
591
     *
592
     * @param mixed $items
593
     *
594
     * @return static
595
     */
596
    public function merge($items)
597
    {
598
        // TODO : Check if the EntityCollection
599
        // returns a native Collection, as it
600
        // is what we want here
601
        $this->initializeProxy();
602
603
        return parent::merge($items);
604
    }
605
606
    /**
607
     * Create a collection by using this collection for keys and another for its values.
608
     *
609
     * @param mixed $values
610
     *
611
     * @return static
612
     */
613
    public function combine($values)
614
    {
615
        // TODO : Check if the EntityCollection
616
        // returns a native Collection, as it
617
        // is what we want here
618
        $this->initializeProxy();
619
620
        return parent::combine($values);
621
    }
622
623
    /**
624
     * Union the collection with the given items.
625
     *
626
     * @param mixed $items
627
     *
628
     * @return static
629
     */
630
    public function union($items)
631
    {
632
        // TODO : Check if the EntityCollection
633
        // returns a native Collection, as it
634
        // is what we want here
635
        $this->initializeProxy();
636
637
        return parent::union($items);
638
    }
639
640
    /**
641
     * Get the min value of a given key.
642
     *
643
     * @param callable|string|null $callback
644
     *
645
     * @return mixed
646
     */
647
    public function min($callback = null)
648
    {
649
        // TODO : we could rely on the QB
650
        // for thos, if initialization has not
651
        // take place yet
652
        $this->initializeProxy();
653
654
        return parent::min($callback);
655
    }
656
657
    /**
658
     * Create a new collection consisting of every n-th element.
659
     *
660
     * @param int $step
661
     * @param int $offset
662
     *
663
     * @return static
664
     */
665
    public function nth($step, $offset = 0)
666
    {
667
        $this->initializeProxy();
668
669
        return parent::nth($step, $offset);
670
    }
671
672
    /**
673
     * Get the items with the specified keys.
674
     *
675
     * @param mixed $keys
676
     *
677
     * @return static
678
     */
679
    public function only($keys)
680
    {
681
        // TODO : we could rely on the QB if
682
        // the collection hasn't been initialized yet
683
        $this->initializeProxy();
684
685
        return parent::only($keys);
686
    }
687
688
    /**
689
     * "Paginate" the collection by slicing it into a smaller collection.
690
     *
691
     * @param int $page
692
     * @param int $perPage
693
     *
694
     * @return static
695
     */
696
    public function forPage($page, $perPage)
697
    {
698
        // TODO : check possibility of partial loading
699
        // if not initialized
700
        $this->initializeProxy();
701
702
        return parent::forPage($page, $perPage);
703
    }
704
705
    /**
706
     * Partition the collection into two arrays using the given callback or key.
707
     *
708
     * @param callable|string $callback
709
     *
710
     * @return static
711
     */
712
    public function partition($callback)
713
    {
714
        $this->initializeProxy();
715
716
        return parent::partition($callback);
717
    }
718
719
    /**
720
     * Pass the collection to the given callback and return the result.
721
     *
722
     * @param callable $callback
723
     *
724
     * @return mixed
725
     */
726
    public function pipe(callable $callback)
727
    {
728
        $this->initializeProxy();
729
730
        return parent::pipe($callback);
731
    }
732
733
    /**
734
     * Get and remove the last item from the collection.
735
     *
736
     * @return mixed
737
     */
738
    public function pop()
739
    {
740
        $this->initializeProxy();
741
742
        return parent::pop();
743
    }
744
745
    /**
746
     * Push an item onto the beginning of the collection.
747
     *
748
     * @param mixed $value
749
     * @param mixed $key
750
     *
751
     * @return $this
752
     */
753
    public function prepend($value, $key = null)
754
    {
755
        // TODO : partial adding of values.
756
        // we could have a $prepended , and $pushed arrays
757
        // which we would combine at full initialization
758
759
        $this->initializeProxy();
760
761
        return parent::prepend($value, $key);
762
    }
763
764
    /**
765
     * Push an item onto the end of the collection.
766
     *
767
     * @param mixed $value
768
     *
769
     * @return $this
770
     */
771
    public function push($value)
772
    {
773
        // TODO : partial adding of values.
774
        // we could have a $prepended , and $pushed arrays
775
        // which we would combine at full initialization
776
777
        $this->initializeProxy();
778
779
        return parent::push($value);
780
    }
781
782
    /**
783
     * Get and remove an item from the collection.
784
     *
785
     * @param mixed $key
786
     * @param mixed $default
787
     *
788
     * @return mixed
789
     */
790
    public function pull($key, $default = null)
791
    {
792
        // TODO : QB query if the collection
793
        // hasn't been initialized yet
794
795
        $this->initializeProxy();
796
797
        return parent::pull($key, $default);
798
    }
799
800
    /**
801
     * Put an item in the collection by key.
802
     *
803
     * @param mixed $key
804
     * @param mixed $value
805
     *
806
     * @return $this
807
     */
808
    public function put($key, $value)
809
    {
810
        // TODO : Partial loading ?
811
812
        $this->initializeProxy();
813
814
        return parent::put($key, $value);
815
    }
816
817
    /**
818
     * Get one or more items randomly from the collection.
819
     *
820
     * @param int $amount
821
     *
822
     * @throws \InvalidArgumentException
823
     *
824
     * @return mixed
825
     */
826
    public function random($amount = 1)
827
    {
828
        // TODO : we could optimize this by only
829
        // fetching the keys from the database
830
        // and performing partial loading
831
832
        $this->initializeProxy();
833
834
        return parent::random($amount);
835
    }
836
837
    /**
838
     * Reduce the collection to a single value.
839
     *
840
     * @param callable $callback
841
     * @param mixed    $initial
842
     *
843
     * @return mixed
844
     */
845
    public function reduce(callable $callback, $initial = null)
846
    {
847
        $this->initializeProxy();
848
849
        return parent::reduce($callback, $initial);
850
    }
851
852
    /**
853
     * Create a collection of all elements that do not pass a given truth test.
854
     *
855
     * @param callable|mixed $callback
856
     *
857
     * @return static
858
     */
859
    public function reject($callback)
860
    {
861
        $this->initializeProxy();
862
863
        return parent::reject($callback);
864
    }
865
866
    /**
867
     * Reverse items order.
868
     *
869
     * @return static
870
     */
871
    public function reverse()
872
    {
873
        $this->initializeProxy();
874
875
        return parent::reverse();
876
    }
877
878
    /**
879
     * Search the collection for a given value and return the corresponding key if successful.
880
     *
881
     * @param mixed $value
882
     * @param bool  $strict
883
     *
884
     * @return mixed
885
     */
886
    public function search($value, $strict = false)
887
    {
888
        $this->initializeProxy();
889
890
        return parent::search($value, $strict);
891
    }
892
893
    /**
894
     * Get and remove the first item from the collection.
895
     *
896
     * @return mixed
897
     */
898
    public function shift()
899
    {
900
        // Todo : Partial Removing
901
        // we could have a pending removal array
902
        $this->initializeProxy();
903
904
        return parent::shift();
905
    }
906
907
    /**
908
     * Shuffle the items in the collection.
909
     *
910
     * @param int $seed
911
     *
912
     * @return static
913
     */
914
    public function shuffle($seed = null)
915
    {
916
        $this->initializeProxy();
917
918
        return parent::shuffle($seed);
919
    }
920
921
    /**
922
     * Slice the underlying collection array.
923
     *
924
     * @param int $offset
925
     * @param int $length
926
     *
927
     * @return static
928
     */
929
    public function slice($offset, $length = null)
930
    {
931
        $this->initializeProxy();
932
933
        return parent::slice($offset, $length);
934
    }
935
936
    /**
937
     * Split a collection into a certain number of groups.
938
     *
939
     * @param int $numberOfGroups
940
     *
941
     * @return static
942
     */
943
    public function split($numberOfGroups)
944
    {
945
        $this->initializeProxy();
946
947
        return parent::split($numberOfGroups);
948
    }
949
950
    /**
951
     * Chunk the underlying collection array.
952
     *
953
     * @param int $size
954
     *
955
     * @return static
956
     */
957
    public function chunk($size)
958
    {
959
        // TODO : partial loading ?
960
        $this->initializeProxy();
961
962
        return parent::chunk($size);
963
    }
964
965
    /**
966
     * Sort through each item with a callback.
967
     *
968
     * @param callable|null $callback
969
     *
970
     * @return static
971
     */
972
    public function sort(callable $callback = null)
973
    {
974
        $this->initializeProxy();
975
976
        return parent::sort($callback);
977
    }
978
979
    /**
980
     * Sort the collection using the given callback.
981
     *
982
     * @param callable|string $callback
983
     * @param int             $options
984
     * @param bool            $descending
985
     *
986
     * @return static
987
     */
988
    public function sortBy($callback, $options = SORT_REGULAR, $descending = false)
989
    {
990
        $this->initializeProxy();
991
992
        return parent::sort($callback, $options, $descending);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (sort() instead of sortBy()). Are you sure this is correct? If so, you might want to change this to $this->sort().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
993
    }
994
995
    /**
996
     * Splice a portion of the underlying collection array.
997
     *
998
     * @param int      $offset
999
     * @param int|null $length
1000
     * @param mixed    $replacement
1001
     *
1002
     * @return static
1003
     */
1004
    public function splice($offset, $length = null, $replacement = [])
1005
    {
1006
        $this->initializeProxy();
1007
1008
        return parent::splice($offset, $length, $replacement);
1009
    }
1010
1011
    /**
1012
     * Get the sum of the given values.
1013
     *
1014
     * @param callable|string|null $callback
1015
     *
1016
     * @return mixed
1017
     */
1018
    public function sum($callback = null)
1019
    {
1020
        $this->initializeProxy();
1021
1022
        return parent::sum($callback);
1023
    }
1024
1025
    /**
1026
     * Take the first or last {$limit} items.
1027
     *
1028
     * @param int $limit
1029
     *
1030
     * @return static
1031
     */
1032
    public function take($limit)
1033
    {
1034
        // TODO: partial loading
1035
        $this->initializeProxy();
1036
1037
        return parent::take($limit);
1038
    }
1039
1040
    /**
1041
     * Transform each item in the collection using a callback.
1042
     *
1043
     * @param callable $callback
1044
     *
1045
     * @return $this
1046
     */
1047
    public function transform(callable $callback)
1048
    {
1049
        $this->initializeProxy();
1050
1051
        return parent::transform($callback);
1052
    }
1053
1054
    /**
1055
     * Return only unique items from the collection array.
1056
     *
1057
     * @param string|callable|null $key
1058
     * @param bool                 $strict
1059
     *
1060
     * @return static
1061
     */
1062
    public function unique($key = null, $strict = false)
1063
    {
1064
        $this->initializeProxy();
1065
1066
        return parent::unique($key, $strict);
1067
    }
1068
1069
    /**
1070
     * Reset the keys on the underlying array.
1071
     *
1072
     * @return static
1073
     */
1074
    public function values()
1075
    {
1076
        $this->initializeProxy();
1077
1078
        return parent::values();
1079
    }
1080
1081
    /**
1082
     * Zip the collection together with one or more arrays.
1083
     *
1084
     * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]);
1085
     *      => [[1, 4], [2, 5], [3, 6]]
1086
     *
1087
     * @param mixed ...$items
1088
     *
1089
     * @return static
1090
     */
1091
    public function zip($items)
1092
    {
1093
        $this->initializeProxy();
1094
1095
        return parent::zip($items);
1096
    }
1097
1098
    /**
1099
     * Get the collection of items as a plain array.
1100
     *
1101
     * @return array
1102
     */
1103
    public function toArray()
1104
    {
1105
        // If this is called on all subsequent proxy,
1106
        // this would eventually trigger all lazy loading,
1107
        // which is NOT what we would expect...
1108
        // TODO : must think of this.
1109
        $this->initializeProxy();
1110
1111
        return parent::toArray();
1112
    }
1113
1114
    /**
1115
     * Convert the object into something JSON serializable.
1116
     *
1117
     * @return array
1118
     */
1119
    public function jsonSerialize()
1120
    {
1121
        // If this is called on all subsequent proxy,
1122
        // this would eventually trigger all lazy loading,
1123
        // which is NOT what we would expect...
1124
        // TODO : must think of this.
1125
        $this->initializeProxy();
1126
1127
        return parent::jsonSerialize();
1128
    }
1129
1130
    /**
1131
     * Get the collection of items as JSON.
1132
     *
1133
     * @param int $options
1134
     *
1135
     * @return string
1136
     */
1137
    public function toJson($options = 0)
1138
    {
1139
        // If this is called on all subsequent proxy,
1140
        // this would eventually trigger all lazy loading,
1141
        // which is NOT what we would expect...
1142
        // TODO : must think of this.
1143
        $this->initializeProxy();
1144
1145
        return parent::toJson($options);
1146
    }
1147
1148
    /**
1149
     * Get an iterator for the items.
1150
     *
1151
     * @return \ArrayIterator
1152
     */
1153
    public function getIterator()
1154
    {
1155
        $this->initializeProxy();
1156
1157
        return parent::getIterator();
1158
    }
1159
1160
    /**
1161
     * Get a CachingIterator instance.
1162
     *
1163
     * @param int $flags
1164
     *
1165
     * @return \CachingIterator
1166
     */
1167
    public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING)
1168
    {
1169
        $this->initializeProxy();
1170
1171
        return parent::getCachingIterator($flags);
1172
    }
1173
1174
    /**
1175
     * Count the number of items in the collection.
1176
     *
1177
     * @return int
1178
     */
1179
    public function count()
1180
    {
1181
        // TODO rely on QB if not initialized
1182
        $this->initializeProxy();
1183
1184
        return parent::count();
1185
    }
1186
1187
    /**
1188
     * Get a base Support collection instance from this collection.
1189
     *
1190
     * @return \Illuminate\Support\Collection
1191
     */
1192
    public function toBase()
1193
    {
1194
        $this->initializeProxy();
1195
1196
        return parent::toBase();
1197
    }
1198
1199
    /**
1200
     * Determine if an item exists at an offset.
1201
     *
1202
     * @param mixed $key
1203
     *
1204
     * @return bool
1205
     */
1206
    public function offsetExists($key)
1207
    {
1208
        // TODO rely on QB if no collection
1209
        // initialized
1210
        $this->initializeProxy();
1211
1212
        return parent::offsetExists($key);
1213
    }
1214
1215
    /**
1216
     * Get an item at a given offset.
1217
     *
1218
     * @param mixed $key
1219
     *
1220
     * @return mixed
1221
     */
1222
    public function offsetGet($key)
1223
    {
1224
        // TODO rely on partial init if no collection
1225
        // initialized
1226
        $this->initializeProxy();
1227
1228
        return parent::offsetGet($key);
1229
    }
1230
1231
    /**
1232
     * Set the item at a given offset.
1233
     *
1234
     * @param mixed $key
1235
     * @param mixed $value
1236
     *
1237
     * @return void
1238
     */
1239
    public function offsetSet($key, $value)
1240
    {
1241
        // TODO : think of the use of it into a ProxyCollection
1242
        // context
1243
        $this->initializeProxy();
1244
1245
        return parent::offsetSet($key, $value);
1246
    }
1247
1248
    /**
1249
     * Unset the item at a given offset.
1250
     *
1251
     * @param string $key
1252
     *
1253
     * @return void
1254
     */
1255
    public function offsetUnset($key)
1256
    {
1257
        // TODO : think of the use of it into a ProxyCollection
1258
        // context
1259
        $this->initializeProxy();
1260
1261
        return parent::offsetUnset($key);
1262
    }
1263
1264
    /**
1265
     * Dynamically access collection proxies.
1266
     *
1267
     * @param string $key
1268
     *
1269
     * @throws \Exception
1270
     *
1271
     * @return mixed
1272
     */
1273
    public function __get($key)
1274
    {
1275
        parent::__get($key);
1276
    }
1277
1278
    /**
1279
     * Dynamically handle calls to the class.
1280
     *
1281
     * @param string $method
1282
     * @param array  $parameters
1283
     *
1284
     * @throws \BadMethodCallException
1285
     *
1286
     * @return mixed
1287
     */
1288
    public function __call($method, $parameters)
1289
    {
1290
        $this->initializeProxy();
1291
1292
        return parent::__call($method, $parameters);
1293
    }
1294
}
1295