|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de> 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * 00017 * This script is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU General Public License for more details. 00021 * 00022 * This copyright notice MUST APPEAR in all copies of the script! 00023 ***************************************************************/ 00024 00025 /** 00026 * A generic Domain Object. 00027 * 00028 * All Model domain objects need to inherit from either AbstractEntity or AbstractValueObject, as this provides important framework information. 00029 * 00030 * @package Extbase 00031 * @subpackage DomainObject 00032 * @version $ID:$ 00033 */ 00034 abstract class Tx_Extbase_DomainObject_AbstractDomainObject implements Tx_Extbase_DomainObject_DomainObjectInterface, Tx_Extbase_Persistence_ObjectMonitoringInterface { 00035 00036 /** 00037 * @var int The uid of the record. The uid is only unique in the context of the database table. 00038 */ 00039 protected $uid; 00040 00041 /** 00042 * @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). 00043 */ 00044 protected $_localizedUid; 00045 00046 /** 00047 * @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. 00048 */ 00049 protected $_languageUid; 00050 00051 /** 00052 * @var int The id of the page the record is "stored". 00053 */ 00054 protected $pid; 00055 00056 /** 00057 * TRUE if the object is a clone 00058 * @var boolean 00059 */ 00060 private $_isClone = FALSE; 00061 00062 /** 00063 * @var An array holding the clean property values. Set right after reconstitution of the object 00064 */ 00065 private $_cleanProperties; 00066 00067 /** 00068 * This is the magic __wakeup() method. It's invoked by the unserialize statement in the reconstitution process 00069 * of the object. If you want to implement your own __wakeup() method in your Domain Object you have to call 00070 * parent::__wakeup() first! 00071 * 00072 * @return void 00073 */ 00074 public function __wakeup() { 00075 $this->initializeObject(); 00076 } 00077 00078 public function initializeObject() { 00079 } 00080 00081 /** 00082 * Getter for uid. 00083 * 00084 * @return int the uid or NULL if none set yet. 00085 */ 00086 final public function getUid() { 00087 if ($this->uid !== NULL) { 00088 return (int)$this->uid; 00089 } else { 00090 return NULL; 00091 } 00092 } 00093 00094 /** 00095 * Setter for the pid. 00096 * 00097 * @return void 00098 */ 00099 public function setPid($pid) { 00100 if ($pid === NULL) { 00101 $this->pid = NULL; 00102 } else { 00103 $this->pid = (int)$pid; 00104 } 00105 } 00106 00107 /** 00108 * Getter for the pid. 00109 * 00110 * @return int The pid or NULL if none set yet. 00111 */ 00112 public function getPid() { 00113 if ($this->pid === NULL) { 00114 return NULL; 00115 } else { 00116 return (int)$this->pid; 00117 } 00118 } 00119 00120 /** 00121 * Reconstitutes a property. Only for internal use. 00122 * 00123 * @param string $propertyName 00124 * @param string $value 00125 * @return void 00126 */ 00127 public function _setProperty($propertyName, $propertyValue) { 00128 if ($this->_hasProperty($propertyName)) { 00129 $this->$propertyName = $propertyValue; 00130 return TRUE; 00131 } 00132 return FALSE; 00133 } 00134 00135 /** 00136 * Returns the property value of the given property name. Only for internal use. 00137 * 00138 * @return mixed The propertyValue 00139 */ 00140 public function _getProperty($propertyName) { 00141 return $this->$propertyName; 00142 } 00143 00144 /** 00145 * Returns a hash map of property names and property values. Only for internal use. 00146 * 00147 * @return array The properties 00148 */ 00149 public function _getProperties() { 00150 $properties = get_object_vars($this); 00151 foreach ($properties as $propertyName => $propertyValue) { 00152 if (substr($propertyName, 0, 1) === '_') { 00153 unset($properties[$propertyName]); 00154 } 00155 } 00156 return $properties; 00157 } 00158 00159 /** 00160 * Returns the property value of the given property name. Only for internal use. 00161 * 00162 * @return boolean TRUE bool true if the property exists, FALSE if it doesn't exist or 00163 * NULL in case of an error. 00164 */ 00165 public function _hasProperty($propertyName) { 00166 return property_exists($this, $propertyName); 00167 } 00168 00169 /** 00170 * Returns TRUE if the object is new (the uid was not set, yet). Only for internal use 00171 * 00172 * @return boolean 00173 */ 00174 public function _isNew() { 00175 return $this->uid === NULL; 00176 } 00177 00178 /** 00179 * Register an object's clean state, e.g. after it has been reconstituted 00180 * from the database. 00181 * 00182 * @param string $propertyName The name of the property to be memorized. If omitted all persistable properties are memorized. 00183 * @return void 00184 */ 00185 public function _memorizeCleanState($propertyName = NULL) { 00186 if ($propertyName !== NULL) { 00187 $this->_memorizePropertyCleanState($propertyName); 00188 } else { 00189 $this->_cleanProperties = array(); 00190 $properties = get_object_vars($this); 00191 foreach ($properties as $propertyName => $propertyValue) { 00192 if (substr($propertyName, 0, 1) === '_') continue; // Do not memorize "internal" properties 00193 $this->_memorizePropertyCleanState($propertyName); 00194 } 00195 } 00196 } 00197 00198 /** 00199 * Register an properties's clean state, e.g. after it has been reconstituted 00200 * from the database. 00201 * 00202 * @param string $propertyName The name of the property to be memorized. If omittet all persistable properties are memorized. 00203 * @return void 00204 */ 00205 public function _memorizePropertyCleanState($propertyName) { 00206 $propertyValue = $this->$propertyName; 00207 if (!is_array($this->_cleanProperties)) { 00208 $this->_cleanProperties = array(); 00209 } 00210 if (is_object($propertyValue)) { 00211 $this->_cleanProperties[$propertyName] = clone($propertyValue); 00212 00213 // We need to make sure the clone and the original object 00214 // are identical when compared with == (see _isDirty()). 00215 // After the cloning, the Domain Object will have the property 00216 // "isClone" set to TRUE, so we manually have to set it to FALSE 00217 // again. Possible fix: Somehow get rid of the "isClone" property, 00218 // which is currently needed in Fluid. 00219 if ($propertyValue instanceof Tx_Extbase_DomainObject_AbstractDomainObject) { 00220 $this->_cleanProperties[$propertyName]->_setClone(FALSE); 00221 } 00222 } else { 00223 $this->_cleanProperties[$propertyName] = $propertyValue; 00224 } 00225 } 00226 00227 /** 00228 * Returns a hash map of clean properties and $values. 00229 * 00230 * @return array 00231 */ 00232 public function _getCleanProperties() { 00233 return $this->_cleanProperties; 00234 } 00235 00236 /** 00237 * Returns the clean value of the given property. The returned value will be NULL if the clean state was not memorized before, or 00238 * if the clean value is NULL. 00239 * 00240 * @param string $propertyName The name of the property to be memorized. If omittet all persistable properties are memorized. 00241 * @return mixed The clean property value or NULL 00242 */ 00243 public function _getCleanProperty($propertyName) { 00244 if (is_array($this->_cleanProperties)) { 00245 return isset($this->_cleanProperties[$propertyName]) ? $this->_cleanProperties[$propertyName] : NULL; 00246 } else { 00247 return NULL; 00248 } 00249 } 00250 00251 /** 00252 * Returns TRUE if the properties were modified after reconstitution 00253 * 00254 * @param string $propertyName An optional name of a property to be checked if its value is dirty 00255 * @return boolean 00256 */ 00257 public function _isDirty($propertyName = NULL) { 00258 if ($this->uid !== NULL && is_array($this->_cleanProperties) && $this->uid != $this->_getCleanProperty('uid')) throw new Tx_Extbase_Persistence_Exception_TooDirty('The uid "' . $this->uid . '" has been modified, that is simply too much.', 1222871239); 00259 if ($propertyName === NULL) { 00260 foreach ($this->_getCleanProperties() as $propertyName => $cleanPropertyValue) { 00261 if ($this->isPropertyDirty($cleanPropertyValue, $this->$propertyName) === TRUE) return TRUE; 00262 } 00263 } else { 00264 if ($this->isPropertyDirty($this->_getCleanProperty($propertyName), $this->$propertyName) === TRUE) return TRUE; 00265 } 00266 return FALSE; 00267 } 00268 00269 /** 00270 * Checks the $value against the $cleanState. 00271 * 00272 * @param mixed $previousValue 00273 * @param mixed $currentValue 00274 * @return boolan 00275 */ 00276 protected function isPropertyDirty($previousValue, $currentValue) { 00277 $result = FALSE; 00278 // In case it is an object and it implements the ObjectMonitoringInterface, we call _isDirty() instead of a simple comparison of objects. 00279 // 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 00280 if (is_object($currentValue)) { 00281 if ($currentValue instanceof Tx_Extbase_DomainObject_DomainObjectInterface) { 00282 $result = !is_object($previousValue) || (get_class($previousValue) !== get_class($currentValue)) || ($currentValue->getUid() !== $previousValue->getUid()); 00283 } elseif ($currentValue instanceof Tx_Extbase_Persistence_ObjectMonitoringInterface) { 00284 $result = !is_object($previousValue) || $currentValue->_isDirty() || (get_class($previousValue) !== get_class($currentValue)); 00285 } else { 00286 // For all other objects we do only a simple comparison (!=) as we want cloned objects to return the same values. 00287 $result = ($previousValue != $currentValue); 00288 } 00289 } else { 00290 $result = ($previousValue !== $currentValue); 00291 } 00292 return $result; 00293 } 00294 00295 /** 00296 * Returns TRUE if the object has been clonesd, cloned, FALSE otherwise. 00297 * 00298 * @return boolean TRUE if the object has been cloned 00299 */ 00300 public function _isClone() { 00301 return $this->_isClone; 00302 } 00303 00304 /** 00305 * Setter whether this Domain Object is a clone of another one. 00306 * NEVER SET THIS PROPERTY DIRECTLY. We currently need it to make the 00307 * _isDirty check inside AbstractEntity work, but it is just a work- 00308 * around right now. 00309 * 00310 * @param boolean $clone 00311 */ 00312 public function _setClone($clone) { 00313 $this->_isClone = (boolean)$clone; 00314 } 00315 00316 /** 00317 * Clone method. Sets the _isClone property. 00318 * 00319 * @return void 00320 */ 00321 public function __clone() { 00322 $this->_isClone = TRUE; 00323 } 00324 00325 /** 00326 * Returns the class name and the uid of the object as string 00327 * 00328 * @return string 00329 */ 00330 public function __toString() { 00331 return get_class($this) . ':' . (string)$this->uid; 00332 } 00333 00334 } 00335 ?>
1.8.0