|
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 class is a backport of the corresponding class of FLOW3. 00009 * All credits go to the v5 team. 00010 * 00011 * This script is part of the TYPO3 project. The TYPO3 project is 00012 * free software; you can redistribute it and/or modify 00013 * it under the terms of the GNU General Public License as published by 00014 * the Free Software Foundation; either version 2 of the License, or 00015 * (at your option) any later version. 00016 * 00017 * The GNU General Public License can be found at 00018 * http://www.gnu.org/copyleft/gpl.html. 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00027 00028 /** 00029 * The base repository - will usually be extended by a more concrete repository. 00030 * 00031 * @package Extbase 00032 * @subpackage Persistence 00033 * @version $ID:$ 00034 * @api 00035 */ 00036 class Tx_Extbase_Persistence_Repository implements Tx_Extbase_Persistence_RepositoryInterface, t3lib_Singleton { 00037 00038 /** 00039 * @var Tx_Extbase_Persistence_IdentityMap 00040 **/ 00041 protected $identityMap; 00042 00043 /** 00044 * Objects of this repository 00045 * 00046 * @var Tx_Extbase_Persistence_ObjectStorage 00047 */ 00048 protected $addedObjects; 00049 00050 /** 00051 * Objects removed but not found in $this->addedObjects at removal time 00052 * 00053 * @var Tx_Extbase_Persistence_ObjectStorage 00054 */ 00055 protected $removedObjects; 00056 00057 /** 00058 * @var Tx_Extbase_Persistence_QueryFactoryInterface 00059 */ 00060 protected $queryFactory; 00061 00062 /** 00063 * @var Tx_Extbase_Persistence_ManagerInterface 00064 */ 00065 protected $persistenceManager; 00066 00067 /** 00068 * @var Tx_Extbase_Object_ObjectManagerInterface 00069 */ 00070 protected $objectManager; 00071 00072 /** 00073 * @var string 00074 */ 00075 protected $objectType; 00076 00077 /** 00078 * @var array 00079 */ 00080 protected $defaultOrderings = array(); 00081 00082 /** 00083 * @var Tx_Extbase_Persistence_QuerySettingsInterface 00084 */ 00085 protected $defaultQuerySettings = NULL; 00086 00087 /** 00088 * Constructs a new Repository 00089 * 00090 * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager 00091 */ 00092 public function __construct(Tx_Extbase_Object_ObjectManagerInterface $objectManager = NULL) { 00093 $this->addedObjects = new Tx_Extbase_Persistence_ObjectStorage(); 00094 $this->removedObjects = new Tx_Extbase_Persistence_ObjectStorage(); 00095 $this->objectType = str_replace(array('_Repository_', 'Repository'), array('_Model_', ''), $this->getRepositoryClassName()); 00096 00097 if ($objectManager === NULL) { 00098 // Legacy creation, in case the object manager is NOT injected 00099 // If ObjectManager IS there, then all properties are automatically injected 00100 $this->objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_ObjectManager'); 00101 $this->injectIdentityMap($this->objectManager->get('Tx_Extbase_Persistence_IdentityMap')); 00102 $this->injectQueryFactory($this->objectManager->get('Tx_Extbase_Persistence_QueryFactory')); 00103 $this->injectPersistenceManager($this->objectManager->get('Tx_Extbase_Persistence_Manager')); 00104 } else { 00105 $this->objectManager = $objectManager; 00106 } 00107 } 00108 00109 /** 00110 * @param Tx_Extbase_Persistence_IdentityMap $identityMap 00111 * @return void 00112 */ 00113 public function injectIdentityMap(Tx_Extbase_Persistence_IdentityMap $identityMap) { 00114 $this->identityMap = $identityMap; 00115 } 00116 00117 /** 00118 * @param Tx_Extbase_Persistence_QueryFactory $queryFactory 00119 * @return void 00120 */ 00121 public function injectQueryFactory(Tx_Extbase_Persistence_QueryFactory $queryFactory) { 00122 $this->queryFactory = $queryFactory; 00123 } 00124 00125 /** 00126 * @param Tx_Extbase_Persistence_ManagerInterface $persistenceManager 00127 * @return void 00128 */ 00129 public function injectPersistenceManager(Tx_Extbase_Persistence_ManagerInterface $persistenceManager) { 00130 $this->persistenceManager = $persistenceManager; 00131 $this->persistenceManager->registerRepositoryClassName($this->getRepositoryClassName()); 00132 } 00133 00134 /** 00135 * Adds an object to this repository 00136 * 00137 * @param object $object The object to add 00138 * @return void 00139 * @api 00140 */ 00141 public function add($object) { 00142 if (!($object instanceof $this->objectType)) { 00143 throw new Tx_Extbase_Persistence_Exception_IllegalObjectType('The object given to add() was not of the type (' . $this->objectType . ') this repository manages.', 1248363335); 00144 } 00145 00146 $this->addedObjects->attach($object); 00147 00148 if ($this->removedObjects->contains($object)) { 00149 $this->removedObjects->detach($object); 00150 } 00151 } 00152 00153 /** 00154 * Removes an object from this repository. 00155 * 00156 * @param object $object The object to remove 00157 * @return void 00158 * @api 00159 */ 00160 public function remove($object) { 00161 if (!($object instanceof $this->objectType)) { 00162 throw new Tx_Extbase_Persistence_Exception_IllegalObjectType('The object given to remove() was not of the type (' . $this->objectType . ') this repository manages.', 1248363335); 00163 } 00164 00165 if ($this->addedObjects->contains($object)) { 00166 $this->addedObjects->detach($object); 00167 } 00168 00169 if (!$object->_isNew()) { 00170 $this->removedObjects->attach($object); 00171 } 00172 } 00173 00174 /** 00175 * Replaces an object by another. 00176 * 00177 * @param object $existingObject The existing object 00178 * @param object $newObject The new object 00179 * @return void 00180 * @api 00181 */ 00182 public function replace($existingObject, $newObject) { 00183 if (!($existingObject instanceof $this->objectType)) { 00184 throw new Tx_Extbase_Persistence_Exception_IllegalObjectType('The existing object given to replace was not of the type (' . $this->objectType . ') this repository manages.', 1248363434); 00185 } 00186 if (!($newObject instanceof $this->objectType)) { 00187 throw new Tx_Extbase_Persistence_Exception_IllegalObjectType('The new object given to replace was not of the type (' . $this->objectType . ') this repository manages.', 1248363439); 00188 } 00189 00190 $backend = $this->persistenceManager->getBackend(); 00191 $session = $this->persistenceManager->getSession(); 00192 $uuid = $backend->getIdentifierByObject($existingObject); 00193 if ($uuid !== NULL) { 00194 $backend->replaceObject($existingObject, $newObject); 00195 $session->unregisterReconstitutedObject($existingObject); 00196 $session->registerReconstitutedObject($newObject); 00197 00198 if ($this->removedObjects->contains($existingObject)) { 00199 $this->removedObjects->detach($existingObject); 00200 $this->removedObjects->attach($newObject); 00201 } 00202 } elseif ($this->addedObjects->contains($existingObject)) { 00203 $this->addedObjects->detach($existingObject); 00204 $this->addedObjects->attach($newObject); 00205 } else { 00206 throw new Tx_Extbase_Persistence_Exception_UnknownObject('The "existing object" is unknown to the persistence backend.', 1238068475); 00207 } 00208 00209 } 00210 00211 /** 00212 * Replaces an existing object with the same identifier by the given object 00213 * 00214 * @param object $modifiedObject The modified object 00215 * @api 00216 */ 00217 public function update($modifiedObject) { 00218 if (!($modifiedObject instanceof $this->objectType)) { 00219 throw new Tx_Extbase_Persistence_Exception_IllegalObjectType('The modified object given to update() was not of the type (' . $this->objectType . ') this repository manages.', 1249479625); 00220 } 00221 00222 $uid = $modifiedObject->getUid(); 00223 if ($uid !== NULL) { 00224 $existingObject = $this->findByUid($uid); 00225 $this->replace($existingObject, $modifiedObject); 00226 } else { 00227 throw new Tx_Extbase_Persistence_Exception_UnknownObject('The "modified object" is does not have an existing counterpart in this repository.', 1249479819); 00228 } 00229 } 00230 00231 /** 00232 * Returns all addedObjects that have been added to this repository with add(). 00233 * 00234 * This is a service method for the persistence manager to get all addedObjects 00235 * added to the repository. Those are only objects *added*, not objects 00236 * fetched from the underlying storage. 00237 * 00238 * @return Tx_Extbase_Persistence_ObjectStorage the objects 00239 */ 00240 public function getAddedObjects() { 00241 return $this->addedObjects; 00242 } 00243 00244 /** 00245 * Returns an Tx_Extbase_Persistence_ObjectStorage with objects remove()d from the repository 00246 * that had been persisted to the storage layer before. 00247 * 00248 * @return Tx_Extbase_Persistence_ObjectStorage the objects 00249 */ 00250 public function getRemovedObjects() { 00251 return $this->removedObjects; 00252 } 00253 00254 /** 00255 * Returns all objects of this repository 00256 * 00257 * @return array An array of objects, empty if no objects found 00258 * @api 00259 */ 00260 public function findAll() { 00261 $result = $this->createQuery()->execute(); 00262 return $result; 00263 } 00264 00265 /** 00266 * Returns the total number objects of this repository. 00267 * 00268 * @return integer The object count 00269 * @api 00270 */ 00271 public function countAll() { 00272 return $this->createQuery()->execute()->count(); 00273 } 00274 00275 /** 00276 * Removes all objects of this repository as if remove() was called for 00277 * all of them. 00278 * 00279 * @return void 00280 * @api 00281 */ 00282 public function removeAll() { 00283 $this->addedObjects = new Tx_Extbase_Persistence_ObjectStorage(); 00284 foreach ($this->findAll() as $object) { 00285 $this->remove($object); 00286 } 00287 } 00288 00289 /** 00290 * Finds an object matching the given identifier. 00291 * 00292 * @param int $uid The identifier of the object to find 00293 * @return object The matching object if found, otherwise NULL 00294 * @api 00295 */ 00296 public function findByUid($uid) { 00297 if ($this->identityMap->hasIdentifier($uid, $this->objectType)) { 00298 $object = $this->identityMap->getObjectByIdentifier($uid, $this->objectType); 00299 } else { 00300 $query = $this->createQuery(); 00301 $query->getQuerySettings()->setRespectSysLanguage(FALSE); 00302 $query->getQuerySettings()->setRespectStoragePage(FALSE); 00303 $object = $query 00304 ->matching( 00305 $query->equals('uid', $uid) 00306 ) 00307 ->execute() 00308 ->getFirst(); 00309 if ($object !== NULL) { 00310 $this->identityMap->registerObject($object, $uid); 00311 } 00312 } 00313 return $object; 00314 } 00315 00316 /** 00317 * Sets the property names to order the result by per default. 00318 * Expected like this: 00319 * array( 00320 * 'foo' => Tx_Extbase_Persistence_QueryInterface::ORDER_ASCENDING, 00321 * 'bar' => Tx_Extbase_Persistence_QueryInterface::ORDER_DESCENDING 00322 * ) 00323 * 00324 * @param array $defaultOrderings The property names to order by 00325 * @return void 00326 * @api 00327 */ 00328 public function setDefaultOrderings(array $defaultOrderings) { 00329 $this->defaultOrderings = $defaultOrderings; 00330 } 00331 00332 /** 00333 * Sets the default query settings to be used in this repository 00334 * 00335 * @param Tx_Extbase_Persistence_QuerySettingsInterface $defaultQuerySettings The query settings to be used by default 00336 * @return void 00337 * @api 00338 */ 00339 public function setDefaultQuerySettings(Tx_Extbase_Persistence_QuerySettingsInterface $defaultQuerySettings) { 00340 $this->defaultQuerySettings = $defaultQuerySettings; 00341 } 00342 00343 /** 00344 * Returns a query for objects of this repository 00345 * 00346 * @return Tx_Extbase_Persistence_QueryInterface 00347 * @api 00348 */ 00349 public function createQuery() { 00350 $query = $this->queryFactory->create($this->objectType); 00351 if ($this->defaultOrderings !== array()) { 00352 $query->setOrderings($this->defaultOrderings); 00353 } 00354 if ($this->defaultQuerySettings !== NULL) { 00355 $query->setQuerySettings($this->defaultQuerySettings); 00356 } 00357 return $query; 00358 } 00359 00360 /** 00361 * Dispatches magic methods (findBy[Property]()) 00362 * 00363 * @param string $methodName The name of the magic method 00364 * @param string $arguments The arguments of the magic method 00365 * @throws Tx_Extbase_Persistence_Exception_UnsupportedMethod 00366 * @return void 00367 * @api 00368 */ 00369 public function __call($methodName, $arguments) { 00370 if (substr($methodName, 0, 6) === 'findBy' && strlen($methodName) > 7) { 00371 $propertyName = strtolower(substr(substr($methodName, 6), 0, 1) ) . substr(substr($methodName, 6), 1); 00372 $query = $this->createQuery(); 00373 $result = $query->matching($query->equals($propertyName, $arguments[0])) 00374 ->execute(); 00375 return $result; 00376 } elseif (substr($methodName, 0, 9) === 'findOneBy' && strlen($methodName) > 10) { 00377 $propertyName = strtolower(substr(substr($methodName, 9), 0, 1) ) . substr(substr($methodName, 9), 1); 00378 $query = $this->createQuery(); 00379 $object = $query->matching($query->equals($propertyName, $arguments[0])) 00380 ->setLimit(1) 00381 ->execute() 00382 ->getFirst(); 00383 return $object; 00384 } elseif (substr($methodName, 0, 7) === 'countBy' && strlen($methodName) > 8) { 00385 $propertyName = strtolower(substr(substr($methodName, 7), 0, 1) ) . substr(substr($methodName, 7), 1); 00386 $query = $this->createQuery(); 00387 $result = $query->matching($query->equals($propertyName, $arguments[0])) 00388 ->execute() 00389 ->count(); 00390 return $result; 00391 } 00392 throw new Tx_Extbase_Persistence_Exception_UnsupportedMethod('The method "' . $methodName . '" is not supported by the repository.', 1233180480); 00393 } 00394 00395 /** 00396 * Returns the class name of this class. 00397 * 00398 * @return string Class name of the repository. 00399 */ 00400 protected function getRepositoryClassName() { 00401 return get_class($this); 00402 } 00403 00404 } 00405 ?>
1.8.0