Extbase:
[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
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 * Name of this argument
50 * @var string
51 */
52 protected $name = '';
53
54 /**
55 * Short name of this argument
56 * @var string
57 */
58 protected $shortName = NULL;
59
60 /**
61 * Data type of this argument's value
62 * @var string
63 */
64 protected $dataType = 'Text';
65
66 /**
67 * TRUE if this argument is required
68 * @var boolean
69 */
70 protected $isRequired = FALSE;
71
72 /**
73 * Actual value of this argument
74 * @var object
75 */
76 protected $value = NULL;
77
78 /**
79 * Default value. Used if argument is optional.
80 * @var mixed
81 */
82 protected $defaultValue = NULL;
83
84 /**
85 * A custom validator, used supplementary to the base validation
86 * @var Tx_Extbase_Validation_Validator_ValidatorInterface
87 */
88 protected $validator = NULL;
89
90 /**
91 * Uid for the argument, if it has one
92 * @var string
93 */
94 protected $uid = NULL;
95
96 /**
97 * Constructs this controller argument
98 *
99 * @param string $name Name of this argument
100 * @param string $dataType The data type of this argument
101 * @throws InvalidArgumentException if $name is not a string or empty
102 */
103 public function __construct($name, $dataType = 'Text') {
104 // $this->queryFactory = t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryFactory');
105 $this->propertyMapper = t3lib_div::makeInstance('Tx_Extbase_Property_Mapper');
106 if (!is_string($name) || strlen($name) < 1) throw new InvalidArgumentException('$name must be of type string, ' . gettype($name) . ' given.', 1187951688);
107 $this->name = $name;
108 if (is_array($dataType)) {
109 $this->setNewValidatorChain($dataType);
110 } else {
111 $this->setDataType($dataType);
112 }
113 }
114
115 /**
116 * Returns the name of this argument
117 *
118 * @return string This argument's name
119 */
120 public function getName() {
121 return $this->name;
122 }
123
124 /**
125 * Sets the short name of this argument.
126 *
127 * @param string $shortName A "short name" - a single character
128 * @return Tx_Extbase_MVC_Controller_Argument $this
129 * @throws InvalidArgumentException if $shortName is not a character
130 */
131 public function setShortName($shortName) {
132 if ($shortName !== NULL && (!is_string($shortName) || strlen($shortName) !== 1)) throw new InvalidArgumentException('$shortName must be a single character or NULL', 1195824959);
133 $this->shortName = $shortName;
134 return $this;
135 }
136
137 /**
138 * Returns the short name of this argument
139 *
140 * @return string This argument's short name
141 */
142 public function getShortName() {
143 return $this->shortName;
144 }
145
146 /**
147 * Sets the data type of this argument's value
148 *
149 * @param string $dataType The data type. Can be either a built-in type such as "Text" or "Integer" or a fully qualified object name
150 * @return Tx_Extbase_MVC_Controller_Argument $this
151 */
152 public function setDataType($dataType) {
153 $this->dataType = $dataType;
154 return $this;
155 }
156
157 /**
158 * Returns the data type of this argument's value
159 *
160 * @return string The data type
161 */
162 public function getDataType() {
163 return $this->dataType;
164 }
165
166 /**
167 * Marks this argument to be required
168 *
169 * @param boolean $required TRUE if this argument should be required
170 * @return Tx_Extbase_MVC_Controller_Argument $this
171 */
172 public function setRequired($required) {
173 $this->isRequired = (boolean)$required;
174 return $this;
175 }
176
177 /**
178 * Returns TRUE if this argument is required
179 *
180 * @return boolean TRUE if this argument is required
181 */
182 public function isRequired() {
183 return $this->isRequired;
184 }
185
186 /**
187 * Sets the default value of the argument
188 *
189 * @param mixed $defaultValue Default value
190 * @return void
191 */
192 public function setDefaultValue($defaultValue) {
193 $this->defaultValue = $defaultValue;
194 }
195
196 /**
197 * Returns the default value of this argument
198 *
199 * @return mixed The default value
200 */
201 public function getDefaultValue() {
202 return $this->defaultValue;
203 }
204
205 /**
206 * Sets a custom validator which is used supplementary to the base validation
207 *
208 * @param Tx_Extbase_Validation_Validator_ValidatorInterface $validator The actual validator object
209 * @return Tx_Extbase_MVC_Controller_Argument Returns $this (used for fluent interface)
210 */
211 public function setValidator(Tx_Extbase_Validation_Validator_ValidatorInterface $validator) {
212 $this->validator = $validator;
213 return $this;
214 }
215
216 /**
217 * Create and set a validator chain
218 *
219 * @param array Object names of the validators
220 * @return Tx_Extbase_MVC_Controller_Argument Returns $this (used for fluent interface)
221 */
222 public function setNewValidatorChain(array $objectNames) {
223 if ($this->validator === NULL) {
224 $this->validator = t3lib_div::makeInstance('Tx_Extbase_Validation_Validator_ChainValidator');
225 }
226 foreach ($objectNames as $objectName) {
227 if (!class_exists($objectName)) $objectName = 'Tx_Extbase_Validation_Validator_' . $objectName;
228 $this->validator->addValidator(t3lib_div::makeInstance($objectName));
229 }
230 return $this;
231 }
232 /**
233 * Returns the set validator
234 *
235 * @return Tx_Extbase_Validation_Validator_ValidatorInterface The set validator, NULL if none was set
236 */
237 public function getValidator() {
238 return $this->validator;
239 }
240
241 /**
242 * Sets the value of this argument.
243 *
244 * @param mixed $value: The value of this argument
245 * @return Tx_Extbase_MVC_Controller_Argument $this
246 * @throws Tx_Extbase_MVC_Exception_InvalidArgumentValue if the argument is not a valid object of type $dataType
247 */
248 public function setValue($value) {
249 if (is_array($value)) {
250 if (isset($value['uid'])) {
251 $existingObject = $this->findObjectByUid($value['uid']);
252 if ($existingObject === FALSE) throw new Tx_Extbase_MVC_Exception_InvalidArgumentValue('Argument "' . $this->name . '": Querying the repository for the specified object was not sucessful.', 1237305720);
253 unset($value['uid']);
254 if (count($value) === 0) {
255 $value = $existingObject;
256 } elseif ($existingObject !== NULL) {
257 $newObject = clone $existingObject;
258 if ($this->propertyMapper->map(array_keys($value), $value, $newObject)) {
259 $value = $newObject;
260 }
261 }
262 } else {
263 $newObject = t3lib_div::makeInstance($this->dataType);
264 if ($this->propertyMapper->map(array_keys($value), $value, $newObject)) {
265 $value = $newObject;
266 }
267 }
268 }
269 $this->value = $value;
270 return $this;
271 }
272
273 /**
274 * Finds an object from the repository by searching for its technical UID.
275 *
276 * @param int $uid The object's uid
277 * @return mixed Either the object matching the uid or, if none or more than one object was found, FALSE
278 */
279 protected function findObjectByUid($uid) {
280 $repositoryClassName = $this->dataType . 'Repository';
281 if (class_exists($repositoryClassName)) {
282 $repository = t3lib_div::makeInstance($this->dataType . 'Repository');
283 $object = $repository->findOneByUid($uid);
284 }
285 return $object;
286 // TODO replace code as soon as the query object is available
287 // $query = $this->queryFactory->create($this->dataType);
288 // $query->matching('uid=' . intval($uid));
289 // $objects = $query->execute();
290 // if (count($objects) === 1 ) return current($objects);
291 // return FALSE;
292 }
293
294 /**
295 * Returns the value of this argument
296 *
297 * @return object The value of this argument - if none was set, NULL is returned
298 */
299 public function getValue() {
300 if ($this->value === NULL) {
301 return $this->defaultValue;
302 } else {
303 return $this->value;
304 }
305 }
306
307 /**
308 * Checks if this argument has a value set.
309 *
310 * @return boolean TRUE if a value was set, otherwise FALSE
311 */
312 public function isValue() {
313 return $this->value !== NULL;
314 }
315
316 /**
317 * Returns a string representation of this argument's value
318 *
319 * @return string
320 */
321 public function __toString() {
322 return (string)$this->value;
323 }
324 }
325 ?>