[TASK] Rename deprecation message version from 1.6 to 6.0
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / MVC / Controller / AbstractController.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 * An abstract base class for Controllers
30 *
31 * @package Extbase
32 * @subpackage MVC\Controller
33 * @version $ID:$
34 * @api
35 */
36 abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbase_MVC_Controller_ControllerInterface {
37 /**
38 * @var Tx_Extbase_Object_ObjectManagerInterface
39 */
40 protected $objectManager;
41
42 /**
43 * @var Tx_Extbase_MVC_Web_Routing_UriBuilder
44 */
45 protected $uriBuilder;
46
47 /**
48 * @var string Key of the extension this controller belongs to
49 */
50 protected $extensionName;
51
52 /**
53 * Contains the settings of the current extension
54 *
55 * @var array
56 * @api
57 */
58 protected $settings;
59
60 /**
61 * The current request.
62 *
63 * @var Tx_Extbase_MVC_Request
64 * @api
65 */
66 protected $request;
67
68 /**
69 * The response which will be returned by this action controller
70 *
71 * @var Tx_Extbase_MVC_Response
72 * @api
73 */
74 protected $response;
75
76 /**
77 * @var Tx_Extbase_Property_Mapper
78 * @deprecated since Extbase 1.4.0, will be removed in Extbase 6.0
79 */
80 protected $deprecatedPropertyMapper;
81
82 /**
83 * @var Tx_Extbase_Validation_ValidatorResolver
84 */
85 protected $validatorResolver;
86
87 /**
88 * @var Tx_Extbase_MVC_Controller_Arguments Arguments passed to the controller
89 */
90 protected $arguments;
91
92 /**
93 * The results of the mapping of request arguments to controller arguments
94 * @var Tx_Extbase_Property_MappingResults
95 * @api
96 * @deprecated since Extbase 1.4.0, will be removed in Extbase 6.0
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 * @var array
105 */
106 protected $supportedRequestTypes = array('Tx_Extbase_MVC_Request');
107
108 /**
109 * @var Tx_Extbase_MVC_Controller_ControllerContext
110 * @api
111 */
112 protected $controllerContext;
113
114 /**
115 * @var Tx_Extbase_MVC_Controller_FlashMessages
116 * @deprecated since Extbase 1.1; will be removed in Extbase 6.0
117 */
118 protected $flashMessages;
119
120 /**
121 * The flash messages. Use $this->flashMessageContainer->add(...) to add a new Flash message.
122 *
123 * @var Tx_Extbase_MVC_Controller_FlashMessages
124 * @api
125 */
126 protected $flashMessageContainer;
127
128 /**
129 * @var Tx_Extbase_Configuration_ConfigurationManagerInterface
130 */
131 protected $configurationManager;
132
133 /**
134 * Constructs the controller.
135 */
136 public function __construct() {
137 list(, $this->extensionName) = explode('_', get_class($this));
138 }
139
140 /**
141 * @param Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager
142 * @return void
143 */
144 public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) {
145 $this->configurationManager = $configurationManager;
146 $this->settings = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS);
147 }
148
149 /**
150 * Injects the property mapper
151 *
152 * @param Tx_Extbase_Property_Mapper $deprecatedPropertyMapper The property mapper
153 * @return void
154 * @deprecated since Extbase 1.4.0, will be removed in Extbase 6.0
155 */
156 public function injectDeprecatedPropertyMapper(Tx_Extbase_Property_Mapper $deprecatedPropertyMapper) {
157 $this->deprecatedPropertyMapper = $deprecatedPropertyMapper;
158 }
159
160 /**
161 * Injects the object manager
162 *
163 * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
164 * @return void
165 */
166 public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
167 $this->objectManager = $objectManager;
168 $this->arguments = $this->objectManager->create('Tx_Extbase_MVC_Controller_Arguments');
169 }
170
171 /**
172 * Injects the validator resolver
173 *
174 * @param Tx_Extbase_Validation_ValidatorResolver $validatorResolver
175 * @return void
176 */
177 public function injectValidatorResolver(Tx_Extbase_Validation_ValidatorResolver $validatorResolver) {
178 $this->validatorResolver = $validatorResolver;
179 }
180
181 /**
182 * Injects the flash messages container
183 *
184 * @param Tx_Extbase_MVC_Controller_FlashMessages $flashMessageContainer
185 * @return void
186 */
187 public function injectFlashMessageContainer(Tx_Extbase_MVC_Controller_FlashMessages $flashMessageContainer) {
188 $this->flashMessageContainer = $flashMessageContainer;
189 // @deprecated since Extbase 1.1; will be removed in Extbase 6.0
190 $this->flashMessages = $flashMessageContainer;
191 }
192
193 /**
194 * Checks if the current request type is supported by the controller.
195 *
196 * If your controller only supports certain request types, either
197 * replace / modify the supporteRequestTypes property or override this
198 * method.
199 *
200 * @param Tx_Extbase_MVC_Request $request The current request
201 * @return boolean TRUE if this request type is supported, otherwise FALSE
202 * @api
203 */
204 public function canProcessRequest(Tx_Extbase_MVC_RequestInterface $request) {
205 foreach ($this->supportedRequestTypes as $supportedRequestType) {
206 if ($request instanceof $supportedRequestType) return TRUE;
207 }
208 return FALSE;
209 }
210
211 /**
212 * Processes a general request. The result can be returned by altering the given response.
213 *
214 * @param Tx_Extbase_MVC_Request $request The request object
215 * @param Tx_Extbase_MVC_Response $response The response, modified by this handler
216 * @return void
217 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType if the controller doesn't support the current request type
218 * @api
219 */
220 public function processRequest(Tx_Extbase_MVC_RequestInterface $request, Tx_Extbase_MVC_ResponseInterface $response) {
221 if (!$this->canProcessRequest($request)) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType(get_class($this) . ' does not support requests of type "' . get_class($request) . '". Supported types are: ' . implode(' ', $this->supportedRequestTypes) , 1187701131);
222
223 $response->setRequest($request);
224 $this->request = $request;
225 $this->request->setDispatched(TRUE);
226 $this->response = $response;
227
228 $this->uriBuilder = $this->objectManager->create('Tx_Extbase_MVC_Web_Routing_UriBuilder');
229 $this->uriBuilder->setRequest($request);
230
231 $this->initializeControllerArgumentsBaseValidators();
232 $this->mapRequestArgumentsToControllerArguments();
233 $this->controllerContext = $this->buildControllerContext();
234 }
235
236 /**
237 * Initialize the controller context
238 *
239 * @return Tx_Extbase_MVC_Controller_ControllerContext ControllerContext to be passed to the view
240 * @api
241 */
242 protected function buildControllerContext() {
243 $controllerContext = $this->objectManager->create('Tx_Extbase_MVC_Controller_ControllerContext');
244 $controllerContext->setRequest($this->request);
245 $controllerContext->setResponse($this->response);
246 if ($this->arguments !== NULL) {
247 $controllerContext->setArguments($this->arguments);
248 }
249 if ($this->argumentsMappingResults !== NULL) {
250 $controllerContext->setArgumentsMappingResults($this->argumentsMappingResults);
251 }
252 $controllerContext->setUriBuilder($this->uriBuilder);
253 $controllerContext->setFlashMessageContainer($this->flashMessageContainer);
254 return $controllerContext;
255 }
256
257 /**
258 * Forwards the request to another action and / or controller.
259 *
260 * Request is directly transfered to the other action / controller
261 * without the need for a new request.
262 *
263 * @param string $actionName Name of the action to forward to
264 * @param string $controllerName Unqualified object name of the controller to forward to. If not specified, the current controller is used.
265 * @param string $extensionName Name of the extension containing the controller to forward to. If not specified, the current extension is assumed.
266 * @param array $arguments Arguments to pass to the target action
267 * @return void
268 * @throws Tx_Extbase_MVC_Exception_StopAction
269 * @see redirect()
270 * @api
271 */
272 public function forward($actionName, $controllerName = NULL, $extensionName = NULL, array $arguments = NULL) {
273 $this->request->setDispatched(FALSE);
274 $this->request->setControllerActionName($actionName);
275 if ($controllerName !== NULL) $this->request->setControllerName($controllerName);
276 if ($extensionName !== NULL) $this->request->setControllerExtensionName($extensionName);
277 if ($arguments !== NULL) $this->request->setArguments($arguments);
278 throw new Tx_Extbase_MVC_Exception_StopAction();
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 Tx_Extbase_MVC_Exception_UnsupportedRequestType If the request is not a web request
298 * @throws Tx_Extbase_MVC_Exception_StopAction
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 Tx_Extbase_MVC_Web_Request) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType('redirect() only supports web requests.', 1220539734);
304
305 if ($controllerName === NULL) {
306 $controllerName = $this->request->getControllerName();
307 }
308
309 $uri = $this->uriBuilder
310 ->reset()
311 ->setTargetPageUid($pageUid)
312 ->uriFor($actionName, $arguments, $controllerName, $extensionName);
313 $this->redirectToUri($uri, $delay, $statusCode);
314 }
315
316 /**
317 * Redirects the web request to another uri.
318 *
319 * NOTE: This method only supports web requests and will thrown an exception if used with other request types.
320 *
321 * @param mixed $uri A string representation of a URI
322 * @param integer $delay (optional) The delay in seconds. Default is no delay.
323 * @param integer $statusCode (optional) The HTTP status code for the redirect. Default is "303 See Other"
324 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType If the request is not a web request
325 * @throws Tx_Extbase_MVC_Exception_StopAction
326 * @api
327 */
328 protected function redirectToUri($uri, $delay = 0, $statusCode = 303) {
329 if (!$this->request instanceof Tx_Extbase_MVC_Web_Request) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType('redirect() only supports web requests.', 1220539734);
330
331 $uri = $this->addBaseUriIfNecessary($uri);
332 $escapedUri = htmlentities($uri, ENT_QUOTES, 'utf-8');
333 $this->response->setContent('<html><head><meta http-equiv="refresh" content="' . intval($delay) . ';url=' . $escapedUri . '"/></head></html>');
334 $this->response->setStatus($statusCode);
335 $this->response->setHeader('Location', (string)$uri);
336 throw new Tx_Extbase_MVC_Exception_StopAction();
337 }
338
339 /**
340 * Adds the base uri if not already in place.
341 *
342 * @param string $uri The URI
343 * @return void
344 */
345 protected function addBaseUriIfNecessary($uri) {
346 $baseUri = $this->request->getBaseUri();
347 if(stripos($uri, 'http://') !== 0 && stripos($uri, 'https://') !== 0) {
348 $uri = $baseUri . (string)$uri;
349 }
350 return $uri;
351 }
352
353 /**
354 * Sends the specified HTTP status immediately.
355 *
356 * NOTE: This method only supports web requests and will thrown an exception if used with other request types.
357 *
358 * @param integer $statusCode The HTTP status code
359 * @param string $statusMessage A custom HTTP status message
360 * @param string $content Body content which further explains the status
361 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType If the request is not a web request
362 * @throws Tx_Extbase_MVC_Exception_StopAction
363 * @api
364 */
365 public function throwStatus($statusCode, $statusMessage = NULL, $content = NULL) {
366 if (!$this->request instanceof Tx_Extbase_MVC_Web_Request) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType('throwStatus() only supports web requests.', 1220539739);
367
368 $this->response->setStatus($statusCode, $statusMessage);
369 if ($content === NULL) $content = $this->response->getStatus();
370 $this->response->setContent($content);
371 throw new Tx_Extbase_MVC_Exception_StopAction();
372 }
373
374 /**
375 * Collects the base validators which were defined for the data type of each
376 * controller argument and adds them to the argument's validator chain.
377 *
378 * @return void
379 */
380 public function initializeControllerArgumentsBaseValidators() {
381 foreach ($this->arguments as $argument) {
382 $validator = $this->validatorResolver->getBaseValidatorConjunction($argument->getDataType());
383 if ($validator !== NULL) $argument->setValidator($validator);
384 }
385 }
386
387 /**
388 * Maps arguments delivered by the request object to the local controller arguments.
389 *
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
397 if ($this->request->hasArgument($argumentName)) {
398 $argument->setValue($this->request->getArgument($argumentName));
399 } elseif ($argument->isRequired()) {
400 throw new Tx_Extbase_MVC_Controller_Exception_RequiredArgumentMissingException('Required argument "' . $argumentName . '" is not set.', 1298012500);
401 }
402 }
403 } else {
404 // @deprecated since Extbase 1.4, will be removed in Extbase 6.0
405 $optionalPropertyNames = array();
406 $allPropertyNames = $this->arguments->getArgumentNames();
407 foreach ($allPropertyNames as $propertyName) {
408 if ($this->arguments[$propertyName]->isRequired() === FALSE) $optionalPropertyNames[] = $propertyName;
409 }
410
411 $validator = $this->objectManager->create('Tx_Extbase_MVC_Controller_ArgumentsValidator');
412 $this->deprecatedPropertyMapper->mapAndValidate($allPropertyNames, $this->request->getArguments(), $this->arguments, $optionalPropertyNames, $validator);
413
414 $this->argumentsMappingResults = $this->deprecatedPropertyMapper->getMappingResults();
415 }
416 }
417 }
418 ?>