[BUGFIX] Make ToolBar in AdminPanel working again
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / DomainObject / AbstractDomainObject.php
1 <?php
2 namespace TYPO3\CMS\Extbase\DomainObject;
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 generic Domain Object.
19 *
20 * All Model domain objects need to inherit from either AbstractEntity or AbstractValueObject, as this provides important framework information.
21 */
22 abstract class AbstractDomainObject implements DomainObjectInterface, \TYPO3\CMS\Extbase\Persistence\ObjectMonitoringInterface {
23
24 /**
25 * @var int The uid of the record. The uid is only unique in the context of the database table.
26 */
27 protected $uid;
28
29 /**
30 * @var int The uid of the localized record. In TYPO3 v4.x the property "uid" holds the uid of the record in default language (the translationOrigin).
31 */
32 protected $_localizedUid;
33
34 /**
35 * @var int The uid of the language of the object. In TYPO3 v4.x this is the uid of the language record in the table sys_language.
36 */
37 protected $_languageUid;
38
39 /**
40 * @var int The uid of the versioned record.
41 */
42 protected $_versionedUid;
43
44 /**
45 * @var int The id of the page the record is "stored".
46 */
47 protected $pid;
48
49 /**
50 * TRUE if the object is a clone
51 *
52 * @var bool
53 */
54 private $_isClone = FALSE;
55
56 /**
57 * @var array An array holding the clean property values. Set right after reconstitution of the object
58 */
59 private $_cleanProperties = array();
60
61 /**
62 * This is the magic __wakeup() method. It's invoked by the unserialize statement in the reconstitution process
63 * of the object. If you want to implement your own __wakeup() method in your Domain Object you have to call
64 * parent::__wakeup() first!
65 *
66 * @return void
67 */
68 public function __wakeup() {
69 $this->initializeObject();
70 }
71
72 public function initializeObject() {
73 }
74
75 /**
76 * Getter for uid.
77 *
78 * @return int the uid or NULL if none set yet.
79 */
80 public function getUid() {
81 if ($this->uid !== NULL) {
82 return (int)$this->uid;
83 } else {
84 return NULL;
85 }
86 }
87
88 /**
89 * Setter for the pid.
90 *
91 * @param int|NULL $pid
92 * @return void
93 */
94 public function setPid($pid) {
95 if ($pid === NULL) {
96 $this->pid = NULL;
97 } else {
98 $this->pid = (int)$pid;
99 }
100 }
101
102 /**
103 * Getter for the pid.
104 *
105 * @return int The pid or NULL if none set yet.
106 */
107 public function getPid() {
108 if ($this->pid === NULL) {
109 return NULL;
110 } else {
111 return (int)$this->pid;
112 }
113 }
114
115 /**
116 * Reconstitutes a property. Only for internal use.
117 *
118 * @param string $propertyName
119 * @param mixed $propertyValue
120 * @return bool
121 */
122 public function _setProperty($propertyName, $propertyValue) {
123 if ($this->_hasProperty($propertyName)) {
124 $this->{$propertyName} = $propertyValue;
125 return TRUE;
126 }
127 return FALSE;
128 }
129
130 /**
131 * Returns the property value of the given property name. Only for internal use.
132 *
133 * @param string $propertyName
134 * @return mixed The propertyValue
135 */
136 public function _getProperty($propertyName) {
137 return $this->{$propertyName};
138 }
139
140 /**
141 * Returns a hash map of property names and property values. Only for internal use.
142 *
143 * @return array The properties
144 */
145 public function _getProperties() {
146 $properties = get_object_vars($this);
147 foreach ($properties as $propertyName => $propertyValue) {
148 if ($propertyName[0] === '_') {
149 unset($properties[$propertyName]);
150 }
151 }
152 return $properties;
153 }
154
155 /**
156 * Returns the property value of the given property name. Only for internal use.
157 *
158 * @param string $propertyName
159 * @return bool TRUE bool true if the property exists, FALSE if it doesn't exist or NULL in case of an error.
160 */
161 public function _hasProperty($propertyName) {
162 return property_exists($this, $propertyName);
163 }
164
165 /**
166 * Returns TRUE if the object is new (the uid was not set, yet). Only for internal use
167 *
168 * @return bool
169 */
170 public function _isNew() {
171 return $this->uid === NULL;
172 }
173
174 /**
175 * Register an object's clean state, e.g. after it has been reconstituted
176 * from the database.
177 *
178 * @param string $propertyName The name of the property to be memorized. If omitted all persistable properties are memorized.
179 * @return void
180 */
181 public function _memorizeCleanState($propertyName = NULL) {
182 if ($propertyName !== NULL) {
183 $this->_memorizePropertyCleanState($propertyName);
184 } else {
185 $this->_cleanProperties = array();
186 $properties = get_object_vars($this);
187 foreach ($properties as $propertyName => $propertyValue) {
188 if ($propertyName[0] === '_') {
189 continue;
190 }
191 // Do not memorize "internal" properties
192 $this->_memorizePropertyCleanState($propertyName);
193 }
194 }
195 }
196
197 /**
198 * Register an properties's clean state, e.g. after it has been reconstituted
199 * from the database.
200 *
201 * @param string $propertyName The name of the property to be memorized. If omittet all persistable properties are memorized.
202 * @return void
203 */
204 public function _memorizePropertyCleanState($propertyName) {
205 $propertyValue = $this->{$propertyName};
206 if (is_object($propertyValue)) {
207 $this->_cleanProperties[$propertyName] = clone $propertyValue;
208 // We need to make sure the clone and the original object
209 // are identical when compared with == (see _isDirty()).
210 // After the cloning, the Domain Object will have the property
211 // "isClone" set to TRUE, so we manually have to set it to FALSE
212 // again. Possible fix: Somehow get rid of the "isClone" property,
213 // which is currently needed in Fluid.
214 if ($propertyValue instanceof \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject) {
215 $this->_cleanProperties[$propertyName]->_setClone(FALSE);
216 }
217 } else {
218 $this->_cleanProperties[$propertyName] = $propertyValue;
219 }
220 }
221
222 /**
223 * Returns a hash map of clean properties and $values.
224 *
225 * @return array
226 */
227 public function _getCleanProperties() {
228 return $this->_cleanProperties;
229 }
230
231 /**
232 * Returns the clean value of the given property. The returned value will be NULL if the clean state was not memorized before, or
233 * if the clean value is NULL.
234 *
235 * @param string $propertyName The name of the property to be memorized.
236 * @return mixed The clean property value or NULL
237 */
238 public function _getCleanProperty($propertyName) {
239 return isset($this->_cleanProperties[$propertyName]) ? $this->_cleanProperties[$propertyName] : NULL;
240 }
241
242 /**
243 * Returns TRUE if the properties were modified after reconstitution
244 *
245 * @param string $propertyName An optional name of a property to be checked if its value is dirty
246 * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\TooDirtyException
247 * @return bool
248 */
249 public function _isDirty($propertyName = NULL) {
250 if ($this->uid !== NULL && $this->_getCleanProperty('uid') !== NULL && $this->uid != $this->_getCleanProperty('uid')) {
251 throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\TooDirtyException('The uid "' . $this->uid . '" has been modified, that is simply too much.', 1222871239);
252 }
253
254 if ($propertyName === NULL) {
255 foreach ($this->_getCleanProperties() as $propertyName => $cleanPropertyValue) {
256 if ($this->isPropertyDirty($cleanPropertyValue, $this->{$propertyName}) === TRUE) {
257 return TRUE;
258 }
259 }
260 } else {
261 if ($this->isPropertyDirty($this->_getCleanProperty($propertyName), $this->{$propertyName}) === TRUE) {
262 return TRUE;
263 }
264 }
265 return FALSE;
266 }
267
268 /**
269 * Checks the $value against the $cleanState.
270 *
271 * @param mixed $previousValue
272 * @param mixed $currentValue
273 * @return bool
274 */
275 protected function isPropertyDirty($previousValue, $currentValue) {
276 // In case it is an object and it implements the ObjectMonitoringInterface, we call _isDirty() instead of a simple comparison of objects.
277 // We do this, because if the object itself contains a lazy loaded property, the comparison of the objects might fail even if the object didn't change
278 if (is_object($currentValue)) {
279 if ($currentValue instanceof DomainObjectInterface) {
280 $result = !is_object($previousValue) || get_class($previousValue) !== get_class($currentValue) || $currentValue->getUid() !== $previousValue->getUid();
281 } elseif ($currentValue instanceof \TYPO3\CMS\Extbase\Persistence\ObjectMonitoringInterface) {
282 $result = !is_object($previousValue) || $currentValue->_isDirty() || get_class($previousValue) !== get_class($currentValue);
283 } else {
284 // For all other objects we do only a simple comparison (!=) as we want cloned objects to return the same values.
285 $result = $previousValue != $currentValue;
286 }
287 } else {
288 $result = $previousValue !== $currentValue;
289 }
290 return $result;
291 }
292
293 /**
294 * Returns TRUE if the object has been clonesd, cloned, FALSE otherwise.
295 *
296 * @return bool TRUE if the object has been cloned
297 */
298 public function _isClone() {
299 return $this->_isClone;
300 }
301
302 /**
303 * Setter whether this Domain Object is a clone of another one.
304 * NEVER SET THIS PROPERTY DIRECTLY. We currently need it to make the
305 * _isDirty check inside AbstractEntity work, but it is just a work-
306 * around right now.
307 *
308 * @param bool $clone
309 */
310 public function _setClone($clone) {
311 $this->_isClone = (bool)$clone;
312 }
313
314 /**
315 * Clone method. Sets the _isClone property.
316 *
317 * @return void
318 */
319 public function __clone() {
320 $this->_isClone = TRUE;
321 }
322
323 /**
324 * Returns the class name and the uid of the object as string
325 *
326 * @return string
327 */
328 public function __toString() {
329 return get_class($this) . ':' . (string)$this->uid;
330 }
331
332 }