TYPO3 CMS  TYPO3_8-7
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 
68  public function getUid()
69  {
70  if ($this->uid !== null) {
71  return (int)$this->uid;
72  }
73  return null;
74  }
75 
81  public function setPid($pid)
82  {
83  if ($pid === null) {
84  $this->pid = null;
85  } else {
86  $this->pid = (int)$pid;
87  }
88  }
89 
95  public function getPid()
96  {
97  if ($this->pid === null) {
98  return null;
99  }
100  return (int)$this->pid;
101  }
102 
110  public function _setProperty($propertyName, $propertyValue)
111  {
112  if ($this->_hasProperty($propertyName)) {
113  $this->{$propertyName} = $propertyValue;
114  return true;
115  }
116  return false;
117  }
118 
125  public function _getProperty($propertyName)
126  {
127  return $this->{$propertyName};
128  }
129 
135  public function _getProperties()
136  {
137  $properties = get_object_vars($this);
138  foreach ($properties as $propertyName => $propertyValue) {
139  if ($propertyName[0] === '_') {
140  unset($properties[$propertyName]);
141  }
142  }
143  return $properties;
144  }
145 
152  public function _hasProperty($propertyName)
153  {
154  return property_exists($this, $propertyName);
155  }
156 
162  public function _isNew()
163  {
164  return $this->uid === null;
165  }
166 
173  public function _memorizeCleanState($propertyName = null)
174  {
175  if ($propertyName !== null) {
176  $this->_memorizePropertyCleanState($propertyName);
177  } else {
178  $this->_cleanProperties = [];
179  $properties = get_object_vars($this);
180  foreach ($properties as $propertyName => $propertyValue) {
181  if ($propertyName[0] === '_') {
182  continue;
183  }
184  // Do not memorize "internal" properties
185  $this->_memorizePropertyCleanState($propertyName);
186  }
187  }
188  }
189 
196  public function _memorizePropertyCleanState($propertyName)
197  {
198  $propertyValue = $this->{$propertyName};
199  if (is_object($propertyValue)) {
200  $this->_cleanProperties[$propertyName] = clone $propertyValue;
201  // We need to make sure the clone and the original object
202  // are identical when compared with == (see _isDirty()).
203  // After the cloning, the Domain Object will have the property
204  // "isClone" set to TRUE, so we manually have to set it to FALSE
205  // again. Possible fix: Somehow get rid of the "isClone" property,
206  // which is currently needed in Fluid.
207  if ($propertyValue instanceof \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject) {
208  $this->_cleanProperties[$propertyName]->_setClone(false);
209  }
210  } else {
211  $this->_cleanProperties[$propertyName] = $propertyValue;
212  }
213  }
214 
220  public function _getCleanProperties()
221  {
223  }
224 
232  public function _getCleanProperty($propertyName)
233  {
234  return isset($this->_cleanProperties[$propertyName]) ? $this->_cleanProperties[$propertyName] : null;
235  }
236 
244  public function _isDirty($propertyName = null)
245  {
246  if ($this->uid !== null && $this->_getCleanProperty('uid') !== null && $this->uid != $this->_getCleanProperty('uid')) {
247  throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\TooDirtyException('The uid "' . $this->uid . '" has been modified, that is simply too much.', 1222871239);
248  }
249 
250  if ($propertyName === null) {
251  foreach ($this->_getCleanProperties() as $propertyName => $cleanPropertyValue) {
252  if ($this->isPropertyDirty($cleanPropertyValue, $this->{$propertyName}) === true) {
253  return true;
254  }
255  }
256  } else {
257  if ($this->isPropertyDirty($this->_getCleanProperty($propertyName), $this->{$propertyName}) === true) {
258  return true;
259  }
260  }
261  return false;
262  }
263 
271  protected function isPropertyDirty($previousValue, $currentValue)
272  {
273  // In case it is an object and it implements the ObjectMonitoringInterface, we call _isDirty() instead of a simple comparison of objects.
274  // 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
275  if (is_object($currentValue)) {
276  $currentTypeString = null;
277  if ($currentValue instanceof LazyLoadingProxy) {
278  $currentTypeString = $currentValue->_getTypeAndUidString();
279  } elseif ($currentValue instanceof DomainObjectInterface) {
280  $currentTypeString = get_class($currentValue) . ':' . $currentValue->getUid();
281  }
282 
283  if ($currentTypeString !== null) {
284  $previousTypeString = null;
285  if ($previousValue instanceof LazyLoadingProxy) {
286  $previousTypeString = $previousValue->_getTypeAndUidString();
287  } elseif ($previousValue instanceof DomainObjectInterface) {
288  $previousTypeString = get_class($previousValue) . ':' . $previousValue->getUid();
289  }
290 
291  $result = $currentTypeString !== $previousTypeString;
292  } elseif ($currentValue instanceof \TYPO3\CMS\Extbase\Persistence\ObjectMonitoringInterface) {
293  $result = !is_object($previousValue) || $currentValue->_isDirty() || get_class($previousValue) !== get_class($currentValue);
294  } else {
295  // For all other objects we do only a simple comparison (!=) as we want cloned objects to return the same values.
296  $result = $previousValue != $currentValue;
297  }
298  } else {
299  $result = $previousValue !== $currentValue;
300  }
301  return $result;
302  }
303 
309  public function _isClone()
310  {
311  return $this->_isClone;
312  }
313 
322  public function _setClone($clone)
323  {
324  $this->_isClone = (bool)$clone;
325  }
326 
330  public function __clone()
331  {
332  $this->_isClone = true;
333  }
334 
340  public function __toString()
341  {
342  return get_class($this) . ':' . (string)$this->uid;
343  }
344 }