TYPO3 API  SVNRelease
AbstractController.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
00006 *  All rights reserved
00007 *
00008 *  This class is a backport of the corresponding class of FLOW3.
00009 *  All credits go to the v5 team.
00010 *
00011 *  This script is part of the TYPO3 project. The TYPO3 project is
00012 *  free software; you can redistribute it and/or modify
00013 *  it under the terms of the GNU General Public License as published by
00014 *  the Free Software Foundation; either version 2 of the License, or
00015 *  (at your option) any later version.
00016 *
00017 *  The GNU General Public License can be found at
00018 *  http://www.gnu.org/copyleft/gpl.html.
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00027 
00028 /**
00029  * An abstract base class for Controllers
00030  *
00031  * @package Extbase
00032  * @subpackage MVC\Controller
00033  * @version $ID:$
00034  * @api
00035  */
00036 abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbase_MVC_Controller_ControllerInterface {
00037     /**
00038      * @var Tx_Extbase_Object_ObjectManagerInterface
00039      */
00040     protected $objectManager;
00041 
00042     /**
00043      * @var Tx_Extbase_MVC_Web_Routing_UriBuilder
00044      */
00045     protected $uriBuilder;
00046 
00047     /**
00048      * @var string Key of the extension this controller belongs to
00049      */
00050     protected $extensionName;
00051 
00052     /**
00053      * Contains the settings of the current extension
00054      *
00055      * @var array
00056      * @api
00057      */
00058     protected $settings;
00059 
00060     /**
00061      * The current request.
00062      *
00063      * @var Tx_Extbase_MVC_Request
00064      * @api
00065      */
00066     protected $request;
00067 
00068     /**
00069      * The response which will be returned by this action controller
00070      *
00071      * @var Tx_Extbase_MVC_Response
00072      * @api
00073      */
00074     protected $response;
00075 
00076     /**
00077      * @var Tx_Extbase_Property_Mapper
00078      */
00079     protected $propertyMapper;
00080 
00081     /**
00082      * @var Tx_Extbase_Validation_ValidatorResolver
00083      */
00084     protected $validatorResolver;
00085 
00086     /**
00087      * @var Tx_Extbase_MVC_Controller_Arguments Arguments passed to the controller
00088      */
00089     protected $arguments;
00090 
00091     /**
00092      * The results of the mapping of request arguments to controller arguments
00093      * @var Tx_Extbase_Property_MappingResults
00094      * @api
00095      */
00096     protected $argumentsMappingResults;
00097 
00098     /**
00099      * An array of supported request types. By default only web requests are supported.
00100      * Modify or replace this array if your specific controller supports certain
00101      * (additional) request types.
00102      * @var array
00103      */
00104     protected $supportedRequestTypes = array('Tx_Extbase_MVC_Request');
00105 
00106     /**
00107      * @var Tx_Extbase_MVC_Controller_ControllerContext
00108      * @api
00109      */
00110     protected $controllerContext;
00111 
00112     /**
00113      * The flash messages. DEPRECATED. Use $this->flashMessageContainer instead.
00114      *
00115      * @var Tx_Extbase_MVC_Controller_FlashMessages
00116      * @deprecated
00117      */
00118     protected $flashMessages;
00119 
00120     /**
00121      * The flash messages. Use $this->flashMessageContainer->add(...) to add a new Flash message.
00122      *
00123      * @var Tx_Extbase_MVC_Controller_FlashMessages
00124      * @api
00125      */
00126     protected $flashMessageContainer;
00127 
00128     /**
00129      * @var Tx_Extbase_Configuration_ConfigurationManager
00130      */
00131     protected $configurationManager;
00132 
00133     /**
00134      * Constructs the controller.
00135      */
00136     public function __construct() {
00137         list(, $this->extensionName) = explode('_', get_class($this));
00138     }
00139 
00140     /**
00141      * @param Tx_Extbase_Configuration_ConfigurationManager $configurationManager
00142      * @return void
00143      */
00144     public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManager $configurationManager) {
00145         $this->configurationManager = $configurationManager;
00146         $this->settings = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS);
00147     }
00148 
00149     /**
00150      * Injects the property mapper
00151      *
00152      * @param Tx_Extbase_Property_Mapper $propertyMapper The property mapper
00153      * @return void
00154      */
00155     public function injectPropertyMapper(Tx_Extbase_Property_Mapper $propertyMapper) {
00156         $this->propertyMapper = $propertyMapper;
00157     }
00158 
00159     /**
00160      * Injects the object manager
00161      *
00162      * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
00163      * @return void
00164      */
00165     public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
00166         $this->objectManager = $objectManager;
00167         $this->arguments = $this->objectManager->create('Tx_Extbase_MVC_Controller_Arguments');
00168     }
00169 
00170     /**
00171      * Injects the validator resolver
00172      *
00173      * @param Tx_Extbase_Validation_ValidatorResolver $validatorResolver
00174      * @return void
00175      */
00176     public function injectValidatorResolver(Tx_Extbase_Validation_ValidatorResolver $validatorResolver) {
00177         $this->validatorResolver = $validatorResolver;
00178     }
00179 
00180     /**
00181      * Injects the flash messages container
00182      *
00183      * @param Tx_Extbase_MVC_Controller_FlashMessages $flashMessages
00184      * @return void
00185      */
00186     public function injectFlashMessageContainer(Tx_Extbase_MVC_Controller_FlashMessages $flashMessageContainer) {
00187         $this->flashMessageContainer = $flashMessageContainer;
00188         $this->flashMessages = $flashMessageContainer; // deprecated, but should still work.
00189     }
00190 
00191     /**
00192      * Checks if the current request type is supported by the controller.
00193      *
00194      * If your controller only supports certain request types, either
00195      * replace / modify the supporteRequestTypes property or override this
00196      * method.
00197      *
00198      * @param Tx_Extbase_MVC_Request $request The current request
00199      * @return boolean TRUE if this request type is supported, otherwise FALSE
00200      * @api
00201      */
00202     public function canProcessRequest(Tx_Extbase_MVC_RequestInterface $request) {
00203         foreach ($this->supportedRequestTypes as $supportedRequestType) {
00204             if ($request instanceof $supportedRequestType) return TRUE;
00205         }
00206         return FALSE;
00207     }
00208 
00209     /**
00210      * Processes a general request. The result can be returned by altering the given response.
00211      *
00212      * @param Tx_Extbase_MVC_Request $request The request object
00213      * @param Tx_Extbase_MVC_Response $response The response, modified by this handler
00214      * @return void
00215      * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType if the controller doesn't support the current request type
00216      * @api
00217      */
00218     public function processRequest(Tx_Extbase_MVC_RequestInterface $request, Tx_Extbase_MVC_ResponseInterface $response) {
00219         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);
00220 
00221         $this->request = $request;
00222         $this->request->setDispatched(TRUE);
00223         $this->response = $response;
00224 
00225         $this->uriBuilder = $this->objectManager->create('Tx_Extbase_MVC_Web_Routing_UriBuilder');
00226         $this->uriBuilder->setRequest($request);
00227 
00228         $this->initializeControllerArgumentsBaseValidators();
00229         $this->mapRequestArgumentsToControllerArguments();
00230         $this->controllerContext = $this->buildControllerContext();
00231     }
00232 
00233     /**
00234      * Initialize the controller context
00235      *
00236      * @return Tx_Extbase_MVC_Controller_ControllerContext ControllerContext to be passed to the view
00237      * @api
00238      */
00239     protected function buildControllerContext() {
00240         $controllerContext = $this->objectManager->create('Tx_Extbase_MVC_Controller_ControllerContext');
00241         $controllerContext->setRequest($this->request);
00242         $controllerContext->setResponse($this->response);
00243         if ($this->arguments !== NULL) {
00244             $controllerContext->setArguments($this->arguments);
00245         }
00246         if ($this->argumentsMappingResults !== NULL) {
00247             $controllerContext->setArgumentsMappingResults($this->argumentsMappingResults);
00248         }
00249         $controllerContext->setUriBuilder($this->uriBuilder);
00250         $controllerContext->setFlashMessageContainer($this->flashMessageContainer);
00251         return $controllerContext;
00252     }
00253 
00254     /**
00255      * Forwards the request to another controller.
00256      *
00257      * @param string $actionName Name of the action to forward to
00258      * @param string $controllerName Unqualified object name of the controller to forward to. If not specified, the current controller is used.
00259      * @param string $extensionName Name of the extension containing the controller to forward to. If not specified, the current extension is assumed.
00260      * @param Tx_Extbase_MVC_Controller_Arguments $arguments Arguments to pass to the target action
00261      * @return void
00262      * @throws Tx_Extbase_MVC_Exception_StopAction
00263      * @api
00264      */
00265     public function forward($actionName, $controllerName = NULL, $extensionName = NULL, array $arguments = NULL) {
00266         $this->request->setDispatched(FALSE);
00267         $this->request->setControllerActionName($actionName);
00268         if ($controllerName !== NULL) $this->request->setControllerName($controllerName);
00269         if ($extensionName !== NULL) $this->request->setControllerExtensionName($extensionName);
00270         if ($arguments !== NULL) $this->request->setArguments($arguments);
00271         throw new Tx_Extbase_MVC_Exception_StopAction();
00272     }
00273 
00274     /**
00275      * Forwards the request to another action and / or controller.
00276      *
00277      * NOTE: This method only supports web requests and will thrown an exception
00278      * if used with other request types.
00279      *
00280      * @param string $actionName Name of the action to forward to
00281      * @param string $controllerName Unqualified object name of the controller to forward to. If not specified, the current controller is used.
00282      * @param string $extensionName Name of the extension containing the controller to forward to. If not specified, the current extension is assumed.
00283      * @param Tx_Extbase_MVC_Controller_Arguments $arguments Arguments to pass to the target action
00284      * @param integer $pageUid Target page uid. If NULL, the current page uid is used
00285      * @param integer $delay (optional) The delay in seconds. Default is no delay.
00286      * @param integer $statusCode (optional) The HTTP status code for the redirect. Default is "303 See Other"
00287      * @return void
00288      * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType If the request is not a web request
00289      * @throws Tx_Extbase_MVC_Exception_StopAction
00290      * @api
00291      */
00292     protected function redirect($actionName, $controllerName = NULL, $extensionName = NULL, array $arguments = NULL, $pageUid = NULL, $delay = 0, $statusCode = 303) {
00293         if (!$this->request instanceof Tx_Extbase_MVC_Web_Request) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType('redirect() only supports web requests.', 1220539734);
00294 
00295         if ($controllerName === NULL) {
00296             $controllerName = $this->request->getControllerName();
00297         }
00298 
00299         $uri = $this->uriBuilder
00300             ->reset()
00301             ->setTargetPageUid($pageUid)
00302             ->uriFor($actionName, $arguments, $controllerName, $extensionName);
00303         $this->redirectToURI($uri, $delay, $statusCode);
00304     }
00305 
00306     /**
00307      * Redirects the web request to another uri.
00308      *
00309      * NOTE: This method only supports web requests and will thrown an exception if used with other request types.
00310      *
00311      * @param mixed $uri A string representation of a URI
00312      * @param integer $delay (optional) The delay in seconds. Default is no delay.
00313      * @param integer $statusCode (optional) The HTTP status code for the redirect. Default is "303 See Other"
00314      * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType If the request is not a web request
00315      * @throws Tx_Extbase_MVC_Exception_StopAction
00316      * @api
00317      */
00318     protected function redirectToURI($uri, $delay = 0, $statusCode = 303) {
00319         if (!$this->request instanceof Tx_Extbase_MVC_Web_Request) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType('redirect() only supports web requests.', 1220539734);
00320 
00321         $uri = $this->addBaseUriIfNecessary($uri);
00322         $escapedUri = htmlentities($uri, ENT_QUOTES, 'utf-8');
00323         $this->response->setContent('<html><head><meta http-equiv="refresh" content="' . intval($delay) . ';url=' . $escapedUri . '"/></head></html>');
00324         $this->response->setStatus($statusCode);
00325         $this->response->setHeader('Location', (string)$uri);
00326         throw new Tx_Extbase_MVC_Exception_StopAction();
00327     }
00328 
00329     /**
00330      * Adds the base uri if not already in place.
00331      *
00332      * @param string $uri The URI
00333      * @return void
00334      */
00335     protected function addBaseUriIfNecessary($uri) {
00336         $baseUri = $this->request->getBaseURI();
00337         if(stripos($uri, $baseUri) !== 0) {
00338             $uri = $baseUri . (string)$uri;
00339         }
00340         return $uri;
00341     }
00342 
00343     /**
00344      * Sends the specified HTTP status immediately.
00345      *
00346      * NOTE: This method only supports web requests and will thrown an exception if used with other request types.
00347      *
00348      * @param integer $statusCode The HTTP status code
00349      * @param string $statusMessage A custom HTTP status message
00350      * @param string $content Body content which further explains the status
00351      * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType If the request is not a web request
00352      * @throws Tx_Extbase_MVC_Exception_StopAction
00353      * @api
00354      */
00355     public function throwStatus($statusCode, $statusMessage = NULL, $content = NULL) {
00356         if (!$this->request instanceof Tx_Extbase_MVC_Web_Request) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType('throwStatus() only supports web requests.', 1220539739);
00357 
00358         $this->response->setStatus($statusCode, $statusMessage);
00359         if ($content === NULL) $content = $this->response->getStatus();
00360         $this->response->setContent($content);
00361         throw new Tx_Extbase_MVC_Exception_StopAction();
00362     }
00363 
00364     /**
00365      * Collects the base validators which were defined for the data type of each
00366      * controller argument and adds them to the argument's validator chain.
00367      *
00368      * @return void
00369      */
00370     public function initializeControllerArgumentsBaseValidators() {
00371         foreach ($this->arguments as $argument) {
00372             $validator = $this->validatorResolver->getBaseValidatorConjunction($argument->getDataType());
00373             if ($validator !== NULL) $argument->setValidator($validator);
00374         }
00375     }
00376 
00377     /**
00378      * Maps arguments delivered by the request object to the local controller arguments.
00379      *
00380      * @return void
00381      */
00382     protected function mapRequestArgumentsToControllerArguments() {
00383         $optionalPropertyNames = array();
00384         $allPropertyNames = $this->arguments->getArgumentNames();
00385         foreach ($allPropertyNames as $propertyName) {
00386             if ($this->arguments[$propertyName]->isRequired() === FALSE) $optionalPropertyNames[] = $propertyName;
00387         }
00388 
00389         $validator = $this->objectManager->create('Tx_Extbase_MVC_Controller_ArgumentsValidator');
00390         $this->propertyMapper->mapAndValidate($allPropertyNames, $this->request->getArguments(), $this->arguments, $optionalPropertyNames, $validator);
00391 
00392         $this->argumentsMappingResults = $this->propertyMapper->getMappingResults();
00393     }
00394 }
00395 ?>