Extbase:
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Persistence / Repository.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
6 * All rights reserved
7 *
8 * This class is a backport of the corresponding class of FLOW3.
9 * All credits go to the v5 team.
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 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27
28 /**
29 * The base repository - will usually be extended by a more concrete repository.
30 *
31 * @package Extbase
32 * @subpackage extbase
33 * @version $ID:$
34 */
35 class Tx_Extbase_Persistence_Repository implements Tx_Extbase_Persistence_RepositoryInterface, t3lib_Singleton {
36
37 /**
38 * @var Tx_Extbase_Persistence_QueryFactoryInterface
39 */
40 protected $queryFactory;
41
42 /**
43 * @var Tx_Extbase_Persistence_ManagerInterface
44 */
45 protected $persistenceManager;
46
47 /**
48 * Constructs a new Repository
49 *
50 */
51 public function __construct() {
52 $this->queryFactory = t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryFactory');
53 $this->persistenceManager = t3lib_div::makeInstance('Tx_Extbase_Persistence_Manager'); // singleton; must have been initialized before (constructor argument)
54 // FIXME This does not work for itemProcFunc()
55 }
56
57 /**
58 * Adds an object to this repository
59 *
60 * @param object $object The object to add
61 * @return void
62 */
63 public function add($object) {
64 // SK: Why is this commented out?
65 // if (!is_object($object) || !($object instanceof $this->aggregateRootClassName)) throw new Tx_Extbase_Persistence_Exception_InvalidClass('The class "' . get_class($object) . '" is not supported by the repository.');
66 $this->persistenceManager->getSession()->registerAddedObject($object);
67 }
68
69 /**
70 * Removes an object from this repository.
71 *
72 * @param object $object The object to remove
73 * @return void
74 */
75 public function remove($object) {
76
77 // SK: Why is this commented out?
78 // if (!is_object($object) || !($object instanceof $this->aggregateRootClassName)) throw new Tx_Extbase_Persistence_Exception_InvalidClass('The class "' . get_class($object) . '" is not supported by the repository.');
79 $this->persistenceManager->getSession()->registerRemovedObject($object);
80 }
81
82 /**
83 * Replaces an object by another.
84 *
85 * @param object $existingObject The existing object
86 * @param object $newObject The new object
87 * return void
88 */
89 public function replace($existingObject, $newObject) {
90 $backend = $this->persistenceManager->getBackend();
91 $session = $this->persistenceManager->getSession();
92 $uid = $backend->getUidByObject($existingObject);
93 if ($uid !== NULL) {
94 $backend->replaceObject($existingObject, $newObject);
95 $session->unregisterReconstitutedObject($existingObject);
96 $session->registerReconstitutedObject($newObject);
97 } else {
98 throw new Tx_Extbase_Persistence_Exception_UnknownObject('The "existing object" is unknown to the repository.', 1238068475);
99 }
100 }
101
102 /**
103 * Returns all objects of this repository
104 *
105 * @return array An array of objects, empty if no objects found
106 */
107 public function findAll() {
108 $result = $this->createQuery()->execute();
109 $this->persistenceManager->getSession()->registerReconstitutedObjects($result);
110 return $result;
111 }
112
113 /**
114 * Finds an object matching the given identifier.
115 *
116 * @param int $uid The identifier of the object to find
117 * @return object The matching object if found, otherwise NULL
118 */
119 public function findByUid($uid) {
120 if (!is_int($uid) || $uid < 0) throw new InvalidArgumentException('The uid must be a positive integer', 1245071889);
121 $query = $this->createQuery();
122 $result = $query->matching($query->withUid($uid))
123 ->setLimit(1)
124 ->execute();
125 $object = NULL;
126 if (count($result) > 0) {
127 $object = current($result);
128 $this->persistenceManager->getSession()->registerReconstitutedObject($object);
129 }
130 return $object;
131 }
132
133 /**
134 * Returns a query for objects of this repository
135 *
136 * @return Tx_Extbase_Persistence_QueryInterface
137 */
138 public function createQuery() {
139 $repositoryClassName = $this->getRepositoryClassName();
140 if (substr($repositoryClassName, -10) == 'Repository' && substr($repositoryClassName, -11, 1) != '_') {
141 $type = substr($repositoryClassName, 0, -10);
142 } else {
143 throw new Tx_Extbase_Exception('The domain repository wasn\'t able to resolve the target class name.', 1237897039);
144 }
145 if (!in_array('Tx_Extbase_DomainObject_DomainObjectInterface', class_implements($type))) {
146 throw new Tx_Extbase_Exception('The domain repository tried to manage objects which are not implementing the Tx_Extbase_DomainObject_DomainObjectInterface.', 1237897039);
147 }
148 return $this->queryFactory->create($type);
149 }
150
151 /**
152 * Dispatches magic methods (findBy[Property]())
153 *
154 * @param string $methodName The name of the magic method
155 * @param string $arguments The arguments of the magic method
156 * @throws Tx_Extbase_Persistence_Exception_UnsupportedMethod
157 * @return void
158 */
159 public function __call($methodName, $arguments) {
160 if (substr($methodName, 0, 6) === 'findBy' && strlen($methodName) > 7) {
161 $propertyName = strtolower(substr(substr($methodName, 6), 0, 1) ) . substr(substr($methodName, 6), 1);
162 $query = $this->createQuery();
163 $result = $query->matching($query->equals($propertyName, $arguments[0]))
164 ->execute();
165 $this->persistenceManager->getSession()->registerReconstitutedObjects($result);
166 return $result;
167 } elseif (substr($methodName, 0, 9) === 'findOneBy' && strlen($methodName) > 10) {
168 $propertyName = strtolower(substr(substr($methodName, 9), 0, 1) ) . substr(substr($methodName, 9), 1);
169 $query = $this->createQuery();
170 $result = $query->matching($query->equals($propertyName, $arguments[0]))
171 ->setLimit(1)
172 ->execute();
173 $object = NULL;
174 if (count($result) > 0) {
175 $object = current($result);
176 // SK: registerReconstitutedObject() needs to be called automatically inside the DataMapper!
177 $this->persistenceManager->getSession()->registerReconstitutedObject($object);
178 }
179 return $object;
180 }
181 throw new Tx_Extbase_Persistence_Exception_UnsupportedMethod('The method "' . $methodName . '" is not supported by the repository.', 1233180480);
182 }
183
184 /**
185 * Returns the class name of this class.
186 *
187 * @return string Class name of the repository.
188 */
189 protected function getRepositoryClassName() {
190 return get_class($this);
191 }
192
193 }
194 ?>