[TASK] Make current persistence replaceable
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Persistence / Repository.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Persistence;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * This class is a backport of the corresponding class of TYPO3 Flow.
8 * 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 base repository - will usually be extended by a more concrete repository.
32 *
33 * @api
34 */
35 class Repository implements \TYPO3\CMS\Extbase\Persistence\RepositoryInterface, \TYPO3\CMS\Core\SingletonInterface {
36
37 /**
38 * @var \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface
39 */
40 protected $persistenceManager;
41
42 /**
43 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
44 */
45 protected $objectManager;
46
47 /**
48 * Warning: if you think you want to set this,
49 * look at RepositoryInterface::ENTITY_CLASSNAME first!
50 *
51 * @var string
52 */
53 protected $entityClassName;
54
55 /**
56 * @var array
57 */
58 protected $defaultOrderings = array();
59
60 /**
61 * Initializes a new Repository.
62 *
63 * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
64 * @deprecated since Extbase 6.0.0; will be removed in Extbase 6.2 - Use objectManager to instantiate repository objects instead of GeneralUtility::makeInstance
65 */
66 public function __construct(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager = NULL) {
67
68 if ($objectManager === NULL) {
69 // Legacy creation, in case the object manager is NOT injected
70 // If ObjectManager IS there, then all properties are automatically injected
71 // @deprecated since Extbase 6.0.0, will be removed in Extbase 6.2
72 \TYPO3\CMS\Core\Utility\GeneralUtility::logDeprecatedFunction();
73
74 $this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
75 $this->injectPersistenceManager($this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\PersistenceManagerInterface'));
76 } else {
77 $this->objectManager = $objectManager;
78 }
79
80 if (static::ENTITY_CLASSNAME === NULL) {
81 $this->entityClassName = preg_replace(array('/\\\Domain\\\Repository\\\/', '/_Domain_Repository_/', '/Repository$/'), array('\\Domain\\Model\\', '_Domain_Model_', ''), get_class($this));
82 } else {
83 $this->entityClassName = static::ENTITY_CLASSNAME;
84 }
85 }
86
87 /**
88 * Injects the persistence manager
89 *
90 * @param \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface $persistenceManager
91 * @return void
92 */
93 public function injectPersistenceManager(\TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface $persistenceManager) {
94 $this->persistenceManager = $persistenceManager;
95 }
96
97 /**
98 * Adds an object to this repository.
99 *
100 * @param object $object The object to add
101 * @return void
102 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
103 * @api
104 */
105 public function add($object) {
106 if (!is_object($object) || !($object instanceof $this->entityClassName)) {
107 $type = (is_object($object) ? get_class($object) : gettype($object));
108 throw new \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException('The value given to add() was ' . $type . ' , however the ' . get_class($this) . ' can only store ' . $this->entityClassName . ' instances.', 1298403438);
109 }
110 $this->persistenceManager->add($object);
111 }
112
113 /**
114 * Removes an object from this repository.
115 *
116 * @param object $object The object to remove
117 * @return void
118 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
119 * @api
120 */
121 public function remove($object) {
122 if (!is_object($object) || !($object instanceof $this->entityClassName)) {
123 $type = (is_object($object) ? get_class($object) : gettype($object));
124 throw new \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException('The value given to remove() was ' . $type . ' , however the ' . get_class($this) . ' can only handle ' . $this->entityClassName . ' instances.', 1298403442);
125 }
126 $this->persistenceManager->remove($object);
127 }
128
129 /**
130 * Replaces an object by another.
131 *
132 * @param object $existingObject The existing object
133 * @param object $newObject The new object
134 * @throws Exception\IllegalObjectTypeException
135 * @return void
136 * @api
137 * @deprecated since Extbase 6.0, will be removed in Extbase 7.0
138 */
139 public function replace($existingObject, $newObject) {
140 if (!$existingObject instanceof $this->entityClassName) {
141 throw new \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException('The existing object given to replace was not of the type (' . $this->entityClassName . ') this repository manages.', 1248363434);
142 }
143 if (!$newObject instanceof $this->entityClassName) {
144 throw new \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException('The new object given to replace was not of the type (' . $this->entityClassName . ') this repository manages.', 1248363439);
145 }
146
147 $this->persistenceManager->replace($existingObject, $newObject);
148 }
149
150 /**
151 * Schedules a modified object for persistence.
152 *
153 * @param object $object The modified object
154 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
155 * @api
156 */
157 public function update($object) {
158 if (!is_object($object) || !($object instanceof $this->entityClassName)) {
159 $type = (is_object($object) ? get_class($object) : gettype($object));
160 throw new \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException('The value given to update() was ' . $type . ' , however the ' . get_class($this) . ' can only store ' . $this->entityClassName . ' instances.', 1249479625);
161 }
162
163 $this->persistenceManager->update($object);
164 }
165
166 /**
167 * Returns all objects of this repository add()ed but not yet persisted to
168 * the storage layer.
169 *
170 * @return array An array of objects
171 * @deprecated since Extbase 6.0, will be removed in Extbase 7.0
172 */
173 public function getAddedObjects() {
174 return $this->persistenceManager->getAddedObjects();
175 }
176
177 /**
178 * Returns an array with objects remove()d from the repository that
179 * had been persisted to the storage layer before.
180 *
181 * @return array
182 * @deprecated since Extbase 6.0, will be removed in Extbase 7.0
183 */
184 public function getRemovedObjects() {
185 return $this->persistenceManager->getRemovedObjects();
186 }
187
188 /**
189 * Returns all objects of this repository
190 *
191 * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface The query result
192 * @api
193 * @see \TYPO3\CMS\Extbase\Persistence\QueryInterface::execute()
194 */
195 public function findAll() {
196 return $this->createQuery()->execute();
197 }
198
199 /**
200 * Counts all objects of this repository
201 *
202 * @return integer
203 * @api
204 */
205 public function countAll() {
206 return $this->createQuery()->count();
207 }
208
209 /**
210 * Removes all objects of this repository as if remove() was called for
211 * all of them.
212 *
213 * @return void
214 * @api
215 */
216 public function removeAll() {
217 foreach ($this->findAll() as $object) {
218 $this->remove($object);
219 }
220 }
221
222 /**
223 * Finds an object matching the given identifier.
224 *
225 * @param integer $uid The identifier of the object to find
226 * @return object The matching object if found, otherwise NULL
227 * @api
228 * @deprecated since Extbase 6.0, will be removed in Extbase 7.0
229 */
230 public function findByUid($uid) {
231 return $this->findByIdentifier($uid);
232 }
233
234 /**
235 * Sets the property names to order results by. Expected like this:
236 * array(
237 * 'foo' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING,
238 * 'bar' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
239 * )
240 *
241 * @param array $defaultOrderings The property names to order by by default
242 * @return void
243 * @api
244 */
245 public function setDefaultOrderings(array $defaultOrderings) {
246 $this->defaultOrderings = $defaultOrderings;
247 }
248
249 /**
250 * Sets the default query settings to be used in this repository
251 *
252 * @param \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $defaultQuerySettings The query settings to be used by default
253 * @return void
254 * @api
255 * @deprecated since Extbase 6.0, will be removed in Extbase 7.0
256 */
257 public function setDefaultQuerySettings(\TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $defaultQuerySettings) {
258 $this->persistenceManager->setDefaultQuerySettings($defaultQuerySettings);
259 }
260
261 /**
262 * Returns a query for objects of this repository
263 *
264 * @return \TYPO3\CMS\Extbase\Persistence\QueryInterface
265 * @api
266 */
267 public function createQuery() {
268 $query = $this->persistenceManager->createQueryForType($this->entityClassName);
269 if ($this->defaultOrderings !== array()) {
270 $query->setOrderings($this->defaultOrderings);
271 }
272 return $query;
273 }
274
275 /**
276 * Magic call method for repository methods.
277 *
278 * Provides three methods
279 * - findBy<PropertyName>($value, $caseSensitive = TRUE)
280 * - findOneBy<PropertyName>($value, $caseSensitive = TRUE)
281 * - countBy<PropertyName>($value, $caseSensitive = TRUE)
282 *
283 * @param string $method Name of the method
284 * @param array $arguments The arguments
285 *
286 * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnsupportedMethodException
287 *
288 * @return mixed The result of the repository method
289 * @api
290 */
291 public function __call($method, $arguments) {
292 $query = $this->createQuery();
293 $caseSensitive = isset($arguments[1]) ? (boolean)$arguments[1] : TRUE;
294
295 if (substr($method, 0, 6) === 'findBy' && strlen($method) > 7) {
296 $propertyName = lcfirst(substr($method, 6));
297 return $query->matching($query->equals($propertyName, $arguments[0], $caseSensitive))->execute();
298 } elseif (substr($method, 0, 7) === 'countBy' && strlen($method) > 8) {
299 $propertyName = lcfirst(substr($method, 7));
300 return $query->matching($query->equals($propertyName, $arguments[0], $caseSensitive))->count();
301 } elseif (substr($method, 0, 9) === 'findOneBy' && strlen($method) > 10) {
302 $propertyName = lcfirst(substr($method, 9));
303 return $query->matching($query->equals($propertyName, $arguments[0], $caseSensitive))->execute()->getFirst();
304 }
305
306 throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnsupportedMethodException('The method "' . $method . '" is not supported by the repository.', 1233180480);
307 }
308
309 /**
310 * Returns the classname of the entities this repository is managing.
311 *
312 * Note that anything that is an "instanceof" this class is accepted
313 * by the repository.
314 *
315 * @return string
316 * @api
317 */
318 public function getEntityClassName() {
319 return $this->entityClassName;
320 }
321
322 /**
323 * Finds an object matching the given identifier.
324 *
325 * @param mixed $identifier The identifier of the object to find
326 * @return object The matching object if found, otherwise NULL
327 * @api
328 */
329 public function findByIdentifier($identifier) {
330 return $this->persistenceManager->getObjectByIdentifier($identifier, $this->entityClassName);
331 }
332 }
333
334 ?>