[CLEANUP] Remove newlines after closing php tag
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Persistence / Generic / PersistenceManager.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Persistence\Generic;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2010-2012 Extbase Team (http://forge.typo3.org/projects/typo3v4-mvc)
8 * Extbase is a backport of TYPO3 Flow. All credits go to the TYPO3 Flow team.
9 * All rights reserved
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 * A copy is found in the textfile GPL.txt and important notices to the license
20 * from the author is found in LICENSE.txt distributed with these scripts.
21 *
22 *
23 * This script is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * This copyright notice MUST APPEAR in all copies of the script!
29 ***************************************************************/
30 /**
31 * The Extbase Persistence Manager
32 *
33 * @api
34 */
35 class PersistenceManager implements \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface, \TYPO3\CMS\Core\SingletonInterface {
36
37 /**
38 * @var \TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface
39 */
40 protected $backend;
41
42 /**
43 * @var \TYPO3\CMS\Extbase\Persistence\Generic\Session
44 */
45 protected $session;
46
47 /**
48 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
49 */
50 protected $objectManager;
51
52 /**
53 * @var \TYPO3\CMS\Extbase\Persistence\Generic\QueryFactoryInterface
54 */
55 protected $queryFactory;
56
57 /**
58 * @var \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface
59 */
60 protected $defaultQuerySettings = NULL;
61
62 /**
63 * Objects of this repository
64 *
65 * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage
66 */
67 protected $addedObjects;
68
69 /**
70 * Objects removed but not found in $this->addedObjects at removal time
71 *
72 * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage
73 */
74 protected $removedObjects;
75
76 public function initializeObject() {
77 $this->addedObjects = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
78 $this->removedObjects = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
79 }
80
81 /**
82 * Returns all addedObjects that have been added to this repository with add().
83 *
84 * This is a service method for the persistence manager to get all addedObjects
85 * added to the repository. Those are only objects *added*, not objects
86 * fetched from the underlying storage.
87 *
88 * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage the objects
89 */
90 public function getAddedObjects() {
91 return $this->addedObjects;
92 }
93
94 /**
95 * Returns an \TYPO3\CMS\Extbase\Persistence\ObjectStorage with objects remove()d from the repository
96 * that had been persisted to the storage layer before.
97 *
98 * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage the objects
99 */
100 public function getRemovedObjects() {
101 return $this->removedObjects;
102 }
103
104 /**
105 * Injects the Persistence Backend
106 *
107 * @param \TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface $backend The persistence backend
108 * @return void
109 */
110 public function injectBackend(\TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface $backend) {
111 $this->backend = $backend;
112 }
113
114 /**
115 * Injects the Persistence Session
116 *
117 * @param \TYPO3\CMS\Extbase\Persistence\Generic\Session $session The persistence session
118 * @return void
119 */
120 public function injectSession(\TYPO3\CMS\Extbase\Persistence\Generic\Session $session) {
121 $this->session = $session;
122 }
123
124 /**
125 * Injects the object manager
126 *
127 * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
128 * @return void
129 */
130 public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager) {
131 $this->objectManager = $objectManager;
132 }
133
134 /**
135 * @param \TYPO3\CMS\Extbase\Persistence\Generic\QueryFactory $queryFactory
136 * @return void
137 */
138 public function injectQueryFactory(\TYPO3\CMS\Extbase\Persistence\Generic\QueryFactory $queryFactory) {
139 $this->queryFactory = $queryFactory;
140 }
141
142 /**
143 * Returns the number of records matching the query.
144 *
145 * @param \TYPO3\CMS\Extbase\Persistence\QueryInterface $query
146 * @return integer
147 * @api
148 */
149 public function getObjectCountByQuery(\TYPO3\CMS\Extbase\Persistence\QueryInterface $query) {
150 return $this->backend->getObjectCountByQuery($query);
151 }
152
153 /**
154 * Returns the object data matching the $query.
155 *
156 * @param \TYPO3\CMS\Extbase\Persistence\QueryInterface $query
157 * @return array
158 * @api
159 */
160 public function getObjectDataByQuery(\TYPO3\CMS\Extbase\Persistence\QueryInterface $query) {
161 return $this->backend->getObjectDataByQuery($query);
162 }
163
164 /**
165 * Returns the (internal) identifier for the object, if it is known to the
166 * backend. Otherwise NULL is returned.
167 *
168 * Note: this returns an identifier even if the object has not been
169 * persisted in case of AOP-managed entities. Use isNewObject() if you need
170 * to distinguish those cases.
171 *
172 * @param object $object
173 * @return mixed The identifier for the object if it is known, or NULL
174 * @api
175 */
176 public function getIdentifierByObject($object) {
177 return $this->backend->getIdentifierByObject($object);
178 }
179
180 /**
181 * Returns the object with the (internal) identifier, if it is known to the
182 * backend. Otherwise NULL is returned.
183 *
184 * @param mixed $identifier
185 * @param string $objectType
186 * @param boolean $useLazyLoading
187 * @return object The object for the identifier if it is known, or NULL
188 * @api
189 */
190 public function getObjectByIdentifier($identifier, $objectType = NULL, $useLazyLoading = FALSE) {
191 return $this->backend->getObjectByIdentifier($identifier, $objectType);
192 }
193
194 /**
195 * Commits new objects and changes to objects in the current persistence
196 * session into the backend
197 *
198 * @return void
199 * @api
200 */
201 public function persistAll() {
202 $aggregateRootObjects = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
203 $removedObjects = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
204
205 $aggregateRootObjects->addAll($this->getAddedObjects());
206 $removedObjects->addAll($this->getRemovedObjects());
207
208 foreach ($this->session->getReconstitutedObjects() as $reconstitutedObject) {
209 $className = get_class($reconstitutedObject);
210 $delimiter = strpos($className, '_') !== FALSE ? '_' : '\\';
211 $possibleRepositoryClassName = str_replace($delimiter . 'Model' . $delimiter, $delimiter . 'Repository' . $delimiter, $className) . 'Repository';
212 if (class_exists($possibleRepositoryClassName)) {
213 $aggregateRootObjects->attach($reconstitutedObject);
214 }
215 }
216 // hand in only aggregate roots, leaving handling of subobjects to
217 // the underlying storage layer
218 $this->backend->setAggregateRootObjects($aggregateRootObjects);
219 $this->backend->setDeletedObjects($removedObjects);
220 $this->backend->commit();
221 // this needs to unregister more than just those, as at least some of
222 // the subobjects are supposed to go away as well...
223 // OTOH those do no harm, changes to the unused ones should not happen,
224 // so all they do is eat some memory.
225 foreach ($removedObjects as $removedObject) {
226 $this->session->unregisterReconstitutedObject($removedObject);
227 }
228 }
229
230 /**
231 * Adds an object to the persistence.
232 *
233 * @param object $object The object to add
234 * @return void
235 * @api
236 */
237 public function add($object) {
238 $this->addedObjects->attach($object);
239 if ($this->removedObjects->contains($object)) {
240 $this->removedObjects->detach($object);
241 }
242 }
243
244 /**
245 * Removes an object to the persistence.
246 *
247 * @param object $object The object to remove
248 * @return void
249 * @api
250 */
251 public function remove($object) {
252 if ($this->addedObjects->contains($object)) {
253 $this->addedObjects->detach($object);
254 }
255
256 if (!$object->_isNew()) {
257 $this->removedObjects->attach($object);
258 }
259 }
260
261 /**
262 * Update an object in the persistence.
263 *
264 * @param object $object The modified object
265 * @return void
266 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
267 * @api
268 */
269 public function update($object) {
270 $uid = $object->getUid();
271 if ($uid !== NULL) {
272 $existingObject = $this->getObjectByIdentifier($uid, get_class($object));
273 $this->replace($existingObject, $object);
274 } else {
275 throw new \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException('The "modified object" is does not have an existing counterpart in this repository.', 1249479819);
276 }
277 }
278
279 /**
280 * Injects the Extbase settings, called by Extbase.
281 *
282 * @param array $settings
283 * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException
284 * @return void
285 * @api
286 */
287 public function injectSettings(array $settings) {
288 throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException(__METHOD__);
289 }
290
291 /**
292 * Initializes the persistence manager, called by Extbase.
293 *
294 * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException
295 * @return void
296 * @api
297 */
298 public function initialize() {
299 throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException(__METHOD__);
300 }
301
302 /**
303 * Clears the in-memory state of the persistence.
304 *
305 * Managed instances become detached, any fetches will
306 * return data directly from the persistence "backend".
307 *
308 * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException
309 * @return void
310 */
311 public function clearState() {
312 throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException(__METHOD__);
313 }
314
315 /**
316 * Checks if the given object has ever been persisted.
317 *
318 * @param object $object The object to check
319 * @return boolean TRUE if the object is new, FALSE if the object exists in the repository
320 * @api
321 */
322 public function isNewObject($object) {
323 return $this->backend->isNewObject($object);
324 }
325
326 /**
327 * Converts the given object into an array containing the identity of the domain object.
328 *
329 * @param object $object The object to be converted
330 * @return array The identity array in the format array('__identity' => '...')
331 * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException
332 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException if the given object is not known to the Persistence Manager
333 * @api
334 */
335 public function convertObjectToIdentityArray($object) {
336 throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException(__METHOD__);
337 }
338
339 /**
340 * Recursively iterates through the given array and turns objects
341 * into arrays containing the identity of the domain object.
342 *
343 * @param array $array The array to be iterated over
344 * @return array The modified array without objects
345 * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException
346 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException if array contains objects that are not known to the Persistence Manager
347 * @api
348 * @see convertObjectToIdentityArray()
349 */
350 public function convertObjectsToIdentityArrays(array $array) {
351 throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException(__METHOD__);
352 }
353
354 /**
355 * Return a query object for the given type.
356 *
357 * @param string $type
358 * @return \TYPO3\CMS\Extbase\Persistence\QueryInterface
359 * @api
360 */
361 public function createQueryForType($type) {
362 /** @var $query \TYPO3\CMS\Extbase\Persistence\Generic\Query */
363 $query = $this->queryFactory->create($type);
364 if ($this->defaultQuerySettings !== NULL) {
365 $query->setQuerySettings(clone $this->defaultQuerySettings);
366 }
367
368 return $query;
369 }
370
371 /**
372 * @param \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $defaultQuerySettings
373 */
374 public function setDefaultQuerySettings($defaultQuerySettings) {
375 $this->defaultQuerySettings = $defaultQuerySettings;
376 }
377
378 /**
379 * @return \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface
380 */
381 public function getDefaultQuerySettings() {
382 return $this->defaultQuerySettings;
383 }
384
385 /**
386 * @param $existingObject
387 * @param $newObject
388 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
389 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
390 */
391 public function replace($existingObject, $newObject) {
392 if (get_class($existingObject) !== get_class($newObject)) {
393 throw new \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException('The existing object and the object given to replace were not of the same type.', 1350243147);
394 }
395
396 $uuid = $this->backend->getIdentifierByObject($existingObject);
397 if ($uuid !== NULL) {
398 $this->backend->replaceObject($existingObject, $newObject);
399 $this->session->unregisterReconstitutedObject($existingObject);
400 $this->session->registerReconstitutedObject($newObject);
401 if ($this->removedObjects->contains($existingObject)) {
402 $this->removedObjects->detach($existingObject);
403 $this->removedObjects->attach($newObject);
404 } elseif ($this->addedObjects->contains($existingObject)) {
405 $this->addedObjects->detach($existingObject);
406 $this->addedObjects->attach($newObject);
407 }
408 } elseif ($this->addedObjects->contains($existingObject)) {
409 $this->addedObjects->detach($existingObject);
410 $this->addedObjects->attach($newObject);
411 } else {
412 throw new \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException('The "existing object" is unknown to the persistence backend.', 1238068475);
413 }
414 }
415 }
416
417 ?>