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
35 abstract class Tx_Extbase_MVC_Controller_AbstractController
implements Tx_Extbase_MVC_Controller_ControllerInterface
{
38 * @var Tx_Extbase_Object_ManagerInterface
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 * Constructs the controller.
109 public function __construct() {
110 $this->objectManager
= t3lib_div
::makeInstance('Tx_Extbase_Object_Manager');
111 $this->arguments
= t3lib_div
::makeInstance('Tx_Extbase_MVC_Controller_Arguments');
112 $this->arguments
->injectPersistenceManager(Tx_Extbase_Dispatcher
::getPersistenceManager());
113 $this->arguments
->injectQueryFactory(t3lib_div
::makeInstance('Tx_Extbase_Persistence_QueryFactory'));
114 list(, $this->extensionName
) = explode('_', get_class($this));
118 * Injects the property mapper
120 * @param Tx_Extbase_Property_Mapper $propertyMapper The property mapper
123 public function injectPropertyMapper(Tx_Extbase_Property_Mapper
$propertyMapper) {
124 $this->propertyMapper
= $propertyMapper;
128 * Injects the settings of the extension.
130 * @param array $settings Settings container of the current extension
133 public function injectSettings(array $settings) {
134 $this->settings
= $settings;
138 * Injects the object manager
140 * @param Tx_Extbase_Object_ManagerInterface $objectManager
143 public function injectObjectManager(Tx_Extbase_Object_ManagerInterface
$objectManager) {
144 $this->objectManager
= $objectManager;
148 * Injects the validator resolver
150 * @param Tx_Extbase_Validation_ValidatorResolver $validatorResolver
153 public function injectValidatorResolver(Tx_Extbase_Validation_ValidatorResolver
$validatorResolver) {
154 $this->validatorResolver
= $validatorResolver;
158 * Checks if the current request type is supported by the controller.
160 * If your controller only supports certain request types, either
161 * replace / modify the supporteRequestTypes property or override this
164 * @param Tx_Extbase_MVC_Request $request The current request
165 * @return boolean TRUE if this request type is supported, otherwise FALSE
168 public function canProcessRequest(Tx_Extbase_MVC_Request
$request) {
169 foreach ($this->supportedRequestTypes
as $supportedRequestType) {
170 if ($request instanceof $supportedRequestType) return TRUE;
176 * Processes a general request. The result can be returned by altering the given response.
178 * @param Tx_Extbase_MVC_Request $request The request object
179 * @param Tx_Extbase_MVC_Response $response The response, modified by this handler
181 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType if the controller doesn't support the current request type
184 public function processRequest(Tx_Extbase_MVC_Request
$request, Tx_Extbase_MVC_Response
$response) {
185 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);
187 $this->request
= $request;
188 $this->request
->setDispatched(TRUE);
189 $this->response
= $response;
191 $this->URIBuilder
= t3lib_div
::makeInstance('Tx_Extbase_MVC_Web_Routing_URIBuilder');
192 $this->URIBuilder
->setRequest($request);
194 $this->initializeControllerArgumentsBaseValidators();
195 $this->mapRequestArgumentsToControllerArguments();
199 * Initialize the controller context
201 * @return Tx_Extbase_MVC_Controller_ControllerContext ControllerContext to be passed to the view
204 protected function buildControllerContext() {
205 $controllerContext = t3lib_div
::makeInstance('Tx_Extbase_MVC_Controller_ControllerContext');
206 $controllerContext->setRequest($this->request
);
207 $controllerContext->setResponse($this->response
);
208 if ($this->arguments
!== NULL) {
209 $controllerContext->setArguments($this->arguments
);
211 if ($this->argumentsMappingResults
!== NULL) {
212 $controllerContext->setArgumentsMappingResults($this->argumentsMappingResults
);
214 $controllerContext->setURIBuilder($this->URIBuilder
);
215 return $controllerContext;
219 * Forwards the request to another controller.
221 * @param string $actionName Name of the action to forward to
222 * @param string $controllerName Unqualified object name of the controller to forward to. If not specified, the current controller is used.
223 * @param string $extensionName Name of the extension containing the controller to forward to. If not specified, the current extension is assumed.
224 * @param Tx_Extbase_MVC_Controller_Arguments $arguments Arguments to pass to the target action
226 * @throws Tx_Extbase_MVC_Exception_StopAction
229 public function forward($actionName, $controllerName = NULL, $extensionName = NULL, array $arguments = NULL) {
230 $this->request
->setDispatched(FALSE);
231 $this->request
->setControllerActionName($actionName);
232 if ($controllerName !== NULL) $this->request
->setControllerName($controllerName);
233 if ($extensionName !== NULL) $this->request
->setControllerExtensionName($extensionName);
234 if ($arguments !== NULL) $this->request
->setArguments($arguments);
235 throw new Tx_Extbase_MVC_Exception_StopAction();
239 * Forwards the request to another action and / or controller.
241 * NOTE: This method only supports web requests and will thrown an exception
242 * if used with other request types.
244 * @param string $actionName Name of the action to forward to
245 * @param string $controllerName Unqualified object name of the controller to forward to. If not specified, the current controller is used.
246 * @param string $extensionName Name of the extension containing the controller to forward to. If not specified, the current extension is assumed.
247 * @param Tx_Extbase_MVC_Controller_Arguments $arguments Arguments to pass to the target action
248 * @param integer $pageUid Target page uid. If NULL, the current page uid is used
249 * @param integer $delay (optional) The delay in seconds. Default is no delay.
250 * @param integer $statusCode (optional) The HTTP status code for the redirect. Default is "303 See Other"
252 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType If the request is not a web request
253 * @throws Tx_Extbase_MVC_Exception_StopAction
256 protected function redirect($actionName, $controllerName = NULL, $extensionName = NULL, array $arguments = NULL, $pageUid = NULL, $delay = 0, $statusCode = 303) {
257 if (!$this->request
instanceof Tx_Extbase_MVC_Web_Request
) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType('redirect() only supports web requests.', 1220539734);
259 if ($controllerName === NULL) {
260 $controllerName = $this->request
->getControllerName();
262 if ($pageUid === NULL) {
263 $pageUid = $GLOBALS['TSFE']->id
;
266 $uri = $this->URIBuilder
->URIFor($pageUid, $actionName, $arguments, $controllerName, $extensionName);
267 $this->redirectToURI($uri, $delay, $statusCode);
271 * Redirects the web request to another uri.
273 * NOTE: This method only supports web requests and will thrown an exception if used with other request types.
275 * @param mixed $uri A string representation of a URI
276 * @param integer $delay (optional) The delay in seconds. Default is no delay.
277 * @param integer $statusCode (optional) The HTTP status code for the redirect. Default is "303 See Other"
278 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType If the request is not a web request
279 * @throws Tx_Extbase_MVC_Exception_StopAction
282 protected function redirectToURI($uri, $delay = 0, $statusCode = 303) {
283 if (!$this->request
instanceof Tx_Extbase_MVC_Web_Request
) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType('redirect() only supports web requests.', 1220539734);
285 $uri = $this->request
->getBaseURI() . (string)$uri;
286 $escapedUri = htmlentities($uri, ENT_QUOTES
, 'utf-8');
287 $this->response
->setContent('<html><head><meta http-equiv="refresh" content="' . intval($delay) . ';url=' . $escapedUri . '"/></head></html>');
288 $this->response
->setStatus($statusCode);
289 $this->response
->setHeader('Location', (string)$uri);
290 throw new Tx_Extbase_MVC_Exception_StopAction();
294 * Sends the specified HTTP status immediately.
296 * NOTE: This method only supports web requests and will thrown an exception if used with other request types.
298 * @param integer $statusCode The HTTP status code
299 * @param string $statusMessage A custom HTTP status message
300 * @param string $content Body content which further explains the status
301 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType If the request is not a web request
302 * @throws Tx_Extbase_MVC_Exception_StopAction
305 public function throwStatus($statusCode, $statusMessage = NULL, $content = NULL) {
306 if (!$this->request
instanceof Tx_Extbase_MVC_Web_Request
) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType('throwStatus() only supports web requests.', 1220539739);
308 $this->response
->setStatus($statusCode, $statusMessage);
309 if ($content === NULL) $content = $this->response
->getStatus();
310 $this->response
->setContent($content);
311 throw new Tx_Extbase_MVC_Exception_StopAction();
315 * Collects the base validators which were defined for the data type of each
316 * controller argument and adds them to the argument's validator chain.
320 public function initializeControllerArgumentsBaseValidators() {
321 foreach ($this->arguments
as $argument) {
322 $validator = $this->validatorResolver
->getBaseValidatorConjunction($argument->getDataType());
323 if ($validator !== NULL) $argument->setValidator($validator);
328 * Maps arguments delivered by the request object to the local controller arguments.
332 protected function mapRequestArgumentsToControllerArguments() {
333 $optionalPropertyNames = array();
334 $allPropertyNames = $this->arguments
->getArgumentNames();
335 foreach ($allPropertyNames as $propertyName) {
336 if ($this->arguments
[$propertyName]->isRequired() === FALSE) $optionalPropertyNames[] = $propertyName;
339 $validator = t3lib_div
::makeInstance('Tx_Extbase_MVC_Controller_ArgumentsValidator');
340 $this->propertyMapper
->mapAndValidate($allPropertyNames, $this->request
->getArguments(), $this->arguments
, $optionalPropertyNames, $validator);
341 $this->argumentsMappingResults
= $this->propertyMapper
->getMappingResults();