@@ -20,6 +20,12 @@ abstract class LazyCollection implements Collection {
20
20
*/
21
21
protected $ queue = [];
22
22
23
+ /**
24
+ * A variable representing the execution chain for this collection;
25
+ * @var null
26
+ */
27
+ protected $ executedValue = null ;
28
+
23
29
/**
24
30
* @see Collection::__construct
25
31
*/
@@ -37,9 +43,17 @@ public function __construct($data, $queue = [], $limit = null) {
37
43
* @return this Returns itself for chaining
38
44
*/
39
45
protected function enqueue ($ method , callable $ callback ) {
40
- $ queue = $ this ->queue ;
41
- $ queue [] = [$ method , $ callback ];
42
- return new static ($ this ->data , $ queue , $ this ->limit );
46
+ $ enqueued = [$ method , $ callback ];
47
+
48
+ if ($ this ->executedValue !== null ) {
49
+ // If this chain has been executed, then create a new object with only one chained method
50
+ return new static ($ this ->executedValue , [$ enqueued ], $ this ->limit );
51
+ } else {
52
+ // Otherwise extend the chain and continue
53
+ $ queue = $ this ->queue ;
54
+ $ queue [] = $ enqueued ;
55
+ return new static ($ this ->data , $ queue , $ this ->limit );
56
+ }
43
57
}
44
58
45
59
/**
@@ -80,7 +94,13 @@ public function reject(callable $callback) {
80
94
* @see Collection::take
81
95
*/
82
96
public function take ($ limit = 1 ) {
83
- return new static ($ this ->data , $ this ->queue , $ limit );
97
+ if ($ this ->executedValue !== null ) {
98
+ // If this chain has been executed, then create a new object with no chained method
99
+ return new static ($ this ->executedValue , [], $ limit );
100
+ } else {
101
+ // Otherwise keep the chain and modify the limit
102
+ return new static ($ this ->data , $ this ->queue , $ limit );
103
+ }
84
104
}
85
105
86
106
/**
@@ -215,6 +235,11 @@ public function jsonSerialize() {
215
235
* @see Collection::execute
216
236
*/
217
237
public function execute () {
238
+ // If a cached value is available, run that
239
+ if ($ this ->executedValue !== null ) {
240
+ return $ this ->executedValue ;
241
+ }
242
+
218
243
// Group queued methods into execution blocks
219
244
$ execution_blocks = [];
220
245
$ current_block = [];
@@ -309,6 +334,8 @@ public function execute() {
309
334
$ returned = array_slice ($ returned , 0 , $ this ->limit );
310
335
}
311
336
337
+ $ this ->executedValue = $ returned ;
338
+
312
339
// Return the transformed data
313
340
return $ returned ;
314
341
}
0 commit comments