[~TASK] Extbase: Reimplemented BE module support. Still needs cleanup.
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Configuration / BackendConfigurationManager.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 * A general purpose configuration manager used in backend mode.
27 *
28 * @package Extbase
29 * @subpackage Configuration
30 * @version $ID:$
31 */
32 class Tx_Extbase_Configuration_BackendConfigurationManager extends Tx_Extbase_Configuration_AbstractConfigurationManager {
33
34 /**
35 * @var array
36 */
37 protected $typoScriptSetupCache = NULL;
38
39 /**
40 * Transfers the request to an Extbase backend module, calling
41 * a given controller/action.
42 *
43 * @param string $configurationType The kind of configuration to fetch - must be one of the CONFIGURATION_TYPE_* constants
44 * @param string $extensionName if specified, the configuration for the given extension will be returned (plugin.tx_extensionname)
45 * @param string $pluginName if specified, the configuration for the given plugin will be returned (plugin.tx_extensionname_pluginname)
46 * @return string The module rendered view
47 */
48 public function getConfiguration($configurationType, $extensionName = NULL, $pluginName = NULL) {
49 $frameworkConfiguration = array();
50 $frameworkConfiguration['persistence']['storagePid'] = self::DEFAULT_BACKEND_STORAGE_PID;
51 $controllerAction = $this->resolveControllerAction($this->configuration['name']);
52 $setup = $this->getTypoScriptSetup();
53 $frameworkConfiguration = array(
54 'pluginName' => $this->configuration['name'],
55 'extensionName' => $this->configuration['extensionName'],
56 'controller' => $controllerAction['controllerName'],
57 'action' => $controllerAction['actionName'],
58 'switchableControllerActions' => array(),
59 'settings' => $this->resolveTyposcriptReference($setup, 'settings'),
60 'persistence' => $this->resolveTyposcriptReference($setup, 'persistence'),
61 'view' => $this->resolveTyposcriptReference($setup, 'view'),
62 '_LOCAL_LANG' => $this->resolveTyposcriptReference($setup, '_LOCAL_LANG'),
63 );
64
65 foreach ($this->configuration['controllerActions'] as $controller => $actions) {
66 // Add an "extObj" action for the default controller to handle external
67 // SCbase modules which add function menu entries
68 $actions .= ',extObj';
69 $frameworkConfiguration['switchableControllerActions'][$i++] = array(
70 'controller' => $controller,
71 'actions' => $actions,
72 );
73 }
74
75 $extbaseConfiguration = $setup['config.']['tx_extbase.'];
76 if (is_array($extbaseConfiguration)) {
77 $extbaseConfiguration = Tx_Extbase_Utility_TypoScript::convertTypoScriptArrayToPlainArray($extbaseConfiguration);
78 $frameworkConfiguration = t3lib_div::array_merge_recursive_overrule($frameworkConfiguration, $extbaseConfiguration);
79 }
80
81 return $frameworkConfiguration;
82 }
83
84 /**
85 * Resolves the controller and action to use for current call.
86 * This takes into account any function menu that has being called.
87 *
88 * @param string $module The name of the module
89 * @return array The controller/action pair to use for current call
90 */
91 protected function resolveControllerAction($module) {
92 $configuration = $GLOBALS['TBE_MODULES']['_configuration'][$module];
93 $fallbackControllerAction = $this->getFallbackControllerAction($configuration);
94
95 // Extract dispatcher settings from request
96 $argumentPrefix = strtolower('tx_' . $configuration['extensionName'] . '_' . $configuration['name']);
97 $dispatcherParameters = t3lib_div::_GPmerged($argumentPrefix);
98 $dispatcherControllerAction = $this->getDispatcherControllerAction($configuration, $dispatcherParameters);
99
100 // Extract module function settings from request
101 $moduleFunctionControllerAction = $this->getModuleFunctionControllerAction($module, $fallbackControllerAction['controllerName']);
102
103 // Dispatcher controller/action has precedence over default controller/action
104 $controllerAction = t3lib_div::array_merge_recursive_overrule($fallbackControllerAction, $dispatcherControllerAction, FALSE, FALSE);
105 // Module function controller/action has precedence
106 $controllerAction = t3lib_div::array_merge_recursive_overrule($controllerAction, $moduleFunctionControllerAction, FALSE, FALSE);
107
108 return $controllerAction;
109 }
110
111 /**
112 * Returns the fallback controller/action pair to be used when request does not contain
113 * any controller/action to be used or the provided parameters are not valid.
114 *
115 * @param array $configuration The module configuration
116 * @return array The controller/action pair
117 */
118 protected function getFallbackControllerAction($configuration) {
119 // Extract module settings from its registration in ext_tables.php
120 $controllers = array_keys($configuration['controllerActions']);
121 $defaultController = array_shift($controllers);
122 $actions = t3lib_div::trimExplode(',', $configuration['controllerActions'][$defaultController], TRUE);
123 $defaultAction = $actions[0];
124
125 return array(
126 'controllerName' => $defaultController,
127 'actionName' => $defaultAction,
128 );
129 }
130
131 /**
132 * Returns the controller/action pair that was specified by the request if it is valid,
133 * otherwise, will just return a blank controller/action pair meaning the default
134 * controller/action should be used instead.
135 *
136 * @param array $configuration The module configuration
137 * @param array $dispatcherParameters The dispatcher parameters
138 * @return array The controller/action pair
139 */
140 protected function getDispatcherControllerAction($configuration, $dispatcherParameters) {
141 $controllerAction = array(
142 'controllerName' => '',
143 'actionName' => '',
144 );
145
146 if (!isset($dispatcherParameters['controllerName'])) {
147 // Early return: should use fallback controller/action
148 return $controllerAction;
149 }
150
151 // Extract configured controllers from module's registration in ext_tables.php
152 $controllers = array_keys($configuration['controllerActions']);
153
154 $controller = $dispatcherParameters['controllerName'];
155 if (in_array($controller, $controllers)) {
156 // Update return value as selected controller is valid
157 $controllerAction['controllerName'] = $controller;
158 $actions = t3lib_div::trimExplode(',', $configuration['controllerActions'][$controller], TRUE);
159 if (isset($dispatcherParameters['actionName'])) {
160 // Extract configured actions for selected controllers
161 $action = $dispatcherParameters['actionName'];
162 if (in_array($action, $actions)) {
163 // Requested action is valid for selected controller
164 $controllerAction['actionName'] = $action;
165 } else {
166 // Use first action of selected controller as fallback action
167 $controllerAction['actionName'] = $actions[0];
168 }
169 } else {
170 // Use first action of selected controller as fallback action
171 $controllerAction['actionName'] = $actions[0];
172 }
173 }
174
175 return $controllerAction;
176 }
177
178 /**
179 * Returns the controller/action pair to use if a module function parameter is found
180 * in the request, otherwise, will just return a blank controller/action pair.
181 *
182 * @param string $module The name of the module
183 * @param string $defaultController The module's default controller
184 * @return array The controller/action pair
185 */
186 protected function getModuleFunctionControllerAction($module, $defaultController) {
187 $controllerAction = array(
188 'controllerName' => '',
189 'actionName' => '',
190 );
191
192 $set = t3lib_div::_GP('SET');
193 if (!$set) {
194 // Early return
195 return $controllerAction;
196 }
197
198 $moduleFunction = $set['function'];
199 $matches = array();
200 if (preg_match('/^(.*)->(.*)$/', $moduleFunction, $matches)) {
201 $controllerAction['controllerName'] = $matches[1];
202 $controllerAction['actionName'] = $matches[2];
203 } else {
204 // Support for external SCbase module function rendering
205 $functions = $GLOBALS['TBE_MODULES_EXT']['_configuration'][$module]['MOD_MENU']['function'];
206 if (isset($functions[$moduleFunction])) {
207 $controllerAction['controllerName'] = $defaultController;
208 $controllerAction['actionName'] = 'extObj';
209 }
210 }
211
212 return $controllerAction;
213 }
214
215 /**
216 * Returns TypoScript Setup array from current Environment.
217 *
218 * @return array the raw TypoScript setup
219 */
220 public function getTypoScriptSetup() {
221 if ($this->typoScriptSetupCache === NULL) {
222 $template = t3lib_div::makeInstance('t3lib_TStemplate');
223 // do not log time-performance information
224 $template->tt_track = 0;
225 $template->init();
226 // Get the root line
227 $sysPage = t3lib_div::makeInstance('t3lib_pageSelect');
228 // get the rootline for the current page
229 $rootline = $sysPage->getRootLine($this->getCurrentPageId());
230 // This generates the constants/config + hierarchy info for the template.
231 $template->runThroughTemplates($rootline, 0);
232 $template->generateConfig();
233 $this->typoScriptSetupCache = $template->setup;
234 }
235 return $this->typoScriptSetupCache;
236 }
237
238 /**
239 * Returns the page uid of the current page.
240 * If no page is selected, we'll return the uid of the first root page.
241 *
242 * @return integer current page id. If no page is selected current root page id is returned
243 */
244 protected function getCurrentPageId() {
245 $pageId = (integer)t3lib_div::_GP('id');
246 if ($pageId > 0) {
247 return $pageId;
248 }
249
250 // get root template
251 $rootTemplates = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('pid', 'sys_template', 'deleted=0 AND hidden=0 AND root=1', '', '', '1');
252 if (count($rootTemplates) > 0) {
253 return $rootTemplates[0]['pid'];
254 }
255
256 // get current site root
257 $rootPages = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid', 'pages', 'deleted=0 AND hidden=0 AND is_siteroot=1', '', '', '1');
258 if (count($rootPages) > 0) {
259 return $rootPages[0]['uid'];
260 }
261
262 // fallback
263 return self::DEFAULT_BACKEND_STORAGE_PID;
264 }
265
266 }
267 ?>