TYPO3 CMS  TYPO3_7-6
AbstractDomainObject.php
Go to the documentation of this file.
1 <?php
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 
18 
25 {
29  protected $uid;
30 
34  protected $_localizedUid;
35 
39  protected $_languageUid;
40 
44  protected $_versionedUid;
45 
49  protected $pid;
50 
56  private $_isClone = false;
57 
61  private $_cleanProperties = [];
62 
71  public function __wakeup()
72  {
74  }
75 
81  public function getUid()
82  {
83  if ($this->uid !== null) {
84  return (int)$this->uid;
85  } else {
86  return null;
87  }
88  }
89 
96  public function setPid($pid)
97  {
98  if ($pid === null) {
99  $this->pid = null;
100  } else {
101  $this->pid = (int)$pid;
102  }
103  }
104 
110  public function getPid()
111  {
112  if ($this->pid === null) {
113  return null;
114  } else {
115  return (int)$this->pid;
116  }
117  }
118 
126  public function _setProperty($propertyName, $propertyValue)
127  {
128  if ($this->_hasProperty($propertyName)) {
129  $this->{$propertyName} = $propertyValue;
130  return true;
131  }
132  return false;
133  }
134 
141  public function _getProperty($propertyName)
142  {
143  return $this->{$propertyName};
144  }
145 
151  public function _getProperties()
152  {
153  $properties = get_object_vars($this);
154  foreach ($properties as $propertyName => $propertyValue) {
155  if ($propertyName[0] === '_') {
156  unset($properties[$propertyName]);
157  }
158  }
159  return $properties;
160  }
161 
168  public function _hasProperty($propertyName)
169  {
170  return property_exists($this, $propertyName);
171  }
172 
178  public function _isNew()
179  {
180  return $this->uid === null;
181  }
182 
190  public function _memorizeCleanState($propertyName = null)
191  {
192  if ($propertyName !== null) {
193  $this->_memorizePropertyCleanState($propertyName);
194  } else {
195  $this->_cleanProperties = [];
196  $properties = get_object_vars($this);
197  foreach ($properties as $propertyName => $propertyValue) {
198  if ($propertyName[0] === '_') {
199  continue;
200  }
201  // Do not memorize "internal" properties
202  $this->_memorizePropertyCleanState($propertyName);
203  }
204  }
205  }
206 
214  public function _memorizePropertyCleanState($propertyName)
215  {
216  $propertyValue = $this->{$propertyName};
217  if (is_object($propertyValue)) {
218  $this->_cleanProperties[$propertyName] = clone $propertyValue;
219  // We need to make sure the clone and the original object
220  // are identical when compared with == (see _isDirty()).
221  // After the cloning, the Domain Object will have the property
222  // "isClone" set to TRUE, so we manually have to set it to FALSE
223  // again. Possible fix: Somehow get rid of the "isClone" property,
224  // which is currently needed in Fluid.
225  if ($propertyValue instanceof \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject) {
226  $this->_cleanProperties[$propertyName]->_setClone(false);
227  }
228  } else {
229  $this->_cleanProperties[$propertyName] = $propertyValue;
230  }
231  }
232 
238  public function _getCleanProperties()
239  {
241  }
242 
250  public function _getCleanProperty($propertyName)
251  {
252  return isset($this->_cleanProperties[$propertyName]) ? $this->_cleanProperties[$propertyName] : null;
253  }
254 
262  public function _isDirty($propertyName = null)
263  {
264  if ($this->uid !== null && $this->_getCleanProperty('uid') !== null && $this->uid != $this->_getCleanProperty('uid')) {
265  throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\TooDirtyException('The uid "' . $this->uid . '" has been modified, that is simply too much.', 1222871239);
266  }
267 
268  if ($propertyName === null) {
269  foreach ($this->_getCleanProperties() as $propertyName => $cleanPropertyValue) {
270  if ($this->isPropertyDirty($cleanPropertyValue, $this->{$propertyName}) === true) {
271  return true;
272  }
273  }
274  } else {
275  if ($this->isPropertyDirty($this->_getCleanProperty($propertyName), $this->{$propertyName}) === true) {
276  return true;
277  }
278  }
279  return false;
280  }
281 
289  protected function isPropertyDirty($previousValue, $currentValue)
290  {
291  // In case it is an object and it implements the ObjectMonitoringInterface, we call _isDirty() instead of a simple comparison of objects.
292  // 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
293  if (is_object($currentValue)) {
294  if ($currentValue instanceof DomainObjectInterface) {
295  $result = !is_object($previousValue) || get_class($previousValue) !== get_class($currentValue) || $currentValue->getUid() !== $previousValue->getUid();
296  } elseif ($currentValue instanceof \TYPO3\CMS\Extbase\Persistence\ObjectMonitoringInterface) {
297  $result = !is_object($previousValue) || $currentValue->_isDirty() || get_class($previousValue) !== get_class($currentValue);
298  } else {
299  // For all other objects we do only a simple comparison (!=) as we want cloned objects to return the same values.
300  $result = $previousValue != $currentValue;
301  }
302  } else {
303  $result = $previousValue !== $currentValue;
304  }
305  return $result;
306  }
307 
313  public function _isClone()
314  {
315  return $this->_isClone;
316  }
317 
326  public function _setClone($clone)
327  {
328  $this->_isClone = (bool)$clone;
329  }
330 
336  public function __clone()
337  {
338  $this->_isClone = true;
339  }
340 
346  public function __toString()
347  {
348  return get_class($this) . ':' . (string)$this->uid;
349  }
350 }