[CLEANUP] Extbase persistence classes
[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-2013 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 text file 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 use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
31 use TYPO3\CMS\Extbase\Persistence\QueryInterface;
32
33 /**
34 * The Extbase Persistence Manager
35 *
36 * @api
37 */
38 class PersistenceManager implements \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface, \TYPO3\CMS\Core\SingletonInterface {
39
40 /**
41 * @var array
42 */
43 protected $newObjects = array();
44
45 /**
46 * @var ObjectStorage
47 */
48 protected $changedObjects;
49
50 /**
51 * @var ObjectStorage
52 */
53 protected $addedObjects;
54
55 /**
56 * @var ObjectStorage
57 */
58 protected $removedObjects;
59
60 /**
61 * @var \TYPO3\CMS\Extbase\Persistence\Generic\QueryFactoryInterface
62 * @inject
63 */
64 protected $queryFactory;
65
66 /**
67 * @var \TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface
68 * @inject
69 */
70 protected $backend;
71
72 /**
73 * @var \TYPO3\CMS\Extbase\Persistence\Generic\Session
74 * @inject
75 */
76 protected $persistenceSession;
77
78 /**
79 * Create new instance
80 */
81 public function __construct() {
82 $this->addedObjects = new ObjectStorage();
83 $this->removedObjects = new ObjectStorage();
84 $this->changedObjects = new ObjectStorage();
85 }
86
87 /**
88 * Registers a repository
89 *
90 * @param string $className The class name of the repository to be reigistered
91 * @deprecated since 6.1, will be remove two versions later
92 * @return void
93 */
94 public function registerRepositoryClassName($className) {
95 }
96
97 /**
98 * Returns the number of records matching the query.
99 *
100 * @param QueryInterface $query
101 * @return integer
102 * @api
103 */
104 public function getObjectCountByQuery(QueryInterface $query) {
105 return $this->backend->getObjectCountByQuery($query);
106 }
107
108 /**
109 * Returns the object data matching the $query.
110 *
111 * @param QueryInterface $query
112 * @return array
113 * @api
114 */
115 public function getObjectDataByQuery(QueryInterface $query) {
116 return $this->backend->getObjectDataByQuery($query);
117 }
118
119 /**
120 * Returns the (internal) identifier for the object, if it is known to the
121 * backend. Otherwise NULL is returned.
122 *
123 * Note: this returns an identifier even if the object has not been
124 * persisted in case of AOP-managed entities. Use isNewObject() if you need
125 * to distinguish those cases.
126 *
127 * @param object $object
128 * @return mixed The identifier for the object if it is known, or NULL
129 * @api
130 */
131 public function getIdentifierByObject($object) {
132 return $this->backend->getIdentifierByObject($object);
133 }
134
135 /**
136 * Returns the object with the (internal) identifier, if it is known to the
137 * backend. Otherwise NULL is returned.
138 *
139 * @param mixed $identifier
140 * @param string $objectType
141 * @param boolean $useLazyLoading Set to TRUE if you want to use lazy loading for this object
142 * @return object The object for the identifier if it is known, or NULL
143 * @api
144 */
145 public function getObjectByIdentifier($identifier, $objectType = NULL, $useLazyLoading = FALSE) {
146 if (isset($this->newObjects[$identifier])) {
147 return $this->newObjects[$identifier];
148 }
149 if ($this->persistenceSession->hasIdentifier($identifier, $objectType)) {
150 return $this->persistenceSession->getObjectByIdentifier($identifier, $objectType);
151 } else {
152 return $this->backend->getObjectByIdentifier($identifier, $objectType);
153 }
154 }
155
156 /**
157 * Commits new objects and changes to objects in the current persistence
158 * session into the backend
159 *
160 * @return void
161 * @api
162 */
163 public function persistAll() {
164 // hand in only aggregate roots, leaving handling of subobjects to
165 // the underlying storage layer
166 // reconstituted entities must be fetched from the session and checked
167 // for changes by the underlying backend as well!
168 $this->backend->setAggregateRootObjects($this->addedObjects);
169 $this->backend->setChangedEntities($this->changedObjects);
170 $this->backend->setDeletedEntities($this->removedObjects);
171 $this->backend->commit();
172
173 $this->addedObjects = new ObjectStorage();
174 $this->removedObjects = new ObjectStorage();
175 $this->changedObjects = new ObjectStorage();
176 }
177
178 /**
179 * Return a query object for the given type.
180 *
181 * @param string $type
182 * @return QueryInterface
183 */
184 public function createQueryForType($type) {
185 return $this->queryFactory->create($type);
186 }
187
188 /**
189 * Adds an object to the persistence.
190 *
191 * @param object $object The object to add
192 * @return void
193 * @api
194 */
195 public function add($object) {
196 $this->addedObjects->attach($object);
197 $this->removedObjects->detach($object);
198 }
199
200 /**
201 * Removes an object to the persistence.
202 *
203 * @param object $object The object to remove
204 * @return void
205 * @api
206 */
207 public function remove($object) {
208 if ($this->addedObjects->contains($object)) {
209 $this->addedObjects->detach($object);
210 } else {
211 $this->removedObjects->attach($object);
212 }
213 }
214
215 /**
216 * Update an object in the persistence.
217 *
218 * @param object $object The modified object
219 * @return void
220 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
221 * @api
222 */
223 public function update($object) {
224 if ($this->isNewObject($object)) {
225 throw new \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException('The object of type "' . get_class($object) . '" given to update must be persisted already, but is new.', 1249479819);
226 }
227 $this->changedObjects->attach($object);
228 }
229
230 /**
231 * Injects the Extbase settings, called by Extbase.
232 *
233 * @param array $settings
234 * @return void
235 * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException
236 * @api
237 */
238 public function injectSettings(array $settings) {
239 throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException(__METHOD__);
240 }
241
242 /**
243 * Initializes the persistence manager, called by Extbase.
244 *
245 * @return void
246 */
247 public function initializeObject() {
248 $this->backend->setPersistenceManager($this);
249 }
250
251 /**
252 * Clears the in-memory state of the persistence.
253 *
254 * Managed instances become detached, any fetches will
255 * return data directly from the persistence "backend".
256 *
257 * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException
258 * @return void
259 */
260 public function clearState() {
261 $this->newObjects = array();
262 $this->addedObjects = new ObjectStorage();
263 $this->removedObjects = new ObjectStorage();
264 $this->changedObjects = new ObjectStorage();
265 $this->persistenceSession->destroy();
266 }
267
268 /**
269 * Checks if the given object has ever been persisted.
270 *
271 * @param object $object The object to check
272 * @return boolean TRUE if the object is new, FALSE if the object exists in the persistence session
273 * @api
274 */
275 public function isNewObject($object) {
276 return ($this->persistenceSession->hasObject($object) === FALSE);
277 }
278
279 /**
280 * Registers an object which has been created or cloned during this request.
281 *
282 * A "new" object does not necessarily
283 * have to be known by any repository or be persisted in the end.
284 *
285 * Objects registered with this method must be known to the getObjectByIdentifier()
286 * method.
287 *
288 * @param object $object The new object to register
289 * @return void
290 */
291 public function registerNewObject($object) {
292 $identifier = $this->getIdentifierByObject($object);
293 $this->newObjects[$identifier] = $object;
294 }
295
296 /**
297 * Converts the given object into an array containing the identity of the domain object.
298 *
299 * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException
300 * @param object $object The object to be converted
301 * @return array
302 * @api
303 */
304 public function convertObjectToIdentityArray($object) {
305 throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException(__METHOD__);
306 }
307
308 /**
309 * Recursively iterates through the given array and turns objects
310 * into arrays containing the identity of the domain object.
311 *
312 * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException
313 * @param array $array The array to be iterated over
314 * @return array
315 * @api
316 * @see convertObjectToIdentityArray()
317 */
318 public function convertObjectsToIdentityArrays(array $array) {
319 throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException(__METHOD__);
320 }
321
322 /**
323 * Tear down the persistence
324 *
325 * This method is called in functional tests to reset the storage between tests.
326 * The implementation is optional and depends on the underlying persistence backend.
327 *
328 * @return void
329 */
330 public function tearDown() {
331 if (method_exists($this->backend, 'tearDown')) {
332 $this->backend->tearDown();
333 }
334 }
335
336 }