[+FEATURE] Backport CommandController Implementation
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Configuration / AbstractConfigurationManager.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 * Abstract base class for a general purpose configuration manager
27 *
28 * @package Extbase
29 * @subpackage Configuration
30 * @version $ID:$
31 */
32 abstract class Tx_Extbase_Configuration_AbstractConfigurationManager implements t3lib_Singleton {
33
34 /**
35 * Default backend storage PID
36 */
37 const DEFAULT_BACKEND_STORAGE_PID = 0;
38
39 /**
40 * Storage of the raw TypoScript configuration
41 * @var array
42 */
43 protected $configuration = array();
44
45 /**
46 * @var tslib_cObj
47 */
48 protected $contentObject;
49
50 /**
51 * @var Tx_Extbase_Object_ObjectManagerInterface
52 */
53 protected $objectManager;
54
55 /**
56 * @var Tx_Extbase_Service_TypoScriptService
57 */
58 protected $typoScriptService;
59
60 /**
61 * name of the extension this Configuration Manager instance belongs to
62 * @var string
63 */
64 protected $extensionName;
65
66 /**
67 * name of the plugin this Configuration Manager instance belongs to
68 * @var string
69 */
70 protected $pluginName;
71
72 /**
73 * 1st level configuration cache
74 *
75 * @var array
76 */
77 protected $configurationCache = array();
78
79 /**
80 * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
81 * @return void
82 */
83 public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
84 $this->objectManager = $objectManager;
85 }
86
87 /**
88 * @param Tx_Extbase_Service_TypoScriptService $typoScriptService
89 * @return void
90 */
91 public function injectTypoScriptService(Tx_Extbase_Service_TypoScriptService $typoScriptService) {
92 $this->typoScriptService = $typoScriptService;
93 }
94
95 /**
96 * @param tslib_cObj $contentObject
97 * @return void
98 */
99 public function setContentObject(tslib_cObj $contentObject = NULL) {
100 $this->contentObject = $contentObject;
101 }
102
103 /**
104 * @return tslib_cObj
105 */
106 public function getContentObject() {
107 if ($this->contentObject !== NULL) {
108 return $this->contentObject;
109 }
110 }
111
112 /**
113 * Sets the specified raw configuration coming from the outside.
114 * Note that this is a low level method and only makes sense to be used by Extbase internally.
115 *
116 * @param array $configuration The new configuration
117 * @return void
118 */
119 public function setConfiguration(array $configuration = array()) {
120 // reset 1st level cache
121 $this->configurationCache = array();
122
123 $this->extensionName = isset($configuration['extensionName']) ? $configuration['extensionName'] : NULL;
124 $this->pluginName = isset($configuration['pluginName']) ? $configuration['pluginName'] : NULL;
125 $this->configuration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($configuration);
126 }
127
128 /**
129 * Loads the Extbase Framework configuration.
130 *
131 * The Extbase framework configuration HAS TO be retrieved using this method, as they are come from different places than the normal settings.
132 * Framework configuration is, in contrast to normal settings, needed for the Extbase framework to operate correctly.
133 *
134 * @param string $extensionName if specified, the configuration for the given extension will be returned (plugin.tx_extensionname)
135 * @param string $pluginName if specified, the configuration for the given plugin will be returned (plugin.tx_extensionname_pluginname)
136 * @return array the Extbase framework configuration
137 */
138 public function getConfiguration($extensionName = NULL, $pluginName = NULL) {
139 // 1st level cache
140 if ($extensionName !== NULL) {
141 if ($pluginName === NULL) {
142 throw new Tx_Extbase_Configuration_Exception('You\'ll have to specify either both, extensionName and pluginName, or neither.', 1289852422);
143 }
144 $configurationCacheKey = strtolower($extensionName . '_' . $pluginName);
145 } else {
146 $configurationCacheKey = strtolower($this->extensionName . '_' . $this->pluginName);
147 }
148 if (isset($this->configurationCache[$configurationCacheKey])) {
149 return $this->configurationCache[$configurationCacheKey];
150 }
151
152 $frameworkConfiguration = $this->getExtbaseConfiguration();
153 if (!isset($frameworkConfiguration['persistence']['storagePid'])) {
154 $frameworkConfiguration['persistence']['storagePid'] = self::DEFAULT_BACKEND_STORAGE_PID;
155 }
156
157 // only merge $this->configuration and override switchableControllerActions when retrieving configuration of the current plugin
158 if ($extensionName === NULL || ($extensionName === $this->extensionName && $pluginName === $this->pluginName)) {
159 $pluginConfiguration = $this->getPluginConfiguration($this->extensionName, $this->pluginName);
160 $pluginConfiguration = t3lib_div::array_merge_recursive_overrule($pluginConfiguration, $this->configuration);
161 $pluginConfiguration['controllerConfiguration'] = $this->getSwitchableControllerActions($this->extensionName, $this->pluginName);
162 if (isset($this->configuration['switchableControllerActions'])) {
163 $this->overrideSwitchableControllerActions($pluginConfiguration, $this->configuration['switchableControllerActions']);
164 }
165 } else {
166 $pluginConfiguration = $this->getPluginConfiguration($extensionName, $pluginName);
167 $pluginConfiguration['controllerConfiguration'] = $this->getSwitchableControllerActions($extensionName, $pluginName);
168 }
169 $frameworkConfiguration = t3lib_div::array_merge_recursive_overrule($frameworkConfiguration, $pluginConfiguration);
170
171 // only load context specific configuration when retrieving configuration of the current plugin
172 if ($extensionName === NULL || ($extensionName === $this->extensionName && $pluginName === $this->pluginName)) {
173 $frameworkConfiguration = $this->getContextSpecificFrameworkConfiguration($frameworkConfiguration);
174 }
175
176 if (!empty($frameworkConfiguration['persistence']['storagePid']) &&
177 is_array($frameworkConfiguration['persistence']['storagePid'])) {
178 /**
179 * We simulate the frontend to enable the use of cObjects in
180 * stdWrap. Than we convert the configuration to normal TypoScript
181 * and apply the stdWrap to the storagePid
182 */
183 if (TYPO3_MODE !== 'FE') {
184 Tx_Extbase_Utility_FrontendSimulator::simulateFrontendEnvironment($this->getContentObject());
185 }
186 $configuration = $this->typoScriptService->convertPlainArrayToTypoScriptArray($frameworkConfiguration['persistence']);
187 $frameworkConfiguration['persistence']['storagePid'] = $GLOBALS['TSFE']->cObj->stdWrap($configuration['storagePid'], $configuration['storagePid.']);
188 if (TYPO3_MODE !== 'FE') {
189 Tx_Extbase_Utility_FrontendSimulator::resetFrontendEnvironment();
190 }
191 }
192
193 // 1st level cache
194 $this->configurationCache[$configurationCacheKey] = $frameworkConfiguration;
195 return $frameworkConfiguration;
196 }
197
198 /**
199 * Returns the TypoScript configuration found in config.tx_extbase
200 *
201 * @return array
202 */
203 protected function getExtbaseConfiguration() {
204 $setup = $this->getTypoScriptSetup();
205 $extbaseConfiguration = array();
206 if (isset($setup['config.']['tx_extbase.'])) {
207 $extbaseConfiguration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($setup['config.']['tx_extbase.']);
208 }
209 return $extbaseConfiguration;
210 }
211
212 /**
213 * @param array $frameworkConfiguration
214 * @param array $overriddenSwitchableControllerActions in the format array('Controller1' => array('action1', 'action2'), 'Controller2' => ...)
215 * @return void
216 */
217 protected function overrideSwitchableControllerActions(array &$frameworkConfiguration, array $switchableControllerActions) {
218 $overriddenSwitchableControllerActions = array();
219 foreach ($switchableControllerActions as $controllerName => $actions) {
220 if (!isset($frameworkConfiguration['controllerConfiguration'][$controllerName])) {
221 continue;
222 }
223 $overriddenSwitchableControllerActions[$controllerName] = array('actions' => $actions);
224 $nonCacheableActions = $frameworkConfiguration['controllerConfiguration'][$controllerName]['nonCacheableActions'];
225
226 if (!is_array($nonCacheableActions)) {
227 // There are no non-cacheable actions, thus we can directly continue
228 // with the next controller name.
229 continue;
230 }
231
232 $overriddenNonCacheableActions = array_intersect($nonCacheableActions, $actions);
233 if (!empty($overriddenNonCacheableActions)) {
234 $overriddenSwitchableControllerActions[$controllerName]['nonCacheableActions'] = $overriddenNonCacheableActions;
235 }
236 }
237 $frameworkConfiguration['controllerConfiguration'] = $overriddenSwitchableControllerActions;
238 }
239
240 /**
241 * The context specific configuration returned by this method
242 * will override the framework configuration which was
243 * obtained from TypoScript. This can be used f.e. to override the storagePid
244 * with the value set inside the Plugin Instance.
245 *
246 * WARNING: Make sure this method ALWAYS returns an array!
247 *
248 * @param array $frameworkConfiguration The framework configuration until now
249 * @return array context specific configuration which will override the configuration obtained by TypoScript
250 */
251 abstract protected function getContextSpecificFrameworkConfiguration(array $frameworkConfiguration);
252
253 /**
254 * Returns TypoScript Setup array from current Environment.
255 *
256 * @return array the TypoScript setup
257 */
258 abstract public function getTypoScriptSetup();
259
260 /**
261 * Returns the TypoScript configuration found in plugin.tx_yourextension_yourplugin / module.tx_yourextension_yourmodule
262 * merged with the global configuration of your extension from plugin.tx_yourextension / module.tx_yourextension
263 *
264 * @param string $extensionName
265 * @param string $pluginName in FE mode this is the specified plugin name, in BE mode this is the full module signature
266 * @return array
267 */
268 abstract protected function getPluginConfiguration($extensionName, $pluginName);
269
270 /**
271 * Returns the configured controller/action pairs of the specified plugin/module in the format
272 * array(
273 * 'Controller1' => array('action1', 'action2'),
274 * 'Controller2' => array('action3', 'action4')
275 * )
276 *
277 * @param string $extensionName
278 * @param string $pluginName in FE mode this is the specified plugin name, in BE mode this is the full module signature
279 * @return array
280 */
281 abstract protected function getSwitchableControllerActions($extensionName, $pluginName);
282 }
283 ?>