118f8ba5e8f74dfe5b2862a2baa6a45ad06213ed
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / MVC / Controller / Argument.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 controller argument
30 *
31 * @package Extbase
32 * @subpackage MVC\Controller
33 * @version $ID:$
34 * @scope prototype
35 */
36 class Tx_Extbase_MVC_Controller_Argument {
37
38 /**
39 * @var Tx_Extbase_Persistence_QueryFactory
40 */
41 protected $queryFactory;
42
43 /**
44 * @var Tx_Extbase_Property_Mapper
45 */
46 protected $propertyMapper;
47
48 /**
49 * @var Tx_Extbase_Reflection_Service
50 */
51 protected $reflectionService;
52
53 /**
54 * Name of this argument
55 * @var string
56 */
57 protected $name = '';
58
59 /**
60 * Short name of this argument
61 * @var string
62 */
63 protected $shortName = NULL;
64
65 /**
66 * Data type of this argument's value
67 * @var string
68 */
69 protected $dataType = 'Text';
70
71 /**
72 * If the data type is an object, the class schema of the data type class is resolved
73 * @var Tx_Extbase_Reflection_ClassSchema
74 */
75 protected $dataTypeClassSchema;
76
77 /**
78 * TRUE if this argument is required
79 * @var boolean
80 */
81 protected $isRequired = FALSE;
82
83 /**
84 * Actual value of this argument
85 * @var object
86 */
87 protected $value = NULL;
88
89 /**
90 * Default value. Used if argument is optional.
91 * @var mixed
92 */
93 protected $defaultValue = NULL;
94
95 /**
96 * A custom validator, used supplementary to the base validation
97 * @var Tx_Extbase_Validation_Validator_ValidatorInterface
98 */
99 protected $validator = NULL;
100
101 /**
102 * If validation for this argument is temporarily disabled
103 * @var boolean
104 */
105 protected $validationDisabled = FALSE;
106
107 /**
108 * Uid for the argument, if it has one
109 * @var string
110 */
111 protected $uid = NULL;
112
113 /**
114 * Constructs this controller argument
115 *
116 * @param string $name Name of this argument
117 * @param string $dataType The data type of this argument
118 * @throws InvalidArgumentException if $name is not a string or empty
119 * @api
120 */
121 public function __construct($name, $dataType = 'Text') {
122 $this->reflectionService = t3lib_div::makeInstance('Tx_Extbase_Reflection_Service');
123 $this->propertyMapper = t3lib_div::makeInstance('Tx_Extbase_Property_Mapper');
124 $this->propertyMapper->injectReflectionService(t3lib_div::makeInstance('Tx_Extbase_Reflection_Service'));
125 if (!is_string($name) || strlen($name) < 1) throw new InvalidArgumentException('$name must be of type string, ' . gettype($name) . ' given.', 1187951688);
126 $this->name = $name;
127 if (is_array($dataType)) {
128 $this->setNewValidatorConjunction($dataType); // TODO: Does this really make sense? Should be "disjunction" (if we really really want to support this feature)
129 } else {
130 $this->setDataType($dataType);
131 }
132 }
133
134 /**
135 * Injects the Persistence Manager
136 *
137 * @param Tx_Extbase_Persistence_ManagerInterface
138 * @return void
139 */
140 public function injectPersistenceManager(Tx_Extbase_Persistence_ManagerInterface $persistenceManager) {
141 $this->persistenceManager = $persistenceManager;
142 }
143
144 /**
145 * Injects a QueryFactory instance
146 *
147 * @param Tx_Extbase_Persistence_QueryFactoryInterface $queryFactory
148 * @return void
149 */
150 public function injectQueryFactory(Tx_Extbase_Persistence_QueryFactoryInterface $queryFactory) {
151 $this->queryFactory = $queryFactory;
152 }
153
154 /**
155 * Returns the name of this argument
156 *
157 * @return string This argument's name
158 * @api
159 */
160 public function getName() {
161 return $this->name;
162 }
163
164 /**
165 * Sets the short name of this argument.
166 *
167 * @param string $shortName A "short name" - a single character
168 * @return Tx_Extbase_MVC_Controller_Argument $this
169 * @throws InvalidArgumentException if $shortName is not a character
170 * @api
171 */
172 public function setShortName($shortName) {
173 if ($shortName !== NULL && (!is_string($shortName) || strlen($shortName) !== 1)) throw new InvalidArgumentException('$shortName must be a single character or NULL', 1195824959);
174 $this->shortName = $shortName;
175 return $this;
176 }
177
178 /**
179 * Returns the short name of this argument
180 *
181 * @return string This argument's short name
182 * @api
183 */
184 public function getShortName() {
185 return $this->shortName;
186 }
187
188 /**
189 * Sets the data type of this argument's value
190 *
191 * @param string $dataType The data type. Can be either a built-in type such as "Text" or "Integer" or a fully qualified object name
192 * @return Tx_Extbase_MVC_Controller_Argument $this
193 * @api
194 */
195 public function setDataType($dataType) {
196 $this->dataType = $dataType;
197 $this->dataTypeClassSchema = $this->reflectionService->getClassSchema($this->dataType);
198 return $this;
199 }
200
201 /**
202 * Returns the data type of this argument's value
203 *
204 * @return string The data type
205 * @api
206 */
207 public function getDataType() {
208 return $this->dataType;
209 }
210
211 /**
212 * Marks this argument to be required
213 *
214 * @param boolean $required TRUE if this argument should be required
215 * @return Tx_Extbase_MVC_Controller_Argument $this
216 * @api
217 */
218 public function setRequired($required) {
219 $this->isRequired = (boolean)$required;
220 return $this;
221 }
222
223 /**
224 * Returns TRUE if this argument is required
225 *
226 * @return boolean TRUE if this argument is required
227 * @api
228 */
229 public function isRequired() {
230 return $this->isRequired;
231 }
232
233 /**
234 * Sets the default value of the argument
235 *
236 * @param mixed $defaultValue Default value
237 * @return void
238 * @api
239 */
240 public function setDefaultValue($defaultValue) {
241 $this->defaultValue = $defaultValue;
242 }
243
244 /**
245 * Returns the default value of this argument
246 *
247 * @return mixed The default value
248 * @api
249 */
250 public function getDefaultValue() {
251 return $this->defaultValue;
252 }
253
254 /**
255 * Sets a custom validator which is used supplementary to the base validation
256 *
257 * @param Tx_Extbase_Validation_Validator_ValidatorInterface $validator The actual validator object
258 * @return Tx_Extbase_MVC_Controller_Argument Returns $this (used for fluent interface)
259 * @api
260 */
261 public function setValidator(Tx_Extbase_Validation_Validator_ValidatorInterface $validator) {
262 $this->validator = $validator;
263 return $this;
264 }
265
266 /**
267 * Create and set a validator chain
268 *
269 * @param array Object names of the validators
270 * @return Tx_Extbase_MVC_Controller_Argument Returns $this (used for fluent interface)
271 * @api
272 */
273 public function setNewValidatorConjunction(array $objectNames) {
274 if ($this->validator === NULL) {
275 $this->validator = t3lib_div::makeInstance('Tx_Extbase_Validation_Validator_ConjunctionValidator');
276 }
277 foreach ($objectNames as $objectName) {
278 if (!class_exists($objectName)) $objectName = 'Tx_Extbase_Validation_Validator_' . $objectName;
279 $this->validator->addValidator(t3lib_div::makeInstance($objectName));
280 }
281 return $this;
282 }
283
284 /**
285 * Returns the set validator
286 *
287 * @return Tx_Extbase_Validation_Validator_ValidatorInterface The set validator, NULL if none was set
288 * @api
289 */
290 public function getValidator() {
291 return $this->validator;
292 }
293
294 /**
295 * Returns TRUE if validation is temporarily disabled for this argument and
296 * FALSE if it's enabled.
297 *
298 * Note that this is flag is only informational and does not have any real impact
299 * on other validation methods of this argument.
300 *
301 * @return boolean If validation is disabled
302 * @api
303 */
304 public function isValidationDisabled() {
305 return $this->validationDisabled;
306 }
307
308 /**
309 * Enables validation for this argument.
310 *
311 * @return void
312 * @api
313 */
314 public function enableValidation() {
315 $this->validationDisabled = FALSE;
316 }
317
318 /**
319 * Disables validation for this argument.
320 *
321 * @return void
322 * @api
323 */
324 public function disableValidation() {
325 $this->validationDisabled = TRUE;
326 }
327
328 /**
329 * Sets the value of this argument.
330 *
331 * @param mixed $value: The value of this argument
332 * @return Tx_Extbase_MVC_Controller_Argument $this
333 * @throws Tx_Extbase_MVC_Exception_InvalidArgumentValue if the argument is not a valid object of type $dataType
334 */
335 public function setValue($value) {
336 if ($value !== NULL && $this->dataTypeClassSchema !== NULL) {
337 if (is_numeric($value)) {
338 $value = $this->findObjectByUid($value);
339 } elseif (is_array($value)) {
340 $value = $this->propertyMapper->map(array_keys($value), $value, $this->dataType);
341 }
342
343 if (!($value instanceof $this->dataType)) {
344 throw new Tx_Extbase_MVC_Exception_InvalidArgumentValue('The value must be of type "' . $this->dataType . '".', 1251730701);
345 }
346 }
347 $this->value = $value;
348
349 return $this;
350 }
351
352 /**
353 * Finds an object from the repository by searching for its technical UID.
354 *
355 * @param int $uid The object's uid
356 * @return mixed Either the object matching the uid or, if none or more than one object was found, FALSE
357 */
358 protected function findObjectByUid($uid) {
359 $query = $this->queryFactory->create($this->dataType);
360 $result = $query->matching($query->withUid($uid))->execute();
361 $object = NULL;
362 if (count($result) > 0) {
363 $object = current($result);
364 }
365 return $object;
366 }
367
368 /**
369 * Returns the value of this argument
370 *
371 * @return object The value of this argument - if none was set, NULL is returned
372 * @api
373 */
374 public function getValue() {
375 if ($this->value === NULL) {
376 return $this->defaultValue;
377 } else {
378 return $this->value;
379 }
380 }
381
382 /**
383 * Checks if this argument has a value set.
384 *
385 * @return boolean TRUE if a value was set, otherwise FALSE
386 */
387 public function isValue() {
388 return $this->value !== NULL;
389 }
390
391 /**
392 * Returns a string representation of this argument's value
393 *
394 * @return string
395 * @api
396 */
397 public function __toString() {
398 return (string)$this->value;
399 }
400 }
401 ?>