2 /***************************************************************
5 * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
8 * This class is a backport of the corresponding class of FLOW3.
9 * All credits go to the v5 team.
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.
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
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.
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
29 * A controller argument
32 * @subpackage MVC\Controller
36 class Tx_Extbase_MVC_Controller_Argument
{
39 * @var Tx_Extbase_Persistence_QueryFactory
41 protected $queryFactory;
44 * @var Tx_Extbase_Property_Mapper
46 protected $propertyMapper;
49 * @var Tx_Extbase_Reflection_Service
51 protected $reflectionService;
54 * Name of this argument
60 * Short name of this argument
63 protected $shortName = NULL;
66 * Data type of this argument's value
69 protected $dataType = 'Text';
72 * If the data type is an object, the class schema of the data type class is resolved
73 * @var Tx_Extbase_Reflection_ClassSchema
75 protected $dataTypeClassSchema;
78 * TRUE if this argument is required
81 protected $isRequired = FALSE;
84 * Actual value of this argument
87 protected $value = NULL;
90 * Default value. Used if argument is optional.
93 protected $defaultValue = NULL;
96 * A custom validator, used supplementary to the base validation
97 * @var Tx_Extbase_Validation_Validator_ValidatorInterface
99 protected $validator = NULL;
102 * Uid for the argument, if it has one
105 protected $uid = NULL;
108 * Constructs this controller argument
110 * @param string $name Name of this argument
111 * @param string $dataType The data type of this argument
112 * @throws InvalidArgumentException if $name is not a string or empty
115 public function __construct($name, $dataType = 'Text') {
116 $this->reflectionService
= t3lib_div
::makeInstance('Tx_Extbase_Reflection_Service');
117 $this->propertyMapper
= t3lib_div
::makeInstance('Tx_Extbase_Property_Mapper');
118 $this->propertyMapper
->injectReflectionService($this->reflectionService
);
119 if (!is_string($name) ||
strlen($name) < 1) throw new InvalidArgumentException('$name must be of type string, ' . gettype($name) . ' given.', 1187951688);
121 $this->setDataType($dataType);
125 * Injects the Persistence Manager
127 * @param Tx_Extbase_Persistence_ManagerInterface
130 public function injectPersistenceManager(Tx_Extbase_Persistence_ManagerInterface
$persistenceManager) {
131 $this->persistenceManager
= $persistenceManager;
135 * Injects a QueryFactory instance
137 * @param Tx_Extbase_Persistence_QueryFactoryInterface $queryFactory
140 public function injectQueryFactory(Tx_Extbase_Persistence_QueryFactoryInterface
$queryFactory) {
141 $this->queryFactory
= $queryFactory;
145 * Returns the name of this argument
147 * @return string This argument's name
150 public function getName() {
155 * Sets the short name of this argument.
157 * @param string $shortName A "short name" - a single character
158 * @return Tx_Extbase_MVC_Controller_Argument $this
159 * @throws InvalidArgumentException if $shortName is not a character
162 public function setShortName($shortName) {
163 if ($shortName !== NULL && (!is_string($shortName) ||
strlen($shortName) !== 1)) throw new InvalidArgumentException('$shortName must be a single character or NULL', 1195824959);
164 $this->shortName
= $shortName;
169 * Returns the short name of this argument
171 * @return string This argument's short name
174 public function getShortName() {
175 return $this->shortName
;
179 * Sets the data type of this argument's value
181 * @param string $dataType The data type. Can be either a built-in type such as "Text" or "Integer" or a fully qualified object name
182 * @return Tx_Extbase_MVC_Controller_Argument $this
185 public function setDataType($dataType) {
186 $this->dataType
= $dataType;
187 $this->dataTypeClassSchema
= $this->reflectionService
->getClassSchema($this->dataType
);
192 * Returns the data type of this argument's value
194 * @return string The data type
197 public function getDataType() {
198 return $this->dataType
;
202 * Marks this argument to be required
204 * @param boolean $required TRUE if this argument should be required
205 * @return Tx_Extbase_MVC_Controller_Argument $this
208 public function setRequired($required) {
209 $this->isRequired
= (boolean
)$required;
214 * Returns TRUE if this argument is required
216 * @return boolean TRUE if this argument is required
219 public function isRequired() {
220 return $this->isRequired
;
224 * Sets the default value of the argument
226 * @param mixed $defaultValue Default value
230 public function setDefaultValue($defaultValue) {
231 $this->defaultValue
= $defaultValue;
235 * Returns the default value of this argument
237 * @return mixed The default value
240 public function getDefaultValue() {
241 return $this->defaultValue
;
245 * Sets a custom validator which is used supplementary to the base validation
247 * @param Tx_Extbase_Validation_Validator_ValidatorInterface $validator The actual validator object
248 * @return Tx_Extbase_MVC_Controller_Argument Returns $this (used for fluent interface)
251 public function setValidator(Tx_Extbase_Validation_Validator_ValidatorInterface
$validator) {
252 $this->validator
= $validator;
257 * Create and set a validator chain
259 * @param array Object names of the validators
260 * @return Tx_Extbase_MVC_Controller_Argument Returns $this (used for fluent interface)
263 public function setNewValidatorConjunction(array $objectNames) {
264 if ($this->validator
=== NULL) {
265 $this->validator
= t3lib_div
::makeInstance('Tx_Extbase_Validation_Validator_ConjunctionValidator');
267 foreach ($objectNames as $objectName) {
268 if (!class_exists($objectName)) $objectName = 'Tx_Extbase_Validation_Validator_' . $objectName;
269 $this->validator
->addValidator(t3lib_div
::makeInstance($objectName));
275 * Returns the set validator
277 * @return Tx_Extbase_Validation_Validator_ValidatorInterface The set validator, NULL if none was set
280 public function getValidator() {
281 return $this->validator
;
285 * Sets the value of this argument.
287 * @param mixed $value: The value of this argument
288 * @return Tx_Extbase_MVC_Controller_Argument $this
289 * @throws Tx_Extbase_MVC_Exception_InvalidArgumentValue if the argument is not a valid object of type $dataType
291 public function setValue($value) {
292 $this->value
= $this->transformValue($value);
298 * Checks if the value is a UUID or an array but should be an object, i.e.
299 * the argument's data type class schema is set. If that is the case, this
300 * method tries to look up the corresponding object instead.
302 * Additionally, it maps arrays to objects in case it is a normal object.
304 * @param mixed $value The value of an argument
307 protected function transformValue($value) {
308 if ($value === NULL) {
311 if (!class_exists($this->dataType
)) {
314 $transformedValue = NULL;
315 if ($this->dataTypeClassSchema
!== NULL) {
316 // It is an Entity or ValueObject.
317 if (is_numeric($value)) {
318 $transformedValue = $this->findObjectByUid($value);
319 } elseif (is_array($value)) {
320 $transformedValue = $this->propertyMapper
->map(array_keys($value), $value, $this->dataType
);
323 if (!is_array($value)) {
324 throw new Tx_Extbase_MVC_Exception_InvalidArgumentValue('The value was a simple type, so we could not map it to an object. Maybe the @entity or @valueobject annotations are missing?', 1251730701);
326 $transformedValue = $this->propertyMapper
->map(array_keys($value), $value, $this->dataType
);
329 if (!($transformedValue instanceof $this->dataType
)) {
330 throw new Tx_Extbase_MVC_Exception_InvalidArgumentValue('The value must be of type "' . $this->dataType
. '", but was of type "' . get_class($transformedValue) . '".', 1251730701);
332 return $transformedValue;
336 * Finds an object from the repository by searching for its technical UID.
338 * @param int $uid The object's uid
339 * @return mixed Either the object matching the uid or, if none or more than one object was found, FALSE
341 protected function findObjectByUid($uid) {
342 $query = $this->queryFactory
->create($this->dataType
);
343 $result = $query->matching($query->withUid($uid))->execute();
345 if (count($result) > 0) {
346 $object = current($result);
352 * Returns the value of this argument
354 * @return object The value of this argument - if none was set, NULL is returned
357 public function getValue() {
358 if ($this->value
=== NULL) {
359 return $this->defaultValue
;
366 * Checks if this argument has a value set.
368 * @return boolean TRUE if a value was set, otherwise FALSE
370 public function isValue() {
371 return $this->value
!== NULL;
375 * Returns a string representation of this argument's value
380 public function __toString() {
381 return (string)$this->value
;