[+TASK] Extbase (DomainObject): Added a "private" property _localizationParentUid...
[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 /**
39 * @var Tx_Extbase_Object_ManagerInterface
40 */
41 protected $objectManager;
42
43 /**
44 * @var Tx_Extbase_MVC_Web_Routing_UriBuilder
45 */
46 protected $uriBuilder;
47
48 /**
49 * @var string Key of the extension this controller belongs to
50 */
51 protected $extensionName;
52
53 /**
54 * Contains the settings of the current extension
55 *
56 * @var array
57 * @api
58 */
59 protected $settings;
60
61 /**
62 * The current request.
63 *
64 * @var Tx_Extbase_MVC_Request
65 * @api
66 */
67 protected $request;
68
69 /**
70 * The response which will be returned by this action controller
71 *
72 * @var Tx_Extbase_MVC_Response
73 * @api
74 */
75 protected $response;
76
77 /**
78 * @var Tx_Extbase_Property_Mapper
79 */
80 protected $propertyMapper;
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 */
97 protected $argumentsMappingResults;
98
99 /**
100 * An array of supported request types. By default only web requests are supported.
101 * Modify or replace this array if your specific controller supports certain
102 * (additional) request types.
103 * @var array
104 */
105 protected $supportedRequestTypes = array('Tx_Extbase_MVC_Request');
106
107 /**
108 * The flash messages. Use $this->flashMessages->add(...) to add a new Flash message.
109 *
110 * @var Tx_Extbase_MVC_Controller_FlashMessages
111 * @api
112 */
113 protected $flashMessages;
114
115 /**
116 * Constructs the controller.
117 */
118 public function __construct() {
119 $this->initializeObjects();
120 list(, $this->extensionName) = explode('_', get_class($this));
121 }
122
123 /**
124 * Initializes objects this class depends on
125 *
126 * @return void
127 */
128 protected function initializeObjects() {
129 $this->objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_Manager');
130 $this->arguments = t3lib_div::makeInstance('Tx_Extbase_MVC_Controller_Arguments');
131 $this->arguments->injectPersistenceManager(Tx_Extbase_Dispatcher::getPersistenceManager());
132 $this->arguments->injectQueryFactory(t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryFactory'));
133 }
134
135 /**
136 * Injects the property mapper
137 *
138 * @param Tx_Extbase_Property_Mapper $propertyMapper The property mapper
139 * @return void
140 */
141 public function injectPropertyMapper(Tx_Extbase_Property_Mapper $propertyMapper) {
142 $this->propertyMapper = $propertyMapper;
143 }
144
145 /**
146 * Injects the settings of the extension.
147 *
148 * @param array $settings Settings container of the current extension
149 * @return void
150 */
151 public function injectSettings(array $settings) {
152 $this->settings = $settings;
153 }
154
155 /**
156 * Injects the object manager
157 *
158 * @param Tx_Extbase_Object_ManagerInterface $objectManager
159 * @return void
160 */
161 public function injectObjectManager(Tx_Extbase_Object_ManagerInterface $objectManager) {
162 $this->objectManager = $objectManager;
163 }
164
165 /**
166 * Injects the validator resolver
167 *
168 * @param Tx_Extbase_Validation_ValidatorResolver $validatorResolver
169 * @return void
170 */
171 public function injectValidatorResolver(Tx_Extbase_Validation_ValidatorResolver $validatorResolver) {
172 $this->validatorResolver = $validatorResolver;
173 }
174
175 /**
176 * Injects the flash messages container
177 *
178 * @param Tx_Extbase_MVC_Controller_FlashMessages $flashMessages
179 * @return void
180 */
181 public function injectFlashMessages(Tx_Extbase_MVC_Controller_FlashMessages $flashMessages) {
182 $this->flashMessages = $flashMessages;
183 }
184
185 /**
186 * Checks if the current request type is supported by the controller.
187 *
188 * If your controller only supports certain request types, either
189 * replace / modify the supporteRequestTypes property or override this
190 * method.
191 *
192 * @param Tx_Extbase_MVC_Request $request The current request
193 * @return boolean TRUE if this request type is supported, otherwise FALSE
194 * @api
195 */
196 public function canProcessRequest(Tx_Extbase_MVC_Request $request) {
197 foreach ($this->supportedRequestTypes as $supportedRequestType) {
198 if ($request instanceof $supportedRequestType) return TRUE;
199 }
200 return FALSE;
201 }
202
203 /**
204 * Processes a general request. The result can be returned by altering the given response.
205 *
206 * @param Tx_Extbase_MVC_Request $request The request object
207 * @param Tx_Extbase_MVC_Response $response The response, modified by this handler
208 * @return void
209 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType if the controller doesn't support the current request type
210 * @api
211 */
212 public function processRequest(Tx_Extbase_MVC_Request $request, Tx_Extbase_MVC_Response $response) {
213 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);
214
215 $this->request = $request;
216 $this->request->setDispatched(TRUE);
217 $this->response = $response;
218
219 $this->uriBuilder = t3lib_div::makeInstance('Tx_Extbase_MVC_Web_Routing_UriBuilder');
220 $this->uriBuilder->setRequest($request);
221
222 $this->initializeControllerArgumentsBaseValidators();
223 $this->mapRequestArgumentsToControllerArguments();
224 }
225
226 /**
227 * Initialize the controller context
228 *
229 * @return Tx_Extbase_MVC_Controller_ControllerContext ControllerContext to be passed to the view
230 * @api
231 */
232 protected function buildControllerContext() {
233 $controllerContext = t3lib_div::makeInstance('Tx_Extbase_MVC_Controller_ControllerContext');
234 $controllerContext->setRequest($this->request);
235 $controllerContext->setResponse($this->response);
236 if ($this->arguments !== NULL) {
237 $controllerContext->setArguments($this->arguments);
238 }
239 if ($this->argumentsMappingResults !== NULL) {
240 $controllerContext->setArgumentsMappingResults($this->argumentsMappingResults);
241 }
242 $controllerContext->setUriBuilder($this->uriBuilder);
243 $controllerContext->setFlashMessages($this->flashMessages);
244 return $controllerContext;
245 }
246
247 /**
248 * Forwards the request to another controller.
249 *
250 * @param string $actionName Name of the action to forward to
251 * @param string $controllerName Unqualified object name of the controller to forward to. If not specified, the current controller is used.
252 * @param string $extensionName Name of the extension containing the controller to forward to. If not specified, the current extension is assumed.
253 * @param Tx_Extbase_MVC_Controller_Arguments $arguments Arguments to pass to the target action
254 * @return void
255 * @throws Tx_Extbase_MVC_Exception_StopAction
256 * @api
257 */
258 public function forward($actionName, $controllerName = NULL, $extensionName = NULL, array $arguments = NULL) {
259 $this->request->setDispatched(FALSE);
260 $this->request->setControllerActionName($actionName);
261 if ($controllerName !== NULL) $this->request->setControllerName($controllerName);
262 if ($extensionName !== NULL) $this->request->setControllerExtensionName($extensionName);
263 if ($arguments !== NULL) $this->request->setArguments($arguments);
264 throw new Tx_Extbase_MVC_Exception_StopAction();
265 }
266
267 /**
268 * Forwards the request to another action and / or controller.
269 *
270 * NOTE: This method only supports web requests and will thrown an exception
271 * if used with other request types.
272 *
273 * @param string $actionName Name of the action to forward to
274 * @param string $controllerName Unqualified object name of the controller to forward to. If not specified, the current controller is used.
275 * @param string $extensionName Name of the extension containing the controller to forward to. If not specified, the current extension is assumed.
276 * @param Tx_Extbase_MVC_Controller_Arguments $arguments Arguments to pass to the target action
277 * @param integer $pageUid Target page uid. If NULL, the current page uid is used
278 * @param integer $delay (optional) The delay in seconds. Default is no delay.
279 * @param integer $statusCode (optional) The HTTP status code for the redirect. Default is "303 See Other"
280 * @return void
281 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType If the request is not a web request
282 * @throws Tx_Extbase_MVC_Exception_StopAction
283 * @api
284 */
285 protected function redirect($actionName, $controllerName = NULL, $extensionName = NULL, array $arguments = NULL, $pageUid = NULL, $delay = 0, $statusCode = 303) {
286 if (!$this->request instanceof Tx_Extbase_MVC_Web_Request) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType('redirect() only supports web requests.', 1220539734);
287
288 if ($controllerName === NULL) {
289 $controllerName = $this->request->getControllerName();
290 }
291 if ($pageUid === NULL && isset($GLOBALS['TSFE'])) {
292 $pageUid = $GLOBALS['TSFE']->id;
293 }
294
295 $uri = $this->uriBuilder
296 ->reset()
297 ->setTargetPageUid($pageUid)
298 ->uriFor($actionName, $arguments, $controllerName, $extensionName);
299 $this->redirectToURI($uri, $delay, $statusCode);
300 }
301
302 /**
303 * Redirects the web request to another uri.
304 *
305 * NOTE: This method only supports web requests and will thrown an exception if used with other request types.
306 *
307 * @param mixed $uri A string representation of a URI
308 * @param integer $delay (optional) The delay in seconds. Default is no delay.
309 * @param integer $statusCode (optional) The HTTP status code for the redirect. Default is "303 See Other"
310 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType If the request is not a web request
311 * @throws Tx_Extbase_MVC_Exception_StopAction
312 * @api
313 */
314 protected function redirectToURI($uri, $delay = 0, $statusCode = 303) {
315 if (!$this->request instanceof Tx_Extbase_MVC_Web_Request) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType('redirect() only supports web requests.', 1220539734);
316
317 $uri = $this->addBaseUriIfNecessary($uri);
318 $escapedUri = htmlentities($uri, ENT_QUOTES, 'utf-8');
319 $this->response->setContent('<html><head><meta http-equiv="refresh" content="' . intval($delay) . ';url=' . $escapedUri . '"/></head></html>');
320 $this->response->setStatus($statusCode);
321 $this->response->setHeader('Location', (string)$uri);
322 throw new Tx_Extbase_MVC_Exception_StopAction();
323 }
324
325 /**
326 * Adds the base uri if not already in place.
327 *
328 * @param string $uri The URI
329 * @return void
330 */
331 protected function addBaseUriIfNecessary($uri) {
332 $baseUri = $this->request->getBaseURI();
333 if(stripos($uri, $baseUri) !== 0) {
334 $uri = $baseUri . (string)$uri;
335 }
336 return $uri;
337 }
338
339 /**
340 * Sends the specified HTTP status immediately.
341 *
342 * NOTE: This method only supports web requests and will thrown an exception if used with other request types.
343 *
344 * @param integer $statusCode The HTTP status code
345 * @param string $statusMessage A custom HTTP status message
346 * @param string $content Body content which further explains the status
347 * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType If the request is not a web request
348 * @throws Tx_Extbase_MVC_Exception_StopAction
349 * @api
350 */
351 public function throwStatus($statusCode, $statusMessage = NULL, $content = NULL) {
352 if (!$this->request instanceof Tx_Extbase_MVC_Web_Request) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType('throwStatus() only supports web requests.', 1220539739);
353
354 $this->response->setStatus($statusCode, $statusMessage);
355 if ($content === NULL) $content = $this->response->getStatus();
356 $this->response->setContent($content);
357 throw new Tx_Extbase_MVC_Exception_StopAction();
358 }
359
360 /**
361 * Collects the base validators which were defined for the data type of each
362 * controller argument and adds them to the argument's validator chain.
363 *
364 * @return void
365 */
366 public function initializeControllerArgumentsBaseValidators() {
367 foreach ($this->arguments as $argument) {
368 $validator = $this->validatorResolver->getBaseValidatorConjunction($argument->getDataType());
369 if ($validator !== NULL) $argument->setValidator($validator);
370 }
371 }
372
373 /**
374 * Maps arguments delivered by the request object to the local controller arguments.
375 *
376 * @return void
377 */
378 protected function mapRequestArgumentsToControllerArguments() {
379 $optionalPropertyNames = array();
380 $allPropertyNames = $this->arguments->getArgumentNames();
381 foreach ($allPropertyNames as $propertyName) {
382 if ($this->arguments[$propertyName]->isRequired() === FALSE) $optionalPropertyNames[] = $propertyName;
383 }
384
385 $validator = t3lib_div::makeInstance('Tx_Extbase_MVC_Controller_ArgumentsValidator');
386 $this->propertyMapper->mapAndValidate($allPropertyNames, $this->request->getArguments(), $this->arguments, $optionalPropertyNames, $validator);
387
388 $this->argumentsMappingResults = $this->propertyMapper->getMappingResults();
389 }
390 }
391 ?>