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 // TODO Remove if autoloader is active
29 require_once(PATH_t3lib . 'interfaces/interface.t3lib_singleton.php');
30 require_once(PATH_tslib . 'class.tslib_content.php');
31 // SK: Remove these require statements as we have the autoloader
32
33 /**
34 * The base repository - will usually be extended by a more concrete repository.
35 *
36 * @package Extbase
37 * @subpackage extbase
38 * @version $ID:$
39 */
40 class Tx_Extbase_Persistence_Repository implements Tx_Extbase_Persistence_RepositoryInterface, t3lib_Singleton {
41
42 /**
43 * @var Tx_Extbase_Persistence_QueryFactoryInterface
44 */
45 protected $queryFactory;
46
47 /**
48 * @var Tx_Extbase_Persistence_ManagerInterface
49 */
50 protected $persistenceManager;
51
52 /**
53 * Constructs a new Repository
54 *
55 */
56 public function __construct() {
57 $this->queryFactory = t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryFactory');
58 $this->persistenceManager = t3lib_div::makeInstance('Tx_Extbase_Persistence_Manager'); // singleton; must have been initialized before (constructor argument)
59 }
60
61 /**
62 * Adds an object to this repository
63 *
64 * @param object $object The object to add
65 * @return void
66 */
67 public function add($object) {
68 // SK: see the following comment, I think this needs to be added again
69 // if (!($object instanceof $this->aggregateRootClassName)) throw new Tx_Extbase_Persistence_Exception_InvalidClass('The class "' . get_class($object) . '" is not supported by the repository.');
70 $this->persistenceManager->getSession()->registerAddedObject($object);
71 }
72
73 /**
74 * Removes an object from this repository.
75 *
76 * @param object $object The object to remove
77 * @return void
78 */
79 public function remove($object) {
80 // SK: see the following comment, I think this needs to be added again
81 // if (!($object instanceof $this->aggregateRootClassName)) throw new Tx_Extbase_Persistence_Exception_InvalidClass('The class "' . get_class($object) . '" is not supported by the repository.');
82 $this->persistenceManager->getSession()->registerRemovedObject($object);
83 }
84
85 /**
86 * Replaces an object by another.
87 *
88 * @param object $existingObject The existing object
89 * @param object $newObject The new object
90 * return void
91 */
92 public function replace($existingObject, $newObject) {
93 $backend = $this->persistenceManager->getBackend();
94 $session = $this->persistenceManager->getSession();
95 $uid = $backend->getUidByObject($existingObject);
96 if ($uid !== NULL) {
97 $backend->replaceObject($existingObject, $newObject);
98 $session->unregisterReconstitutedObject($existingObject);
99 $session->registerReconstitutedObject($newObject);
100 } else {
101 throw new Tx_Extbase_Persistence_Exception_UnknownObject('The "existing object" is unknown to the repository.', 1238068475);
102 }
103 }
104
105 /**
106 * Returns all objects of this repository
107 *
108 * @return array An array of objects, empty if no objects found
109 */
110 public function findAll() {
111 $result = $this->createQuery()->execute();
112 $this->persistenceManager->getSession()->registerReconstitutedObjects($result);
113 return $result;
114 }
115
116 /**
117 * Finds an object matching the given identifier.
118 *
119 * @param int $uid The identifier of the object to find
120 * @return object The matching object if found, otherwise NULL
121 */
122 public function findByUid($uid) {
123 if (!is_int($uid) || $uid < 0) throw new InvalidArgumentException('The uid must be a positive integer', 1245071889);
124 $query = $this->createQuery();
125 $result = $query->matching($query->withUid($uid))
126 ->setLimit(1)
127 ->execute();
128 $object = NULL;
129 if (count($result) > 0) {
130 $object = current($result);
131 $this->persistenceManager->getSession()->registerReconstitutedObject($object);
132 }
133 return $object;
134 }
135
136 /**
137 * Returns a query for objects of this repository
138 *
139 * @return Tx_Extbase_Persistence_QueryInterface
140 */
141 public function createQuery() {
142 $repositoryClassName = $this->getRepositoryClassName();
143 if (substr($repositoryClassName, -10) == 'Repository' && substr($repositoryClassName, -11, 1) != '_') {
144 $type = substr($repositoryClassName, 0, -10);
145 } else {
146 throw new Tx_Extbase_Exception('The domain repository wasn\'t able to resolve the target class name.', 1237897039);
147 }
148 if (!in_array('Tx_Extbase_DomainObject_DomainObjectInterface', class_implements($type))) {
149 throw new Tx_Extbase_Exception('The domain repository tried to manage objects which are not implementing the Tx_Extbase_DomainObject_DomainObjectInterface.', 1237897039);
150 }
151 return $this->queryFactory->create($type);
152 }
153
154 /**
155 * Dispatches magic methods (findBy[Property]())
156 *
157 * @param string $methodName The name of the magic method
158 * @param string $arguments The arguments of the magic method
159 * @throws Tx_Extbase_Persistence_Exception_UnsupportedMethod
160 * @return void
161 */
162 public function __call($methodName, $arguments) {
163 if (substr($methodName, 0, 6) === 'findBy' && strlen($methodName) > 7) {
164 $propertyName = strtolower(substr(substr($methodName, 6), 0, 1) ) . substr(substr($methodName, 6), 1);
165 $query = $this->createQuery();
166 $result = $query->matching($query->equals($propertyName, $arguments[0]))
167 ->execute();
168 $this->persistenceManager->getSession()->registerReconstitutedObjects($result);
169 return $result;
170 } elseif (substr($methodName, 0, 9) === 'findOneBy' && strlen($methodName) > 10) {
171 $propertyName = strtolower(substr(substr($methodName, 9), 0, 1) ) . substr(substr($methodName, 9), 1);
172 $query = $this->createQuery();
173 $result = $query->matching($query->equals($propertyName, $arguments[0]))
174 ->setLimit(1)
175 ->execute();
176 $object = NULL;
177 if (count($result) > 0) {
178 $object = current($result);
179 $this->persistenceManager->getSession()->registerReconstitutedObject($object);
180 }
181 return $object;
182 }
183 throw new Tx_Extbase_Persistence_Exception_UnsupportedMethod('The method "' . $methodName . '" is not supported by the repository.', 1233180480);
184 }
185
186 /**
187 * Returns the class name of this class.
188 *
189 * @return string Class name of the repository.
190 */
191 protected function getRepositoryClassName() {
192 return get_class($this);
193 }
194
195 }
196 ?>