Passed
Push — master ( e47dd8...3ef27a )
by
unknown
13:30
created

PersistenceManager::convertObjectsToIdentityArrays()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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