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