[TASK] Use arrays in str_replace() calls
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Mvc / Request.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Mvc;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2010-2013 Extbase Team (http://forge.typo3.org/projects/typo3v4-mvc)
8 * Extbase is a backport of TYPO3 Flow. All credits go to the TYPO3 Flow team.
9 * All rights reserved
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 * A copy is found in the textfile GPL.txt and important notices to the license
20 * from the author is found in LICENSE.txt distributed with these scripts.
21 *
22 *
23 * This script is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * This copyright notice MUST APPEAR in all copies of the script!
29 ***************************************************************/
30
31 use TYPO3\CMS\Core\Utility\ClassNamingUtility;
32
33 /**
34 * Represents a generic request.
35 *
36 * @api
37 */
38 class Request implements \TYPO3\CMS\Extbase\Mvc\RequestInterface {
39
40 const PATTERN_MATCH_FORMAT = '/^[a-z0-9]{1,5}$/';
41
42 /**
43 * Pattern after which the controller object name is built
44 *
45 * @var string
46 */
47 protected $controllerObjectNamePattern = 'Tx_@extension_@subpackage_Controller_@controllerController';
48
49 /**
50 * Pattern after which the namespaced controller object name is built
51 *
52 * @var string
53 */
54 protected $namespacedControllerObjectNamePattern = '@vendor\@extension\@subpackage\Controller\@controllerController';
55
56 /**
57 * @var string Key of the plugin which identifies the plugin. It must be a string containing [a-z0-9]
58 */
59 protected $pluginName = '';
60
61 /**
62 * @var string Name of the extension which is supposed to handle this request. This is the extension name converted to UpperCamelCase
63 */
64 protected $controllerExtensionName = NULL;
65
66 /**
67 * @var string vendor prefix
68 */
69 protected $controllerVendorName = NULL;
70
71 /**
72 * Subpackage key of the controller which is supposed to handle this request.
73 *
74 * @var string
75 */
76 protected $controllerSubpackageKey = NULL;
77
78 /**
79 * @var string Object name of the controller which is supposed to handle this request.
80 */
81 protected $controllerName = 'Standard';
82
83 /**
84 * @var string Name of the action the controller is supposed to take.
85 */
86 protected $controllerActionName = 'index';
87
88 /**
89 * @var array The arguments for this request
90 */
91 protected $arguments = array();
92
93 /**
94 * Framework-internal arguments for this request, such as __referrer.
95 * All framework-internal arguments start with double underscore (__),
96 * and are only used from within the framework. Not for user consumption.
97 * Internal Arguments can be objects, in contrast to public arguments
98 *
99 * @var array
100 */
101 protected $internalArguments = array();
102
103 /**
104 * @var string The requested representation format
105 */
106 protected $format = 'txt';
107
108 /**
109 * @var boolean If this request has been changed and needs to be dispatched again
110 */
111 protected $dispatched = FALSE;
112
113 /**
114 * If this request is a forward because of an error, the original request gets filled.
115 *
116 * @var \TYPO3\CMS\Extbase\Mvc\Request
117 */
118 protected $originalRequest = NULL;
119
120 /**
121 * If the request is a forward because of an error, these mapping results get filled here.
122 *
123 * @var \TYPO3\CMS\Extbase\Error\Result
124 */
125 protected $originalRequestMappingResults = NULL;
126
127 /**
128 * @var array Errors that occured during this request
129 * @deprecated since Extbase 1.4.0, will be removed two versions after Extbase 6.1
130 */
131 protected $errors = array();
132
133 /**
134 * Sets the dispatched flag
135 *
136 * @param boolean $flag If this request has been dispatched
137 *
138 * @return void
139 * @api
140 */
141 public function setDispatched($flag) {
142 $this->dispatched = $flag ? TRUE : FALSE;
143 }
144
145 /**
146 * If this request has been dispatched and addressed by the responsible
147 * controller and the response is ready to be sent.
148 *
149 * The dispatcher will try to dispatch the request again if it has not been
150 * addressed yet.
151 *
152 * @return boolean TRUE if this request has been disptached sucessfully
153 * @api
154 */
155 public function isDispatched() {
156 return $this->dispatched;
157 }
158
159 /**
160 * Returns the object name of the controller defined by the extension name and
161 * controller name
162 *
163 * @return string The controller's Object Name
164 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchControllerException if the controller does not exist
165 * @api
166 */
167 public function getControllerObjectName() {
168 if (NULL !== $this->controllerVendorName) {
169 // It's safe to assume a namespaced name as namespaced names have to follow PSR-0
170 $objectName = str_replace(
171 array(
172 '@extension',
173 '@subpackage',
174 '@controller',
175 '@vendor',
176 '\\\\'
177 ),
178 array(
179 $this->controllerExtensionName,
180 $this->controllerSubpackageKey,
181 $this->controllerName,
182 $this->controllerVendorName,
183 '\\'
184 ),
185 $this->namespacedControllerObjectNamePattern
186 );
187 } else {
188 $objectName = str_replace(
189 array(
190 '@extension',
191 '@subpackage',
192 '@controller',
193 '__'
194 ),
195 array(
196 $this->controllerExtensionName,
197 $this->controllerSubpackageKey,
198 $this->controllerName,
199 '_'
200 ),
201 $this->controllerObjectNamePattern
202 );
203 }
204 // TODO implement getCaseSensitiveObjectName()
205 if ($objectName === FALSE) {
206 throw new \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchControllerException('The controller object "' . $objectName . '" does not exist.', 1220884009);
207 }
208 return $objectName;
209 }
210
211 /**
212 * Explicitly sets the object name of the controller
213 *
214 * @param string $controllerObjectName The fully qualified controller object name
215 *
216 * @return void
217 */
218 public function setControllerObjectName($controllerObjectName) {
219 $nameParts = ClassNamingUtility::explodeObjectControllerName($controllerObjectName);
220 $this->controllerVendorName = isset($nameParts['vendorName']) ? $nameParts['vendorName'] : NULL;
221 $this->controllerExtensionName = $nameParts['extensionName'];
222 $this->controllerSubpackageKey = isset($nameParts['subpackageKey']) ? $nameParts['subpackageKey'] : NULL;
223 $this->controllerName = $nameParts['controllerName'];
224 }
225
226 /**
227 * Sets the plugin name.
228 *
229 * @param string|NULL $pluginName
230 *
231 * @return void
232 */
233 public function setPluginName($pluginName = NULL) {
234 if ($pluginName !== NULL) {
235 $this->pluginName = $pluginName;
236 }
237 }
238
239 /**
240 * Returns the plugin key.
241 *
242 * @return string The plugin key
243 * @api
244 */
245 public function getPluginName() {
246 return $this->pluginName;
247 }
248
249 /**
250 * Sets the extension name of the controller.
251 *
252 * @param string $controllerExtensionName The extension name.
253 *
254 * @return void
255 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidExtensionNameException if the extension name is not valid
256 */
257 public function setControllerExtensionName($controllerExtensionName) {
258 if ($controllerExtensionName !== NULL) {
259 $this->controllerExtensionName = $controllerExtensionName;
260 }
261 }
262
263 /**
264 * Returns the extension name of the specified controller.
265 *
266 * @return string The extension name
267 * @api
268 */
269 public function getControllerExtensionName() {
270 return $this->controllerExtensionName;
271 }
272
273 /**
274 * Returns the extension name of the specified controller.
275 *
276 * @return string The extension key
277 * @api
278 */
279 public function getControllerExtensionKey() {
280 return \TYPO3\CMS\Core\Utility\GeneralUtility::camelCaseToLowerCaseUnderscored($this->controllerExtensionName);
281 }
282
283 /**
284 * Sets the subpackage key of the controller.
285 *
286 * @param string $subpackageKey The subpackage key.
287 *
288 * @return void
289 */
290 public function setControllerSubpackageKey($subpackageKey) {
291 $this->controllerSubpackageKey = $subpackageKey;
292 }
293
294 /**
295 * Returns the subpackage key of the specified controller.
296 * If there is no subpackage key set, the method returns NULL
297 *
298 * @return string The subpackage key
299 */
300 public function getControllerSubpackageKey() {
301 return $this->controllerSubpackageKey;
302 }
303
304 /**
305 * Sets the name of the controller which is supposed to handle the request.
306 * Note: This is not the object name of the controller!
307 *
308 * @param string $controllerName Name of the controller
309 *
310 * @throws Exception\InvalidControllerNameException
311 * @return void
312 */
313 public function setControllerName($controllerName) {
314 if (!is_string($controllerName) && $controllerName !== NULL) {
315 throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidControllerNameException('The controller name must be a valid string, ' . gettype($controllerName) . ' given.', 1187176358);
316 }
317 if (strpos($controllerName, '_') !== FALSE) {
318 throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidControllerNameException('The controller name must not contain underscores.', 1217846412);
319 }
320 if ($controllerName !== NULL) {
321 $this->controllerName = $controllerName;
322 }
323 }
324
325 /**
326 * Returns the object name of the controller supposed to handle this request, if one
327 * was set already (if not, the name of the default controller is returned)
328 *
329 * @return string Object name of the controller
330 * @api
331 */
332 public function getControllerName() {
333 return $this->controllerName;
334 }
335
336 /**
337 * Sets the name of the action contained in this request.
338 *
339 * Note that the action name must start with a lower case letter and is case sensitive.
340 *
341 * @param string $actionName Name of the action to execute by the controller
342 *
343 * @return void
344 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidActionNameException if the action name is not valid
345 */
346 public function setControllerActionName($actionName) {
347 if (!is_string($actionName) && $actionName !== NULL) {
348 throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidActionNameException('The action name must be a valid string, ' . gettype($actionName) . ' given (' . $actionName . ').', 1187176358);
349 }
350 if ($actionName[0] !== strtolower($actionName[0]) && $actionName !== NULL) {
351 throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidActionNameException('The action name must start with a lower case letter, "' . $actionName . '" does not match this criteria.', 1218473352);
352 }
353 if ($actionName !== NULL) {
354 $this->controllerActionName = $actionName;
355 }
356 }
357
358 /**
359 * Returns the name of the action the controller is supposed to execute.
360 *
361 * @return string Action name
362 * @api
363 */
364 public function getControllerActionName() {
365 $controllerObjectName = $this->getControllerObjectName();
366 if ($controllerObjectName !== '' && $this->controllerActionName === strtolower($this->controllerActionName)) {
367 $actionMethodName = $this->controllerActionName . 'Action';
368 $classMethods = get_class_methods($controllerObjectName);
369 if (is_array($classMethods)) {
370 foreach ($classMethods as $existingMethodName) {
371 if (strtolower($existingMethodName) === strtolower($actionMethodName)) {
372 $this->controllerActionName = substr($existingMethodName, 0, -6);
373 break;
374 }
375 }
376 }
377 }
378 return $this->controllerActionName;
379 }
380
381 /**
382 * Sets the value of the specified argument
383 *
384 * @param string $argumentName Name of the argument to set
385 * @param mixed $value The new value
386 *
387 * @throws Exception\InvalidArgumentNameException
388 * @return void
389 */
390 public function setArgument($argumentName, $value) {
391 if (!is_string($argumentName) || strlen($argumentName) == 0) {
392 throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentNameException('Invalid argument name.', 1210858767);
393 }
394 if ($argumentName[0] === '_' && $argumentName[1] === '_') {
395 $this->internalArguments[$argumentName] = $value;
396 return;
397 }
398 switch ($argumentName) {
399 case '@extension':
400 $this->setControllerExtensionName($value);
401 break;
402 case '@subpackage':
403 $this->setControllerSubpackageKey($value);
404 break;
405 case '@controller':
406 $this->setControllerName($value);
407 break;
408 case '@action':
409 $this->setControllerActionName($value);
410 break;
411 case '@format':
412 $this->setFormat($value);
413 break;
414 case '@vendor':
415 $this->setControllerVendorName($value);
416 break;
417 default:
418 $this->arguments[$argumentName] = $value;
419 }
420 }
421
422 /**
423 * sets the VendorName
424 *
425 * @param string $vendorName
426 *
427 * @return void
428 */
429 public function setControllerVendorName($vendorName) {
430 $this->controllerVendorName = $vendorName;
431 }
432
433 /**
434 * get the VendorName
435 *
436 * @return string
437 */
438 public function getControllerVendorName() {
439 return $this->controllerVendorName;
440 }
441
442 /**
443 * Sets the whole arguments array and therefore replaces any arguments
444 * which existed before.
445 *
446 * @param array $arguments An array of argument names and their values
447 *
448 * @return void
449 */
450 public function setArguments(array $arguments) {
451 $this->arguments = array();
452 foreach ($arguments as $argumentName => $argumentValue) {
453 $this->setArgument($argumentName, $argumentValue);
454 }
455 }
456
457 /**
458 * Returns an array of arguments and their values
459 *
460 * @return array Associative array of arguments and their values (which may be arguments and values as well)
461 * @api
462 */
463 public function getArguments() {
464 return $this->arguments;
465 }
466
467 /**
468 * Returns the value of the specified argument
469 *
470 * @param string $argumentName Name of the argument
471 *
472 * @return string Value of the argument
473 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException if such an argument does not exist
474 * @api
475 */
476 public function getArgument($argumentName) {
477 if (!isset($this->arguments[$argumentName])) {
478 throw new \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException('An argument "' . $argumentName . '" does not exist for this request.', 1176558158);
479 }
480 return $this->arguments[$argumentName];
481 }
482
483 /**
484 * Checks if an argument of the given name exists (is set)
485 *
486 * @param string $argumentName Name of the argument to check
487 *
488 * @return boolean TRUE if the argument is set, otherwise FALSE
489 * @api
490 */
491 public function hasArgument($argumentName) {
492 return isset($this->arguments[$argumentName]);
493 }
494
495 /**
496 * Sets the requested representation format
497 *
498 * @param string $format The desired format, something like "html", "xml", "png", "json" or the like. Can even be something like "rss.xml".
499 *
500 * @return void
501 */
502 public function setFormat($format) {
503 $this->format = $format;
504 }
505
506 /**
507 * Returns the requested representation format
508 *
509 * @return string The desired format, something like "html", "xml", "png", "json" or the like.
510 * @api
511 */
512 public function getFormat() {
513 return $this->format;
514 }
515
516 /**
517 * Set errors that occured during the request (e.g. argument mapping errors)
518 *
519 * @param array $errors An array of \TYPO3\CMS\Extbase\Error\Error objects
520 *
521 * @return void
522 * @deprecated since Extbase 1.4.0, will be removed two versions after Extbase 6.1
523 */
524 public function setErrors(array $errors) {
525 $this->errors = $errors;
526 }
527
528 /**
529 * Get errors that occured during the request (e.g. argument mapping errors)
530 *
531 * @return array The errors that occured during the request
532 * @deprecated since Extbase 1.4.0, will be removed two versions after Extbase 6.1
533 */
534 public function getErrors() {
535 return $this->errors;
536 }
537
538 /**
539 * Returns the original request. Filled only if a property mapping error occured.
540 *
541 * @return \TYPO3\CMS\Extbase\Mvc\Request the original request.
542 */
543 public function getOriginalRequest() {
544 return $this->originalRequest;
545 }
546
547 /**
548 * @param \TYPO3\CMS\Extbase\Mvc\Request $originalRequest
549 *
550 * @return void
551 */
552 public function setOriginalRequest(\TYPO3\CMS\Extbase\Mvc\Request $originalRequest) {
553 $this->originalRequest = $originalRequest;
554 }
555
556 /**
557 * Get the request mapping results for the original request.
558 *
559 * @return \TYPO3\CMS\Extbase\Error\Result
560 */
561 public function getOriginalRequestMappingResults() {
562 if ($this->originalRequestMappingResults === NULL) {
563 return new \TYPO3\CMS\Extbase\Error\Result();
564 }
565 return $this->originalRequestMappingResults;
566 }
567
568 /**
569 * @param \TYPO3\CMS\Extbase\Error\Result $originalRequestMappingResults
570 */
571 public function setOriginalRequestMappingResults(\TYPO3\CMS\Extbase\Error\Result $originalRequestMappingResults) {
572 $this->originalRequestMappingResults = $originalRequestMappingResults;
573 }
574
575 /**
576 * Get the internal arguments of the request, i.e. every argument starting
577 * with two underscores.
578 *
579 * @return array
580 */
581 public function getInternalArguments() {
582 return $this->internalArguments;
583 }
584
585 /**
586 * Returns the value of the specified argument
587 *
588 * @param string $argumentName Name of the argument
589 *
590 * @return string Value of the argument, or NULL if not set.
591 */
592 public function getInternalArgument($argumentName) {
593 if (!isset($this->internalArguments[$argumentName])) {
594 return NULL;
595 }
596 return $this->internalArguments[$argumentName];
597 }
598 }