[BUGFIX] Extbase: Optional arguments must not throw an Exception
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Mvc / Controller / Argument.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Mvc\Controller;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Extbase\Property\Exception\TargetNotFoundException;
18 use TYPO3\CMS\Extbase\Utility\TypeHandlingUtility;
19
20 /**
21 * A controller argument
22 *
23 * @api
24 */
25 class Argument {
26
27 /**
28 * @var \TYPO3\CMS\Extbase\Property\PropertyMapper
29 */
30 protected $propertyMapper;
31
32 /**
33 * @var MvcPropertyMappingConfiguration
34 */
35 protected $propertyMappingConfiguration;
36
37 /**
38 * Name of this argument
39 *
40 * @var string
41 */
42 protected $name = '';
43
44 /**
45 * Short name of this argument
46 *
47 * @var string
48 */
49 protected $shortName = NULL;
50
51 /**
52 * Data type of this argument's value
53 *
54 * @var string
55 */
56 protected $dataType = NULL;
57
58 /**
59 * TRUE if this argument is required
60 *
61 * @var bool
62 */
63 protected $isRequired = FALSE;
64
65 /**
66 * Actual value of this argument
67 *
68 * @var mixed
69 */
70 protected $value = NULL;
71
72 /**
73 * Default value. Used if argument is optional.
74 *
75 * @var mixed
76 */
77 protected $defaultValue = NULL;
78
79 /**
80 * A custom validator, used supplementary to the base validation
81 *
82 * @var \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface
83 */
84 protected $validator = NULL;
85
86 /**
87 * The validation results. This can be asked if the argument has errors.
88 *
89 * @var \TYPO3\CMS\Extbase\Error\Result
90 */
91 protected $validationResults = NULL;
92
93 /**
94 * @param \TYPO3\CMS\Extbase\Property\PropertyMapper $propertyMapper
95 */
96 public function injectPropertyMapper(\TYPO3\CMS\Extbase\Property\PropertyMapper $propertyMapper) {
97 $this->propertyMapper = $propertyMapper;
98 }
99
100 /**
101 * @param \TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfiguration $propertyMappingConfiguration
102 */
103 public function injectPropertyMappingConfiguration(MvcPropertyMappingConfiguration $propertyMappingConfiguration) {
104 $this->propertyMappingConfiguration = $propertyMappingConfiguration;
105 }
106
107 /**
108 * Constructs this controller argument
109 *
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
113 * @api
114 */
115 public function __construct($name, $dataType) {
116 if (!is_string($name)) {
117 throw new \InvalidArgumentException('$name must be of type string, ' . gettype($name) . ' given.', 1187951688);
118 }
119 if ($name === '') {
120 throw new \InvalidArgumentException('$name must be a non-empty string.', 1232551853);
121 }
122 $this->name = $name;
123 $this->dataType = TypeHandlingUtility::normalizeType($dataType);
124 }
125
126 /**
127 * Returns the name of this argument
128 *
129 * @return string This argument's name
130 * @api
131 */
132 public function getName() {
133 return $this->name;
134 }
135
136 /**
137 * Sets the short name of this argument.
138 *
139 * @param string $shortName A "short name" - a single character
140 * @throws \InvalidArgumentException if $shortName is not a character
141 * @return \TYPO3\CMS\Extbase\Mvc\Controller\Argument $this
142 * @api
143 */
144 public function setShortName($shortName) {
145 if ($shortName !== NULL && (!is_string($shortName) || strlen($shortName) !== 1)) {
146 throw new \InvalidArgumentException('$shortName must be a single character or NULL', 1195824959);
147 }
148 $this->shortName = $shortName;
149 return $this;
150 }
151
152 /**
153 * Returns the short name of this argument
154 *
155 * @return string This argument's short name
156 * @api
157 */
158 public function getShortName() {
159 return $this->shortName;
160 }
161
162 /**
163 * Returns the data type of this argument's value
164 *
165 * @return string The data type
166 * @api
167 */
168 public function getDataType() {
169 return $this->dataType;
170 }
171
172 /**
173 * Marks this argument to be required
174 *
175 * @param bool $required TRUE if this argument should be required
176 * @return \TYPO3\CMS\Extbase\Mvc\Controller\Argument $this
177 * @api
178 */
179 public function setRequired($required) {
180 $this->isRequired = (bool)$required;
181 return $this;
182 }
183
184 /**
185 * Returns TRUE if this argument is required
186 *
187 * @return bool TRUE if this argument is required
188 * @api
189 */
190 public function isRequired() {
191 return $this->isRequired;
192 }
193
194 /**
195 * Sets the default value of the argument
196 *
197 * @param mixed $defaultValue Default value
198 * @return \TYPO3\CMS\Extbase\Mvc\Controller\Argument $this
199 * @api
200 */
201 public function setDefaultValue($defaultValue) {
202 $this->defaultValue = $defaultValue;
203 return $this;
204 }
205
206 /**
207 * Returns the default value of this argument
208 *
209 * @return mixed The default value
210 * @api
211 */
212 public function getDefaultValue() {
213 return $this->defaultValue;
214 }
215
216 /**
217 * Sets a custom validator which is used supplementary to the base validation
218 *
219 * @param \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $validator The actual validator object
220 * @return \TYPO3\CMS\Extbase\Mvc\Controller\Argument Returns $this (used for fluent interface)
221 * @api
222 */
223 public function setValidator(\TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $validator) {
224 $this->validator = $validator;
225 return $this;
226 }
227
228 /**
229 * Returns the set validator
230 *
231 * @return \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface The set validator, NULL if none was set
232 * @api
233 */
234 public function getValidator() {
235 return $this->validator;
236 }
237
238 /**
239 * Sets the value of this argument.
240 *
241 * @param mixed $rawValue The value of this argument
242 *
243 * @return \TYPO3\CMS\Extbase\Mvc\Controller\Argument
244 * @throws \TYPO3\CMS\Extbase\Property\Exception
245 */
246 public function setValue($rawValue) {
247 if ($rawValue === NULL) {
248 $this->value = NULL;
249 return $this;
250 }
251 if (is_object($rawValue) && $rawValue instanceof $this->dataType) {
252 $this->value = $rawValue;
253 return $this;
254 }
255 try {
256 $this->value = $this->propertyMapper->convert($rawValue, $this->dataType, $this->propertyMappingConfiguration);
257 } catch (TargetNotFoundException $e) {
258 // for optional arguments no exeption is thrown.
259 if ($this->isRequired()) {
260 throw $e;
261 }
262 }
263 $this->validationResults = $this->propertyMapper->getMessages();
264 if ($this->validator !== NULL) {
265 // @todo Validation API has also changed!!!
266 $validationMessages = $this->validator->validate($this->value);
267 $this->validationResults->merge($validationMessages);
268 }
269 return $this;
270 }
271
272 /**
273 * Returns the value of this argument
274 *
275 * @return mixed The value of this argument - if none was set, NULL is returned
276 * @api
277 */
278 public function getValue() {
279 if ($this->value === NULL) {
280 return $this->defaultValue;
281 } else {
282 return $this->value;
283 }
284 }
285
286 /**
287 * Return the Property Mapping Configuration used for this argument; can be used by the initialize*action to modify the Property Mapping.
288 *
289 * @return \TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfiguration
290 * @api
291 */
292 public function getPropertyMappingConfiguration() {
293 return $this->propertyMappingConfiguration;
294 }
295
296 /**
297 * @return bool TRUE if the argument is valid, FALSE otherwise
298 * @api
299 */
300 public function isValid() {
301 return !$this->validationResults->hasErrors();
302 }
303
304 /**
305 * @return \TYPO3\CMS\Extbase\Error\Result Validation errors which have occurred.
306 * @api
307 */
308 public function getValidationResults() {
309 return $this->validationResults;
310 }
311
312 /**
313 * Returns a string representation of this argument's value
314 *
315 * @return string
316 * @api
317 */
318 public function __toString() {
319 return (string)$this->value;
320 }
321
322 }