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