[TASK] Rename FlashMessages to FlashMessageContainer
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Mvc / Controller / AbstractController.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Mvc\Controller;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
8 * All rights reserved
9 *
10 * This class is a backport of the corresponding class of FLOW3.
11 * All credits go to the v5 team.
12 *
13 * This script is part of the TYPO3 project. The TYPO3 project is
14 * free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * The GNU General Public License can be found at
20 * http://www.gnu.org/copyleft/gpl.html.
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29 /**
30 * An abstract base class for Controllers
31 *
32 * @api
33 */
34 abstract class AbstractController implements \TYPO3\CMS\Extbase\Mvc\Controller\ControllerInterface {
35
36 /**
37 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
38 */
39 protected $objectManager;
40
41 /**
42 * @var \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder
43 */
44 protected $uriBuilder;
45
46 /**
47 * @var string Key of the extension this controller belongs to
48 */
49 protected $extensionName;
50
51 /**
52 * Contains the settings of the current extension
53 *
54 * @var array
55 * @api
56 */
57 protected $settings;
58
59 /**
60 * The current request.
61 *
62 * @var \TYPO3\CMS\Extbase\Mvc\Request
63 * @api
64 */
65 protected $request;
66
67 /**
68 * The response which will be returned by this action controller
69 *
70 * @var \TYPO3\CMS\Extbase\Mvc\Response
71 * @api
72 */
73 protected $response;
74
75 /**
76 * @var \TYPO3\CMS\Extbase\Property\Mapper
77 * @deprecated since Extbase 1.4.0, will be removed in Extbase 6.1
78 */
79 protected $deprecatedPropertyMapper;
80
81 /**
82 * @var \TYPO3\CMS\Extbase\Validation\ValidatorResolver
83 */
84 protected $validatorResolver;
85
86 /**
87 * @var \TYPO3\CMS\Extbase\Mvc\Controller\Arguments Arguments passed to the controller
88 */
89 protected $arguments;
90
91 /**
92 * The results of the mapping of request arguments to controller arguments
93 *
94 * @var \TYPO3\CMS\Extbase\Property\MappingResults
95 * @api
96 * @deprecated since Extbase 1.4.0, will be removed in Extbase 6.1
97 */
98 protected $argumentsMappingResults;
99
100 /**
101 * An array of supported request types. By default only web requests are supported.
102 * Modify or replace this array if your specific controller supports certain
103 * (additional) request types.
104 *
105 * @var array
106 */
107 protected $supportedRequestTypes = array('TYPO3\\CMS\\Extbase\\Mvc\\Request');
108
109 /**
110 * @var \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext
111 * @api
112 */
113 protected $controllerContext;
114
115 /**
116 * The flash messages. Use $this->flashMessageContainer->add(...) to add a new Flash message.
117 *
118 * @var \TYPO3\CMS\Extbase\Mvc\Controller\FlashMessageContainer
119 * @api
120 */
121 protected $flashMessageContainer;
122
123 /**
124 * @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
125 */
126 protected $configurationManager;
127
128 /**
129 * Constructs the controller.
130 */
131 public function __construct() {
132 list(, $this->extensionName) = explode('_', get_class($this));
133 }
134
135 /**
136 * @param \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager
137 * @return void
138 */
139 public function injectConfigurationManager(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager) {
140 $this->configurationManager = $configurationManager;
141 $this->settings = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS);
142 }
143
144 /**
145 * Injects the property mapper
146 *
147 * @param \TYPO3\CMS\Extbase\Property\Mapper $deprecatedPropertyMapper The property mapper
148 * @return void
149 * @deprecated since Extbase 1.4.0, will be removed in Extbase 6.1
150 */
151 public function injectDeprecatedPropertyMapper(\TYPO3\CMS\Extbase\Property\Mapper $deprecatedPropertyMapper) {
152 $this->deprecatedPropertyMapper = $deprecatedPropertyMapper;
153 }
154
155 /**
156 * Injects the object manager
157 *
158 * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
159 * @return void
160 */
161 public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager) {
162 $this->objectManager = $objectManager;
163 $this->arguments = $this->objectManager->create('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Arguments');
164 }
165
166 /**
167 * Injects the validator resolver
168 *
169 * @param \TYPO3\CMS\Extbase\Validation\ValidatorResolver $validatorResolver
170 * @return void
171 */
172 public function injectValidatorResolver(\TYPO3\CMS\Extbase\Validation\ValidatorResolver $validatorResolver) {
173 $this->validatorResolver = $validatorResolver;
174 }
175
176 /**
177 * Injects the flash messages container
178 *
179 * @param \TYPO3\CMS\Extbase\Mvc\Controller\FlashMessageContainer $flashMessageContainer
180 * @return void
181 */
182 public function injectFlashMessageContainer(\TYPO3\CMS\Extbase\Mvc\Controller\FlashMessageContainer $flashMessageContainer) {
183 $this->flashMessageContainer = $flashMessageContainer;
184 }
185
186 /**
187 * Checks if the current request type is supported by the controller.
188 *
189 * If your controller only supports certain request types, either
190 * replace / modify the supporteRequestTypes property or override this
191 * method.
192 *
193 * @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The current request
194 * @return boolean TRUE if this request type is supported, otherwise FALSE
195 * @api
196 */
197 public function canProcessRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request) {
198 foreach ($this->supportedRequestTypes as $supportedRequestType) {
199 if ($request instanceof $supportedRequestType) {
200 return TRUE;
201 }
202 }
203 return FALSE;
204 }
205
206 /**
207 * Processes a general request. The result can be returned by altering the given response.
208 *
209 * @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The request object
210 * @param \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response The response, modified by this handler
211 * @return void
212 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException if the controller doesn't support the current request type
213 * @api
214 */
215 public function processRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response) {
216 if (!$this->canProcessRequest($request)) {
217 throw new \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException(get_class($this) . ' does not support requests of type "' . get_class($request) . '". Supported types are: ' . implode(' ', $this->supportedRequestTypes), 1187701131);
218 }
219 $response->setRequest($request);
220 $this->request = $request;
221 $this->request->setDispatched(TRUE);
222 $this->response = $response;
223 $this->uriBuilder = $this->objectManager->create('TYPO3\\CMS\\Extbase\\Mvc\\Web\\Routing\\UriBuilder');
224 $this->uriBuilder->setRequest($request);
225 $this->initializeControllerArgumentsBaseValidators();
226 $this->mapRequestArgumentsToControllerArguments();
227 $this->controllerContext = $this->buildControllerContext();
228 }
229
230 /**
231 * Initialize the controller context
232 *
233 * @return \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext ControllerContext to be passed to the view
234 * @api
235 */
236 protected function buildControllerContext() {
237 $controllerContext = $this->objectManager->create('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ControllerContext');
238 $controllerContext->setRequest($this->request);
239 $controllerContext->setResponse($this->response);
240 if ($this->arguments !== NULL) {
241 $controllerContext->setArguments($this->arguments);
242 }
243 if ($this->argumentsMappingResults !== NULL) {
244 $controllerContext->setArgumentsMappingResults($this->argumentsMappingResults);
245 }
246 $controllerContext->setUriBuilder($this->uriBuilder);
247 $controllerContext->setFlashMessageContainer($this->flashMessageContainer);
248 return $controllerContext;
249 }
250
251 /**
252 * Forwards the request to another action and / or controller.
253 *
254 * Request is directly transfered to the other action / controller
255 * without the need for a new request.
256 *
257 * @param string $actionName Name of the action to forward to
258 * @param string $controllerName Unqualified object name of the controller to forward to. If not specified, the current controller is used.
259 * @param string $extensionName Name of the extension containing the controller to forward to. If not specified, the current extension is assumed.
260 * @param array $arguments Arguments to pass to the target action
261 * @return void
262 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
263 * @see redirect()
264 * @api
265 */
266 public function forward($actionName, $controllerName = NULL, $extensionName = NULL, array $arguments = NULL) {
267 $this->request->setDispatched(FALSE);
268 $this->request->setControllerActionName($actionName);
269 if ($controllerName !== NULL) {
270 $this->request->setControllerName($controllerName);
271 }
272 if ($extensionName !== NULL) {
273 $this->request->setControllerExtensionName($extensionName);
274 }
275 if ($arguments !== NULL) {
276 $this->request->setArguments($arguments);
277 }
278 throw new \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException();
279 }
280
281 /**
282 * Redirects the request to another action and / or controller.
283 *
284 * Redirect will be sent to the client which then performs another request to the new URI.
285 *
286 * NOTE: This method only supports web requests and will thrown an exception
287 * if used with other request types.
288 *
289 * @param string $actionName Name of the action to forward to
290 * @param string $controllerName Unqualified object name of the controller to forward to. If not specified, the current controller is used.
291 * @param string $extensionName Name of the extension containing the controller to forward to. If not specified, the current extension is assumed.
292 * @param array $arguments Arguments to pass to the target action
293 * @param integer $pageUid Target page uid. If NULL, the current page uid is used
294 * @param integer $delay (optional) The delay in seconds. Default is no delay.
295 * @param integer $statusCode (optional) The HTTP status code for the redirect. Default is "303 See Other
296 * @return void
297 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException If the request is not a web request
298 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
299 * @see forward()
300 * @api
301 */
302 protected function redirect($actionName, $controllerName = NULL, $extensionName = NULL, array $arguments = NULL, $pageUid = NULL, $delay = 0, $statusCode = 303) {
303 if (!$this->request instanceof \TYPO3\CMS\Extbase\Mvc\Web\Request) {
304 throw new \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException('redirect() only supports web requests.', 1220539734);
305 }
306 if ($controllerName === NULL) {
307 $controllerName = $this->request->getControllerName();
308 }
309 $uri = $this->uriBuilder->reset()->setTargetPageUid($pageUid)->setCreateAbsoluteUri(TRUE)->uriFor($actionName, $arguments, $controllerName, $extensionName);
310 $this->redirectToUri($uri, $delay, $statusCode);
311 }
312
313 /**
314 * Redirects the web request to another uri.
315 *
316 * NOTE: This method only supports web requests and will thrown an exception if used with other request types.
317 *
318 * @param mixed $uri A string representation of a URI
319 * @param integer $delay (optional) The delay in seconds. Default is no delay.
320 * @param integer $statusCode (optional) The HTTP status code for the redirect. Default is "303 See Other
321 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException If the request is not a web request
322 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
323 * @api
324 */
325 protected function redirectToUri($uri, $delay = 0, $statusCode = 303) {
326 if (!$this->request instanceof \TYPO3\CMS\Extbase\Mvc\Web\Request) {
327 throw new \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException('redirect() only supports web requests.', 1220539734);
328 }
329 $uri = $this->addBaseUriIfNecessary($uri);
330 $escapedUri = htmlentities($uri, ENT_QUOTES, 'utf-8');
331 $this->response->setContent('<html><head><meta http-equiv="refresh" content="' . intval($delay) . ';url=' . $escapedUri . '"/></head></html>');
332 $this->response->setStatus($statusCode);
333 $this->response->setHeader('Location', (string) $uri);
334 throw new \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException();
335 }
336
337 /**
338 * Adds the base uri if not already in place.
339 *
340 * @param string $uri The URI
341 * @return string
342 */
343 protected function addBaseUriIfNecessary($uri) {
344 return \TYPO3\CMS\Core\Utility\GeneralUtility::locationHeaderUrl((string) $uri);
345 }
346
347 /**
348 * Sends the specified HTTP status immediately.
349 *
350 * NOTE: This method only supports web requests and will thrown an exception if used with other request types.
351 *
352 * @param integer $statusCode The HTTP status code
353 * @param string $statusMessage A custom HTTP status message
354 * @param string $content Body content which further explains the status
355 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException If the request is not a web request
356 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
357 * @api
358 */
359 public function throwStatus($statusCode, $statusMessage = NULL, $content = NULL) {
360 if (!$this->request instanceof \TYPO3\CMS\Extbase\Mvc\Web\Request) {
361 throw new \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException('throwStatus() only supports web requests.', 1220539739);
362 }
363 $this->response->setStatus($statusCode, $statusMessage);
364 if ($content === NULL) {
365 $content = $this->response->getStatus();
366 }
367 $this->response->setContent($content);
368 throw new \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException();
369 }
370
371 /**
372 * Collects the base validators which were defined for the data type of each
373 * controller argument and adds them to the argument's validator chain.
374 *
375 * @return void
376 */
377 public function initializeControllerArgumentsBaseValidators() {
378 foreach ($this->arguments as $argument) {
379 $validator = $this->validatorResolver->getBaseValidatorConjunction($argument->getDataType());
380 if ($validator !== NULL) {
381 $argument->setValidator($validator);
382 }
383 }
384 }
385
386 /**
387 * Maps arguments delivered by the request object to the local controller arguments.
388 *
389 * @throws Exception\RequiredArgumentMissingException
390 * @return void
391 */
392 protected function mapRequestArgumentsToControllerArguments() {
393 if ($this->configurationManager->isFeatureEnabled('rewrittenPropertyMapper')) {
394 foreach ($this->arguments as $argument) {
395 $argumentName = $argument->getName();
396 if ($this->request->hasArgument($argumentName)) {
397 $argument->setValue($this->request->getArgument($argumentName));
398 } elseif ($argument->isRequired()) {
399 throw new \TYPO3\CMS\Extbase\Mvc\Controller\Exception\RequiredArgumentMissingException('Required argument "' . $argumentName . '" is not set.', 1298012500);
400 }
401 }
402 } else {
403 // @deprecated since Extbase 1.4, will be removed in Extbase 6.1
404 $optionalPropertyNames = array();
405 $allPropertyNames = $this->arguments->getArgumentNames();
406 foreach ($allPropertyNames as $propertyName) {
407 if ($this->arguments[$propertyName]->isRequired() === FALSE) {
408 $optionalPropertyNames[] = $propertyName;
409 }
410 }
411 /** @var $validator ArgumentsValidator */
412 $validator = $this->objectManager->create('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ArgumentsValidator');
413 $this->deprecatedPropertyMapper->mapAndValidate($allPropertyNames, $this->request->getArguments(), $this->arguments, $optionalPropertyNames, $validator);
414 $this->argumentsMappingResults = $this->deprecatedPropertyMapper->getMappingResults();
415 }
416 }
417
418 }
419
420
421 ?>