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 | ||
59 | public function offsetExists($offset) { | |
60 | return isset($this->load()->cache[$offset]); | |
61 | } | |
62 | ||
63 | public function &offsetGet($offset) { | |
64 | return $this->load()->cache[$offset]; | |
65 | } | |
66 | ||
67 | public function offsetSet($offset, $value) { | |
68 | if ($offset === NULL) { | |
69 | $this->load()->cache[] = $value; | |
70 | } | |
71 | else { | |
72 | $this->load()->cache[$offset] = $value; | |
73 | } | |
74 | } | |
75 | ||
76 | public function offsetUnset($offset) { | |
77 | unset($this->load()->cache[$offset]); | |
78 | } | |
79 | ||
80 | public function getIterator() { | |
81 | return new ArrayIterator($this->load()->cache); | |
82 | } | |
83 | ||
84 | /** | |
85 | * @return array | |
86 | */ | |
87 | public function getArrayCopy() { | |
88 | return $this->load()->cache; | |
89 | } | |
90 | ||
91 | public function count() { | |
92 | return count($this->load()->cache); | |
93 | } | |
94 | ||
95 | } |