2 /***************************************************************
5 * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
8 * This class is a backport of the corresponding class of FLOW3.
9 * All credits go to the v5 team.
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.
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
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.
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
29 * An abstract base class for Controllers
32 * @subpackage MVC\Controller
36 abstract class Tx_Extbase_MVC_Controller_AbstractController
implements Tx_Extbase_MVC_Controller_ControllerInterface
, t3lib_Singleton
{
38 * @var Tx_Extbase_Object_ObjectManagerInterface
40 protected $objectManager;
43 * @var Tx_Extbase_MVC_Web_Routing_UriBuilder
45 protected $uriBuilder;
48 * @var string Key of the extension this controller belongs to
50 protected $extensionName;
53 * Contains the settings of the current extension
61 * The current request.
63 * @var Tx_Extbase_MVC_Request
69 * The response which will be returned by this action controller
71 * @var Tx_Extbase_MVC_Response
77 * @var Tx_Extbase_Property_Mapper
79 protected $propertyMapper;
82 * @var Tx_Extbase_Validation_ValidatorResolver
84 protected $validatorResolver;
87 * @var Tx_Extbase_MVC_Controller_Arguments Arguments passed to the controller
92 * The results of the mapping of request arguments to controller arguments
93 * @var Tx_Extbase_Property_MappingResults
96 protected $argumentsMappingResults;
99 * An array of supported request types. By default only web requests are supported.
100 * Modify or replace this array if your specific controller supports certain
101 * (additional) request types.
104 protected $supportedRequestTypes = array('Tx_Extbase_MVC_Request');
107 * @var Tx_Extbase_MVC_Controller_ControllerContext
110 protected $controllerContext;
113 * The flash messages. DEPRECATED. Use $this->flashMessageContainer instead.
115 * @var Tx_Extbase_MVC_Controller_FlashMessages
118 protected $flashMessages;
121 * The flash messages. Use $this->flashMessageContainer->add(...) to add a new Flash message.
123 * @var Tx_Extbase_MVC_Controller_FlashMessages
126 protected $flashMessageContainer;
129 * @var Tx_Extbase_Configuration_ConfigurationManager
131 protected $configurationManager;
134 * Constructs the controller.
136 public function __construct() {
137 list(, $this->extensionName
) = explode('_', get_class($this));
141 * @param Tx_Extbase_Configuration_ConfigurationManager $configurationManager
144 public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManager
$configurationManager) {
145 $this->configurationManager
= $configurationManager;
146 $this->settings
= $this->configurationManager
->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface
::CONFIGURATION_TYPE_SETTINGS
);
150 * Injects the property mapper
152 * @param Tx_Extbase_Property_Mapper $propertyMapper The property mapper
155 public function injectPropertyMapper(Tx_Extbase_Property_Mapper
$propertyMapper) {
156 $this->propertyMapper
= $propertyMapper;
160 * Injects the object manager
162 * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
165 public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface
$objectManager) {
166 $this->objectManager
= $objectManager;
167 $this->arguments
= $this->objectManager
->create('Tx_Extbase_MVC_Controller_Arguments');
171 * Injects the validator resolver
173 * @param Tx_Extbase_Validation_ValidatorResolver $validatorResolver
176 public function injectValidatorResolver(Tx_Extbase_Validation_ValidatorResolver
$validatorResolver) {
177 $this->validatorResolver
= $validatorResolver;
181 * Injects the flash messages container
183 * @param Tx_Extbase_MVC_Controller_FlashMessages $flashMessages
186 public function injectFlashMessageContainer(Tx_Extbase_MVC_Controller_FlashMessages
$flashMessageContainer) {
187 $this->flashMessageContainer
= $flashMessageContainer;
188 $this->flashMessages
= $flashMessageContainer; // deprecated, but should still work.
192 * Checks if the current request type is supported by the controller.
194 * If your controller only supports certain request types, either
195 * replace / modify the supporteRequestTypes property or override this
198 * @param Tx_Extbase_MVC_Request $request The current request
199 * @return boolean TRUE if this request type is supported, otherwise FALSE
202 public function canProcessRequest(Tx_Extbase_MVC_RequestInterface
$request) {
203 foreach ($this->supportedRequestTypes
as $supportedRequestType) {
204 if ($request instanceof $supportedRequestType) return TRUE;
210 * Processes a general request. The result can be returned by altering the given response.
212 * @param Tx_Extbase_MVC_Request $request The request object
213 * @param Tx_Extbase_MVC_Response $response The response, modified by this handler
215 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType if the controller doesn't support the current request type
218 public function processRequest(Tx_Extbase_MVC_RequestInterface
$request, Tx_Extbase_MVC_ResponseInterface
$response) {
219 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);
221 $this->request
= $request;
222 $this->request
->setDispatched(TRUE);
223 $this->response
= $response;
225 $this->uriBuilder
= $this->objectManager
->create('Tx_Extbase_MVC_Web_Routing_UriBuilder');
226 $this->uriBuilder
->setRequest($request);
228 $this->initializeControllerArgumentsBaseValidators();
229 $this->mapRequestArgumentsToControllerArguments();
230 $this->controllerContext
= $this->buildControllerContext();
234 * Initialize the controller context
236 * @return Tx_Extbase_MVC_Controller_ControllerContext ControllerContext to be passed to the view
239 protected function buildControllerContext() {
240 $controllerContext = $this->objectManager
->create('Tx_Extbase_MVC_Controller_ControllerContext');
241 $controllerContext->setRequest($this->request
);
242 $controllerContext->setResponse($this->response
);
243 if ($this->arguments
!== NULL) {
244 $controllerContext->setArguments($this->arguments
);
246 if ($this->argumentsMappingResults
!== NULL) {
247 $controllerContext->setArgumentsMappingResults($this->argumentsMappingResults
);
249 $controllerContext->setUriBuilder($this->uriBuilder
);
250 $controllerContext->setFlashMessageContainer($this->flashMessageContainer
);
251 return $controllerContext;
255 * Forwards the request to another controller.
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 Tx_Extbase_MVC_Controller_Arguments $arguments Arguments to pass to the target action
262 * @throws Tx_Extbase_MVC_Exception_StopAction
265 public function forward($actionName, $controllerName = NULL, $extensionName = NULL, array $arguments = NULL) {
266 $this->request
->setDispatched(FALSE);
267 $this->request
->setControllerActionName($actionName);
268 if ($controllerName !== NULL) $this->request
->setControllerName($controllerName);
269 if ($extensionName !== NULL) $this->request
->setControllerExtensionName($extensionName);
270 if ($arguments !== NULL) $this->request
->setArguments($arguments);
271 throw new Tx_Extbase_MVC_Exception_StopAction();
275 * Forwards the request to another action and / or controller.
277 * NOTE: This method only supports web requests and will thrown an exception
278 * if used with other request types.
280 * @param string $actionName Name of the action to forward to
281 * @param string $controllerName Unqualified object name of the controller to forward to. If not specified, the current controller is used.
282 * @param string $extensionName Name of the extension containing the controller to forward to. If not specified, the current extension is assumed.
283 * @param Tx_Extbase_MVC_Controller_Arguments $arguments Arguments to pass to the target action
284 * @param integer $pageUid Target page uid. If NULL, the current page uid is used
285 * @param integer $delay (optional) The delay in seconds. Default is no delay.
286 * @param integer $statusCode (optional) The HTTP status code for the redirect. Default is "303 See Other"
288 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType If the request is not a web request
289 * @throws Tx_Extbase_MVC_Exception_StopAction
292 protected function redirect($actionName, $controllerName = NULL, $extensionName = NULL, array $arguments = NULL, $pageUid = NULL, $delay = 0, $statusCode = 303) {
293 if (!$this->request
instanceof Tx_Extbase_MVC_Web_Request
) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType('redirect() only supports web requests.', 1220539734);
295 if ($controllerName === NULL) {
296 $controllerName = $this->request
->getControllerName();
299 $uri = $this->uriBuilder
301 ->setTargetPageUid($pageUid)
302 ->uriFor($actionName, $arguments, $controllerName, $extensionName);
303 $this->redirectToURI($uri, $delay, $statusCode);
307 * Redirects the web request to another uri.
309 * NOTE: This method only supports web requests and will thrown an exception if used with other request types.
311 * @param mixed $uri A string representation of a URI
312 * @param integer $delay (optional) The delay in seconds. Default is no delay.
313 * @param integer $statusCode (optional) The HTTP status code for the redirect. Default is "303 See Other"
314 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType If the request is not a web request
315 * @throws Tx_Extbase_MVC_Exception_StopAction
318 protected function redirectToURI($uri, $delay = 0, $statusCode = 303) {
319 if (!$this->request
instanceof Tx_Extbase_MVC_Web_Request
) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType('redirect() only supports web requests.', 1220539734);
321 $uri = $this->addBaseUriIfNecessary($uri);
322 $escapedUri = htmlentities($uri, ENT_QUOTES
, 'utf-8');
323 $this->response
->setContent('<html><head><meta http-equiv="refresh" content="' . intval($delay) . ';url=' . $escapedUri . '"/></head></html>');
324 $this->response
->setStatus($statusCode);
325 $this->response
->setHeader('Location', (string)$uri);
326 throw new Tx_Extbase_MVC_Exception_StopAction();
330 * Adds the base uri if not already in place.
332 * @param string $uri The URI
335 protected function addBaseUriIfNecessary($uri) {
336 $baseUri = $this->request
->getBaseURI();
337 if(stripos($uri, $baseUri) !== 0) {
338 $uri = $baseUri . (string)$uri;
344 * Sends the specified HTTP status immediately.
346 * NOTE: This method only supports web requests and will thrown an exception if used with other request types.
348 * @param integer $statusCode The HTTP status code
349 * @param string $statusMessage A custom HTTP status message
350 * @param string $content Body content which further explains the status
351 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType If the request is not a web request
352 * @throws Tx_Extbase_MVC_Exception_StopAction
355 public function throwStatus($statusCode, $statusMessage = NULL, $content = NULL) {
356 if (!$this->request
instanceof Tx_Extbase_MVC_Web_Request
) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType('throwStatus() only supports web requests.', 1220539739);
358 $this->response
->setStatus($statusCode, $statusMessage);
359 if ($content === NULL) $content = $this->response
->getStatus();
360 $this->response
->setContent($content);
361 throw new Tx_Extbase_MVC_Exception_StopAction();
365 * Collects the base validators which were defined for the data type of each
366 * controller argument and adds them to the argument's validator chain.
370 public function initializeControllerArgumentsBaseValidators() {
371 foreach ($this->arguments
as $argument) {
372 $validator = $this->validatorResolver
->getBaseValidatorConjunction($argument->getDataType());
373 if ($validator !== NULL) $argument->setValidator($validator);
378 * Maps arguments delivered by the request object to the local controller arguments.
382 protected function mapRequestArgumentsToControllerArguments() {
383 $optionalPropertyNames = array();
384 $allPropertyNames = $this->arguments
->getArgumentNames();
385 foreach ($allPropertyNames as $propertyName) {
386 if ($this->arguments
[$propertyName]->isRequired() === FALSE) $optionalPropertyNames[] = $propertyName;
389 $validator = $this->objectManager
->create('Tx_Extbase_MVC_Controller_ArgumentsValidator');
390 $this->propertyMapper
->mapAndValidate($allPropertyNames, $this->request
->getArguments(), $this->arguments
, $optionalPropertyNames, $validator);
392 $this->argumentsMappingResults
= $this->propertyMapper
->getMappingResults();