ExtBase:
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / class.tx_extbase_dispatcher.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 /**
26 * Creates a request an dispatches it to the controller which was specified
27 * by TS Setup, Flexform and returns the content to the v4 framework.
28 *
29 * @package TYPO3
30 * @subpackage extbase
31 * @version $ID:$
32 */
33 class Tx_ExtBase_Dispatcher {
34
35 /**
36 * @var Tx_ExtBase_Configuration_Manager A reference to the configuration manager
37 */
38 protected $configurationManager;
39
40 /**
41 * @var Tx_ExtBase_Web_RequestBuilder
42 */
43 protected $requestBuilder;
44
45 /**
46 * @var ArrayObject The raw GET parameters
47 */
48 protected $getParameters;
49
50 /**
51 * @var ArrayObject The raw POST parameters
52 */
53 protected $postParameters;
54
55 /**
56 * @var array An array of registered classes (class files with path)
57 */
58 protected $registeredClassNames;
59
60 /**
61 * Constructs this dispatcher
62 *
63 */
64 public function __construct() {
65 spl_autoload_register(array($this, 'autoLoadClasses'));
66 }
67
68 /**
69 * Creates a request an dispatches it to a controller.
70 *
71 * @param String $content The content
72 * @param array|NULL $configuration The TS configuration array
73 * @uses t3lib_div::_GET()
74 * @uses t3lib_div::makeInstance()
75 * @uses t3lib_div::GParrayMerged()
76 * @uses t3lib_div::getIndpEnv()
77 * @return String $content The processed content
78 */
79 public function dispatch($content, $configuration) {
80 $parameters = t3lib_div::_GET();
81 $extensionName = $configuration['extension'];
82 $controllerName = $configuration['controller'];
83 $allowedActions = t3lib_div::trimExplode(',', $configuration['allowedActions']);
84 if (isset($parameters['action']) && in_array($parameters['action'], $allowedActions)) {
85 $actionName = stripslashes($parameters['action']);
86 } else {
87 $actionName = $configuration['action'];
88 }
89 if (empty($extensionName) || empty($controllerName) || empty($allowedActions)) {
90 throw new Exception('Could not dispatch the request. Please configure your plugin in the TS Setup.', 1237879677);
91 }
92
93 $request = $this->buildRequest($extensionName, $controllerName, $actionName);
94 $controller = t3lib_div::makeInstance($request->getControllerObjectName());
95 if (!$controller instanceof Tx_ExtBase_Controller_ControllerInterface) {
96 throw new Tx_ExtBase_Exception_InvalidController('Invalid controller "' . $request->getControllerObjectName() . '". The controller must be a valid request handling controller.', 1202921619);
97 }
98
99 if (!$controller->isCachableAction($actionName) && $this->cObj->getUserObjectType() === tslib_cObj::OBJECTTYPE_USER) {
100 // FIXME Caching does not work because it's by default a USER object, so the dispatcher is never called
101 // SK: does caching already work?
102 $this->cObj->convertToUserIntObject();
103 return $content;
104 }
105
106 $arguments = t3lib_div::makeInstance('Tx_ExtBase_Controller_Arguments');
107 // SK: strtolower($extensionName) is wrong I think, as all underscores need to be removed as well.
108 // SK: Example: tt_news -> tx_ttnews
109 foreach (t3lib_div::GParrayMerged('tx_' . strtolower($extensionName)) as $key => $value) {
110 $request->setArgument($key, $value);
111 }
112
113 $response = t3lib_div::makeInstance('Tx_ExtBase_Web_Response');
114 $controller->injectSettings($this->getSettings($extensionName));
115
116 $persistenceSession = t3lib_div::makeInstance('Tx_ExtBase_Persistence_Session');
117 try {
118 $controller->processRequest($request, $response);
119 } catch (Tx_ExtBase_Exception_StopAction $ignoredException) {
120 }
121 // debug($persistenceSession);
122 $persistenceSession->commit();
123 $persistenceSession->clear();
124
125 if (count($response->getAdditionalHeaderData()) > 0) {
126 $GLOBALS['TSFE']->additionalHeaderData[$request->getExtensionName()] = implode("\n", $response->getAdditionalHeaderData());
127 }
128 // TODO Handle $response->getStatus()
129 // SK: Call sendHeaders() on the response
130 return $response->getContent();
131 }
132
133 protected function getSettings($extensionName) {
134 $configurationSources = array();
135 $configurationSources[] = t3lib_div::makeInstance('Tx_ExtBase_Configuration_Source_TypoScriptSource');
136 if (!empty($this->cObj->data['pi_flexform'])) {
137 $configurationSource = t3lib_div::makeInstance('Tx_ExtBase_Configuration_Source_FlexFormSource');
138 $configurationSource->setFlexFormContent($this->cObj->data['pi_flexform']);
139 $configurationSources[] = $configurationSource;
140 }
141 $configurationManager = t3lib_div::makeInstance('Tx_ExtBase_Configuration_Manager', $configurationSources);
142 $configurationManager->loadGlobalSettings($extensionName);
143 return $configurationManager->getSettings($extensionName);
144 }
145
146 protected function buildRequest($extensionName, $controllerName, $actionName) {
147 $request = t3lib_div::makeInstance('Tx_ExtBase_Web_Request');
148 $request->setExtensionName($extensionName);
149 $request->setControllerName($controllerName);
150 $request->setControllerActionName($actionName);
151 $request->setRequestURI(t3lib_div::getIndpEnv('TYPO3_REQUEST_URL'));
152 $request->setBaseURI(t3lib_div::getIndpEnv('TYPO3_SITE_URL'));
153 return $request;
154 }
155
156 /**
157 * Loads php files containing classes or interfaces found in the classes directory of
158 * an extension.
159 *
160 * @param string $className: Name of the class/interface to load
161 * @uses t3lib_extMgm::extPath()
162 * @return void
163 */
164 // TODO Remove autoloader as soon as we do not need it anymore
165 public function autoLoadClasses($className) {
166 if (empty($this->registeredClassNames[$className])) {
167 $classNameParts = explode('_', $className);
168 if ($classNameParts[0] === 'ux') {
169 array_shift($classNameParts);
170 }
171 if (count($classNameParts) > 2 && $classNameParts[0] === 'Tx') {
172 $classFilePathAndName = t3lib_extMgm::extPath(strtolower($classNameParts[1])) . 'Classes/';
173 $classFilePathAndName .= implode(array_slice($classNameParts, 2, -1), '/') . '/';
174 $classFilePathAndName .= array_pop($classNameParts) . '.php';
175 }
176 if (isset($classFilePathAndName) && file_exists($classFilePathAndName)) {
177 require_once($classFilePathAndName);
178 $this->registeredClassNames[$className] = $classFilePathAndName;
179 }
180 }
181 }
182
183 }
184 ?>