Commit | Line | Data |
---|---|---|
48872a57 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
4 | | Copyright CiviCRM LLC. All rights reserved. | | |
5 | | | | |
6 | | This work is published under the GNU AGPLv3 license with some | | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
9 | +--------------------------------------------------------------------+ | |
10 | */ | |
11 | ||
12 | /** | |
13 | * A lazy-array works much like a regular array or ArrayObject. However, it is | |
14 | * initially empty - and it is only populated if used. | |
15 | */ | |
16 | class CRM_Utils_LazyArray implements ArrayAccess, IteratorAggregate, Countable { | |
17 | ||
18 | /** | |
19 | * A function which generates a list of values. | |
20 | * | |
21 | * @var callable | |
22 | * function(): iterable | |
23 | */ | |
24 | private $func; | |
25 | ||
26 | /** | |
27 | * Cached values | |
28 | * | |
29 | * @var array|null | |
30 | */ | |
31 | private $cache; | |
32 | ||
33 | /** | |
34 | * CRM_Utils_LazyList constructor. | |
35 | * | |
36 | * @param callable $func | |
37 | * Function which provides a list of values (array/iterator/generator). | |
38 | */ | |
39 | public function __construct($func) { | |
40 | $this->func = $func; | |
41 | } | |
42 | ||
43 | /** | |
44 | * Determine if the content has been fetched. | |
45 | * | |
46 | * @return bool | |
47 | */ | |
48 | public function isLoaded() { | |
49 | return $this->cache !== NULL; | |
50 | } | |
51 | ||
52 | public function load($force = FALSE) { | |
53 | if ($this->cache === NULL || $force) { | |
54 | $this->cache = CRM_Utils_Array::cast(call_user_func($this->func)); | |
55 | } | |
56 | return $this; | |
57 | } | |
58 | ||
d77b3d91 | 59 | public function offsetExists($offset): bool { |
48872a57 TO |
60 | return isset($this->load()->cache[$offset]); |
61 | } | |
62 | ||
d77b3d91 | 63 | #[\ReturnTypeWillChange] |
48872a57 TO |
64 | public function &offsetGet($offset) { |
65 | return $this->load()->cache[$offset]; | |
66 | } | |
67 | ||
d77b3d91 | 68 | public function offsetSet($offset, $value): void { |
48872a57 TO |
69 | if ($offset === NULL) { |
70 | $this->load()->cache[] = $value; | |
71 | } | |
72 | else { | |
73 | $this->load()->cache[$offset] = $value; | |
74 | } | |
75 | } | |
76 | ||
d77b3d91 | 77 | public function offsetUnset($offset): void { |
48872a57 TO |
78 | unset($this->load()->cache[$offset]); |
79 | } | |
80 | ||
d77b3d91 | 81 | #[\ReturnTypeWillChange] |
48872a57 TO |
82 | public function getIterator() { |
83 | return new ArrayIterator($this->load()->cache); | |
84 | } | |
85 | ||
86 | /** | |
87 | * @return array | |
88 | */ | |
89 | public function getArrayCopy() { | |
90 | return $this->load()->cache; | |
91 | } | |
92 | ||
d77b3d91 | 93 | public function count(): int { |
48872a57 TO |
94 | return count($this->load()->cache); |
95 | } | |
96 | ||
97 | } |