7fa50ea8e5e6ac9037fc580efd88619ff7854e5e
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Persistence / Generic / LazyLoadingProxy.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Persistence\Generic;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * A proxy that can replace any object and replaces itself in it's parent on
19 * first access (call, get, set, isset, unset).
20 */
21 class LazyLoadingProxy implements \Iterator, \TYPO3\CMS\Extbase\Persistence\Generic\LoadingStrategyInterface {
22
23 /**
24 * @var \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper
25 * @inject
26 */
27 protected $dataMapper;
28
29 /**
30 * The object this property is contained in.
31 *
32 * @var \TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface
33 */
34 private $parentObject;
35
36 /**
37 * The name of the property represented by this proxy.
38 *
39 * @var string
40 */
41 private $propertyName;
42
43 /**
44 * The raw field value.
45 *
46 * @var mixed
47 */
48 private $fieldValue;
49
50 /**
51 * Constructs this proxy instance.
52 *
53 * @param object $parentObject The object instance this proxy is part of
54 * @param string $propertyName The name of the proxied property in it's parent
55 * @param mixed $fieldValue The raw field value.
56 */
57 public function __construct($parentObject, $propertyName, $fieldValue) {
58 $this->parentObject = $parentObject;
59 $this->propertyName = $propertyName;
60 $this->fieldValue = $fieldValue;
61 }
62
63 /**
64 * Populate this proxy by asking the $population closure.
65 *
66 * @return object The instance (hopefully) returned
67 */
68 public function _loadRealInstance() {
69 // this check safeguards against a proxy being activated multiple times
70 // usually that does not happen, but if the proxy is held from outside
71 // it's parent... the result would be weird.
72 if ($this->parentObject->_getProperty($this->propertyName) instanceof \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy) {
73 $objects = $this->dataMapper->fetchRelated($this->parentObject, $this->propertyName, $this->fieldValue, FALSE, FALSE);
74 $propertyValue = $this->dataMapper->mapResultToPropertyValue($this->parentObject, $this->propertyName, $objects);
75 $this->parentObject->_setProperty($this->propertyName, $propertyValue);
76 $this->parentObject->_memorizeCleanState($this->propertyName);
77 return $propertyValue;
78 } else {
79 return $this->parentObject->_getProperty($this->propertyName);
80 }
81 }
82
83 /**
84 * Magic method call implementation.
85 *
86 * @param string $methodName The name of the property to get
87 * @param array $arguments The arguments given to the call
88 * @return mixed
89 */
90 public function __call($methodName, $arguments) {
91 $realInstance = $this->_loadRealInstance();
92 if (!is_object($realInstance)) {
93 return NULL;
94 }
95 return call_user_func_array(array($realInstance, $methodName), $arguments);
96 }
97
98 /**
99 * Magic get call implementation.
100 *
101 * @param string $propertyName The name of the property to get
102 * @return mixed
103 */
104 public function __get($propertyName) {
105 $realInstance = $this->_loadRealInstance();
106 return $realInstance->{$propertyName};
107 }
108
109 /**
110 * Magic set call implementation.
111 *
112 * @param string $propertyName The name of the property to set
113 * @param mixed $value The value for the property to set
114 * @return void
115 */
116 public function __set($propertyName, $value) {
117 $realInstance = $this->_loadRealInstance();
118 $realInstance->{$propertyName} = $value;
119 }
120
121 /**
122 * Magic isset call implementation.
123 *
124 * @param string $propertyName The name of the property to check
125 * @return bool
126 */
127 public function __isset($propertyName) {
128 $realInstance = $this->_loadRealInstance();
129 return isset($realInstance->{$propertyName});
130 }
131
132 /**
133 * Magic unset call implementation.
134 *
135 * @param string $propertyName The name of the property to unset
136 * @return void
137 */
138 public function __unset($propertyName) {
139 $realInstance = $this->_loadRealInstance();
140 unset($realInstance->{$propertyName});
141 }
142
143 /**
144 * Magic toString call implementation.
145 *
146 * @return string
147 */
148 public function __toString() {
149 $realInstance = $this->_loadRealInstance();
150 return $realInstance->__toString();
151 }
152
153 /**
154 * Returns the current value of the storage array
155 *
156 * @return mixed
157 */
158 public function current() {
159 $realInstance = $this->_loadRealInstance();
160 return current($realInstance);
161 }
162
163 /**
164 * Returns the current key storage array
165 *
166 * @return int
167 */
168 public function key() {
169 $realInstance = $this->_loadRealInstance();
170 return key($realInstance);
171 }
172
173 /**
174 * Returns the next position of the storage array
175 *
176 * @return void
177 */
178 public function next() {
179 $realInstance = $this->_loadRealInstance();
180 next($realInstance);
181 }
182
183 /**
184 * Resets the array pointer of the storage
185 *
186 * @return void
187 */
188 public function rewind() {
189 $realInstance = $this->_loadRealInstance();
190 reset($realInstance);
191 }
192
193 /**
194 * Checks if the array pointer of the storage points to a valid position
195 *
196 * @return bool
197 */
198 public function valid() {
199 return $this->current() !== FALSE;
200 }
201
202 }