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