[!!!][~TASK] Extbase (Utility): Moved configureDispatcher() and registerPlugin()...
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Persistence / Repository.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
6 * All rights reserved
7 *
8 * This class is a backport of the corresponding class of FLOW3.
9 * All credits go to the v5 team.
10 *
11 * This script is part of the TYPO3 project. The TYPO3 project is
12 * free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27
28 /**
29 * The base repository - will usually be extended by a more concrete repository.
30 *
31 * @package Extbase
32 * @subpackage Persistence
33 * @version $ID:$
34 */
35 class Tx_Extbase_Persistence_Repository implements Tx_Extbase_Persistence_RepositoryInterface, t3lib_Singleton {
36
37 /**
38 * Objects of this repository
39 *
40 * @var Tx_Extbase_Persistence_ObjectStorage
41 */
42 protected $addedObjects;
43
44 /**
45 * Objects removed but not found in $this->addedObjects at removal time
46 *
47 * @var Tx_Extbase_Persistence_ObjectStorage
48 */
49 protected $removedObjects;
50
51 /**
52 * @var Tx_Extbase_Persistence_QueryFactoryInterface
53 */
54 protected $queryFactory;
55
56 /**
57 * @var Tx_Extbase_Persistence_ManagerInterface
58 */
59 protected $persistenceManager;
60
61 /**
62 * @var string
63 */
64 protected $objectType;
65
66 /**
67 * Constructs a new Repository
68 *
69 */
70 public function __construct() {
71 $this->addedObjects = new Tx_Extbase_Persistence_ObjectStorage();
72 $this->removedObjects = new Tx_Extbase_Persistence_ObjectStorage();
73 $this->queryFactory = t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryFactory'); // singleton
74 $this->persistenceManager = Tx_Extbase_Dispatcher::getPersistenceManager();
75 $this->persistenceManager->registerRepositoryClassName(get_class($this));
76 $this->objectType = str_replace(array('_Repository_', 'Repository'), array('_Model_', ''), $this->getRepositoryClassName());
77 }
78
79 /**
80 * Adds an object to this repository
81 *
82 * @param object $object The object to add
83 * @return void
84 * @api
85 */
86 public function add($object) {
87 if (!($object instanceof $this->objectType)) {
88 throw new Tx_Extbase_Persistence_Exception_IllegalObjectType('The object given to add() was not of the type (' . $this->objectType . ') this repository manages.', 1248363335);
89 }
90
91 $this->addedObjects->attach($object);
92 $this->removedObjects->detach($object);
93 }
94
95 /**
96 * Removes an object from this repository.
97 *
98 * @param object $object The object to remove
99 * @return void
100 * @api
101 */
102 public function remove($object) {
103 if (!($object instanceof $this->objectType)) {
104 throw new Tx_Extbase_Persistence_Exception_IllegalObjectType('The object given to add() was not of the type (' . $this->objectType . ') this repository manages.', 1248363335);
105 }
106
107 if ($this->addedObjects->contains($object)) {
108 $this->addedObjects->detach($object);
109 } else {
110 $this->removedObjects->attach($object);
111 }
112 }
113
114 /**
115 * Replaces an object by another.
116 *
117 * @param object $existingObject The existing object
118 * @param object $newObject The new object
119 * return void
120 * @api
121 */
122 public function replace($existingObject, $newObject) {
123 if (!($existingObject instanceof $this->objectType)) {
124 throw new Tx_Extbase_Persistence_Exception_IllegalObjectType('The existing object given to replace was not of the type (' . $this->objectType . ') this repository manages.', 1248363434);
125 }
126 if (!($newObject instanceof $this->objectType)) {
127 throw new Tx_Extbase_Persistence_Exception_IllegalObjectType('The new object given to replace was not of the type (' . $this->objectType . ') this repository manages.', 1248363439);
128 }
129
130 $backend = $this->persistenceManager->getBackend();
131 $session = $this->persistenceManager->getSession();
132 $uuid = $backend->getIdentifierByObject($existingObject);
133 if ($uuid !== NULL) {
134 $backend->replaceObject($existingObject, $newObject);
135 $session->unregisterReconstitutedObject($existingObject);
136 $session->registerReconstitutedObject($newObject);
137
138 if ($this->removedObjects->contains($existingObject)) {
139 $this->removedObjects->detach($existingObject);
140 $this->removedObjects->attach($newObject);
141 }
142 } elseif ($this->addedObjects->contains($existingObject)) {
143 $this->addedObjects->detach($existingObject);
144 $this->addedObjects->attach($newObject);
145 } else {
146 throw new Tx_Extbase_Persistence_Exception_UnknownObject('The "existing object" is unknown to the persistence backend.', 1238068475);
147 }
148
149 }
150
151 /**
152 * Replaces an existing object with the same identifier by the given object
153 *
154 * @param object $modifiedObject The modified object
155 * @api
156 */
157 public function update($modifiedObject) {
158 if (!($modifiedObject instanceof $this->objectType)) {
159 throw new Tx_Extbase_Persistence_Exception_IllegalObjectType('The modified object given to update() was not of the type (' . $this->objectType . ') this repository manages.', 1249479625);
160 }
161
162 $uid = $modifiedObject->getUid();
163 if ($uid !== NULL) {
164 $existingObject = $this->findByUid($uid);
165 $this->replace($existingObject, $modifiedObject);
166 } else {
167 throw new Tx_Extbase_Persistence_Exception_UnknownObject('The "modified object" is does not have an existing counterpart in this repository.', 1249479819);
168 }
169 }
170
171 /**
172 * Returns all addedObjects that have been added to this repository with add().
173 *
174 * This is a service method for the persistence manager to get all addedObjects
175 * added to the repository. Those are only objects *added*, not objects
176 * fetched from the underlying storage.
177 *
178 * @return Tx_Extbase_Persistence_ObjectStorage the objects
179 */
180 public function getAddedObjects() {
181 return $this->addedObjects;
182 }
183
184 /**
185 * Returns an Tx_Extbase_Persistence_ObjectStorage with objects remove()d from the repository
186 * that had been persisted to the storage layer before.
187 *
188 * @return Tx_Extbase_Persistence_ObjectStorage the objects
189 */
190 public function getRemovedObjects() {
191 return $this->removedObjects;
192 }
193
194 /**
195 * Returns all objects of this repository
196 *
197 * @return array An array of objects, empty if no objects found
198 * @api
199 */
200 public function findAll() {
201 $result = $this->createQuery()->execute();
202 return $result;
203 }
204
205 /**
206 * Finds an object matching the given identifier.
207 *
208 * @param int $uid The identifier of the object to find
209 * @return object The matching object if found, otherwise NULL
210 * @api
211 */
212 public function findByUid($uid) {
213 if (!is_int($uid) || $uid < 0) throw new InvalidArgumentException('The uid must be a positive integer', 1245071889);
214 $query = $this->createQuery();
215 $result = $query->matching($query->withUid($uid))->execute();
216 $object = NULL;
217 if (count($result) > 0) {
218 $object = current($result);
219 }
220 return $object;
221 }
222
223 /**
224 * Returns a query for objects of this repository
225 *
226 * @param boolean $useStoragePageId If FALSE, will NOT add pid=... to the query. TRUE by default. Only change if you know what you are doing.
227 * @return Tx_Extbase_Persistence_QueryInterface
228 * @api
229 */
230 public function createQuery() {
231 return $this->queryFactory->create($this->objectType);
232 }
233
234 /**
235 * Dispatches magic methods (findBy[Property]())
236 *
237 * @param string $methodName The name of the magic method
238 * @param string $arguments The arguments of the magic method
239 * @throws Tx_Extbase_Persistence_Exception_UnsupportedMethod
240 * @return void
241 * @api
242 */
243 public function __call($methodName, $arguments) {
244 if (substr($methodName, 0, 6) === 'findBy' && strlen($methodName) > 7) {
245 $propertyName = strtolower(substr(substr($methodName, 6), 0, 1) ) . substr(substr($methodName, 6), 1);
246 $query = $this->createQuery();
247 $result = $query->matching($query->equals($propertyName, $arguments[0]))
248 ->execute();
249 return $result;
250 } elseif (substr($methodName, 0, 9) === 'findOneBy' && strlen($methodName) > 10) {
251 $propertyName = strtolower(substr(substr($methodName, 9), 0, 1) ) . substr(substr($methodName, 9), 1);
252 $query = $this->createQuery();
253 $result = $query->matching($query->equals($propertyName, $arguments[0]))
254 ->setLimit(1)
255 ->execute();
256 $object = NULL;
257 if (count($result) > 0) {
258 $object = current($result);
259 }
260 return $object;
261 }
262 throw new Tx_Extbase_Persistence_Exception_UnsupportedMethod('The method "' . $methodName . '" is not supported by the repository.', 1233180480);
263 }
264
265 /**
266 * Returns the class name of this class.
267 *
268 * @return string Class name of the repository.
269 */
270 protected function getRepositoryClassName() {
271 return get_class($this);
272 }
273
274 }
275 ?>