Add Extbase 1.0.1 to TYPO3core. Do NOT make changes inside! See misc/core_svn_rules...
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Reflection / ClassSchema.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 * A class schema
30 *
31 * @version $Id: ClassSchema.php 1729 2009-11-25 21:37:20Z stucki $
32 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
33 */
34 class Tx_Extbase_Reflection_ClassSchema {
35
36 /**
37 * Available model types
38 */
39 const MODELTYPE_ENTITY = 1;
40 const MODELTYPE_VALUEOBJECT = 2;
41
42 /**
43 * Specifies the allowed property types.
44 */
45 const ALLOWED_TYPES_PATTERN = '/^(?P<type>integer|int|float|boolean|string|DateTime|Tx_[a-zA-Z0-9_]+|array|ArrayObject|Tx_Extbase_Persistence_ObjectStorage)(?:<(?P<elementType>[a-zA-Z0-9_]+)>)?/';
46
47 /**
48 * Name of the class this schema is referring to
49 *
50 * @var string
51 */
52 protected $className;
53
54 /**
55 * Model type of the class this schema is referring to
56 *
57 * @var integer
58 */
59 protected $modelType = self::MODELTYPE_ENTITY;
60
61 /**
62 * Whether a repository exists for the class this schema is referring to
63 * @var boolean
64 */
65 protected $aggregateRoot = FALSE;
66
67 /**
68 * The name of the property holding the uuid of an entity, if any.
69 *
70 * @var string
71 */
72 protected $uuidPropertyName;
73
74 /**
75 * Properties of the class which need to be persisted
76 *
77 * @var array
78 */
79 protected $properties = array();
80
81 /**
82 * The properties forming the identity of an object
83 *
84 * @var array
85 */
86 protected $identityProperties = array();
87
88 /**
89 * Constructs this class schema
90 *
91 * @param string $className Name of the class this schema is referring to
92 * @author Robert Lemke <robert@typo3.org>
93 */
94 public function __construct($className) {
95 $this->className = $className;
96 }
97
98 /**
99 * Returns the class name this schema is referring to
100 *
101 * @return string The class name
102 * @author Robert Lemke <robert@typo3.org>
103 */
104 public function getClassName() {
105 return $this->className;
106 }
107
108 /**
109 * Adds (defines) a specific property and its type.
110 *
111 * @param string $name Name of the property
112 * @param string $type Type of the property (see ALLOWED_TYPES_PATTERN)
113 * @param boolean $lazy Whether the property should be lazy-loaded when reconstituting
114 * @param string $cascade Strategy to cascade the object graph.
115 * @return void
116 * @author Robert Lemke <robert@typo3.org>
117 * @author Karsten Dambekalns <karsten@typo3.org>
118 */
119 public function addProperty($name, $type, $lazy = FALSE, $cascade = '') {
120 $matches = array();
121 if (preg_match(self::ALLOWED_TYPES_PATTERN, $type, $matches)) {
122 $type = ($matches['type'] === 'int') ? 'integer' : $matches['type'];
123 $elementType = isset($matches['elementType']) ? $matches['elementType'] : NULL;
124
125 if ($elementType !== NULL && !in_array($type, array('array', 'ArrayObject', 'Tx_Extbase_Persistence_ObjectStorage', 'Tx_Extbase_Persistence_LazyObjectStorage'))) {
126 throw new Tx_Extbase_Reflection_Exception_InvalidPropertyType('Property of type "' . $type . '" must not have an element type hint (' . $elementType . ').', 1248103053);
127 }
128
129 $this->properties[$name] = array(
130 'type' => $type,
131 'elementType' => $elementType,
132 'lazy' => $lazy,
133 'cascade' => $cascade
134 );
135 } else {
136 throw new Tx_Extbase_Reflection_Exception_InvalidPropertyType('Invalid property type encountered: ' . $type, 1220387528);
137 }
138 }
139
140 /**
141 * Returns the given property defined in this schema. Check with
142 * hasProperty($propertyName) before!
143 *
144 * @return array
145 * @author Karsten Dambekalns <karsten@typo3.org>
146 */
147 public function getProperty($propertyName) {
148 return is_array($this->properties[$propertyName]) ? $this->properties[$propertyName] : array();
149 }
150
151 /**
152 * Returns all properties defined in this schema
153 *
154 * @return array
155 * @author Robert Lemke <robert@typo3.org>
156 */
157 public function getProperties() {
158 return $this->properties;
159 }
160
161 /**
162 * Sets the model type of the class this schema is referring to.
163 *
164 * @param integer The model type, one of the MODELTYPE_* constants.
165 * @return void
166 * @author Robert Lemke <robert@typo3.org>
167 */
168 public function setModelType($modelType) {
169 if ($modelType < self::MODELTYPE_ENTITY || $modelType > self::MODELTYPE_VALUEOBJECT) throw new InvalidArgumentException('"' . $modelType . '" is an invalid model type.', 1212519195);
170 $this->modelType = $modelType;
171 }
172
173 /**
174 * Returns the model type of the class this schema is referring to.
175 *
176 * @return integer The model type, one of the MODELTYPE_* constants.
177 * @author Robert Lemke <robert@typo3.org>
178 */
179 public function getModelType() {
180 return $this->modelType;
181 }
182
183 /**
184 * Marks the class if it is root of an aggregate and therefore accessible
185 * through a repository - or not.
186 *
187 * @param boolean $isRoot TRUE if it is the root of an aggregate
188 * @return void
189 * @author Karsten Dambekalns <karsten@typo3.org>
190 */
191 public function setAggregateRoot($isRoot) {
192 $this->aggregateRoot = $isRoot;
193 }
194
195 /**
196 * Whether the class is an aggregate root and therefore accessible through
197 * a repository.
198 *
199 * @return boolean TRUE if it is managed
200 * @author Karsten Dambekalns <karsten@typo3.org>
201 */
202 public function isAggregateRoot() {
203 return $this->aggregateRoot;
204 }
205
206 /**
207 * If the class schema has a certain property.
208 *
209 * @param string $propertyName Name of the property
210 * @return boolean
211 * @author Robert Lemke <robert@typo3.org>
212 */
213 public function hasProperty($propertyName) {
214 return array_key_exists($propertyName, $this->properties);
215 }
216
217 /**
218 * Sets the property marked as uuid of an object with @uuid
219 *
220 * @param string $propertyName
221 * @return void
222 * @author Karsten Dambekalns <karsten@typo3.org>
223 */
224 public function setUUIDPropertyName($propertyName) {
225 if (!array_key_exists($propertyName, $this->properties)) {
226 throw new InvalidArgumentException('Property "' . $propertyName . '" must be added to the class schema before it can be marked as UUID property.', 1233863842);
227 }
228
229 $this->uuidPropertyName = $propertyName;
230 }
231
232 /**
233 * Gets the name of the property marked as uuid of an object
234 *
235 * @return string
236 * @author Karsten Dambekalns <karsten@typo3.org>
237 */
238 public function getUUIDPropertyName() {
239 return $this->uuidPropertyName;
240 }
241
242 /**
243 * Marks the given property as one of properties forming the identity
244 * of an object. The property must already be registered in the class
245 * schema.
246 *
247 * @param string $propertyName
248 * @return void
249 * @author Karsten Dambekalns <karsten@typo3.org>
250 */
251 public function markAsIdentityProperty($propertyName) {
252 if (!array_key_exists($propertyName, $this->properties)) {
253 throw new InvalidArgumentException('Property "' . $propertyName . '" must be added to the class schema before it can be marked as identity property.', 1233775407);
254 }
255 if ($this->properties[$propertyName]['lazy'] === TRUE) {
256 throw new InvalidArgumentException('Property "' . $propertyName . '" must not be makred for lazy loading to be marked as identity property.', 1239896904);
257 }
258
259 $this->identityProperties[$propertyName] = $this->properties[$propertyName]['type'];
260 }
261
262 /**
263 * Gets the properties (names and types) forming the identity of an object.
264 *
265 * @return array
266 * @author Karsten Dambekalns <karsten@typo3.org>
267 * @see markAsIdentityProperty()
268 */
269 public function getIdentityProperties() {
270 return $this->identityProperties;
271 }
272
273 }
274 ?>