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