[+FEATURE] Extbase (Persistence): Implemented a second Lazy Loading strategy called...
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Persistence / ObjectStorage.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 /**
26 * The storage for objects. It ensures the uniqueness of an object in the storage. It's a remake of the
27 * SplObjectStorage introduced in PHP 5.3.
28 *
29 * @package Extbase
30 * @subpackage Persistence
31 * @version $ID:$
32 */
33 class Tx_Extbase_Persistence_ObjectStorage implements Iterator, Countable, ArrayAccess {
34
35 /**
36 * The array holding references of the stored objects
37 *
38 * @var array
39 */
40 protected $storage = array();
41
42 /**
43 * This is a template function to be overwritten by a concrete implementation. It enables you to implement
44 * a lazy load implementation.
45 *
46 * @return void
47 */
48 protected function initializeStorage() {
49 }
50
51 /**
52 * Resets the array pointer of the storage
53 *
54 * @return void
55 */
56 public function rewind() {
57 $this->initializeStorage();
58 reset($this->storage);
59 }
60
61 /**
62 * Checks if the array pointer of the storage points to a valid position
63 *
64 * @return void
65 */
66 public function valid() {
67 $this->initializeStorage();
68 return $this->current() !== FALSE;
69 }
70
71 /**
72 * Returns the current key storage array
73 *
74 * @return void
75 */
76 public function key() {
77 $this->initializeStorage();
78 return key($this->storage);
79 }
80
81 /**
82 * Returns the current value of the storage array
83 *
84 * @return void
85 */
86 public function current() {
87 $this->initializeStorage();
88 return current($this->storage);
89 }
90
91 /**
92 * Returns the next position of the storage array
93 *
94 * @return void
95 */
96 public function next() {
97 $this->initializeStorage();
98 next($this->storage);
99 }
100
101 /**
102 * Counts the elements in the storage array
103 *
104 * @return void
105 */
106 public function count() {
107 $this->initializeStorage();
108 return count($this->storage);
109 }
110
111 /**
112 * Loads the array at a given offset. Nothing happens if the object already exists in the storage
113 *
114 * @param string $offset
115 * @param string $obj The object
116 * @return void
117 */
118 public function offsetSet($offset, $value) {
119 if (!is_object($offset)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter 1 to be object, ' . gettype($offset) . ' given');
120 // TODO Check implementation again
121 // if (!is_object($obj)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter 2 to be object, ' . gettype($offset) . ' given');
122 // if (!($offset === $obj)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Parameter 1 and parameter 2 must be a reference to the same object.');
123 $this->initializeStorage();
124 if (!$this->contains($offset)) {
125 $this->storage[spl_object_hash($offset)] = $value;
126 }
127 }
128
129 /**
130 * Checks if a given offset exists in the storage
131 *
132 * @param string $offset
133 * @return boolean TRUE if the given offset exists; otherwise FALSE
134 */
135 public function offsetExists($offset) {
136 if (!is_object($offset)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($offset) . ' given');
137 $this->initializeStorage();
138 return isset($this->storage[spl_object_hash($offset)]);
139 }
140
141 /**
142 * Unsets the storage at the given offset
143 *
144 * @param string $offset The offset
145 * @return void
146 */
147 public function offsetUnset($offset) {
148 if (!is_object($offset)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($offset) . ' given');
149 $this->initializeStorage();
150 unset($this->storage[spl_object_hash($offset)]);
151 }
152
153 /**
154 * Returns the object at the given offset
155 *
156 * @param string $offset The offset
157 * @return Object The object
158 */
159 public function offsetGet($offset) {
160 if (!is_object($offset)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($offset) . ' given');
161 $this->initializeStorage();
162 return isset($this->storage[spl_object_hash($offset)]) ? $this->storage[spl_object_hash($offset)] : NULL;
163 }
164
165 /**
166 * Checks if the storage contains the given object
167 *
168 * @param Object $object The object to be checked for
169 * @return boolean TRUE|FALSE Returns TRUE if the storage contains the object; otherwise FALSE
170 */
171 public function contains($object) {
172 if (!is_object($object)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($object) . ' given');
173 $this->initializeStorage();
174 return array_key_exists(spl_object_hash($object), $this->storage);
175 }
176
177 /**
178 * Attaches an object to the storage
179 *
180 * @param Object $obj The Object to be attached
181 * @return void
182 */
183 public function attach($object, $value = NULL) {
184 if (!is_object($object)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($object) . ' given');
185 $this->initializeStorage();
186 if (!$this->contains($object)) {
187 if ($value === NULL) {
188 $value = $object;
189 }
190 // TODO Revise this with Karsten
191 $this->storage[spl_object_hash($object)] = $value;
192 }
193 }
194
195 /**
196 * Detaches an object from the storage
197 *
198 * @param Object $object The object to be removed from the storage
199 * @return void
200 */
201 public function detach($object) {
202 if (!is_object($object)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($object) . ' given');
203 $this->initializeStorage();
204 unset($this->storage[spl_object_hash($object)]);
205 }
206
207 /**
208 * Attach all objects to the storage
209 *
210 * @param array $objects The objects to be attached to the storage
211 * @return void
212 */
213 public function addAll($objects) {
214 if (is_array($objects) || ($objects instanceof Tx_Extbase_Persistence_ObjectStorage)) {
215 $this->initializeStorage();
216 foreach ($objects as $object) {
217 $this->attach($object);
218 }
219 } else {
220 throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an array, ' . gettype($object) . ' given');
221 }
222 }
223
224 /**
225 * Detaches all objects from the storage
226 *
227 * @param array $objects The objects to be detached from the storage
228 * @return void
229 */
230 public function removeAll($objects) {
231 if (!is_array($object)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an array, ' . gettype($object) . ' given');
232 $this->initializeStorage();
233 foreach ($objects as $object) {
234 $this->detach($object);
235 }
236 }
237
238 /**
239 * Returns this object storage as an array
240 *
241 * @return array The object storage
242 */
243 public function toArray() {
244 $this->initializeStorage();
245 return $this->storage;
246 }
247
248 }
249
250 ?>