c9e744c69a9ff3e982d8c53929f4448266c03789
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Configuration / FrontendConfigurationManager.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 frontend mode.
27 *
28 * Should NOT be singleton, as a new configuration manager is needed per plugin.
29 *
30 * @package Extbase
31 * @subpackage Configuration
32 * @version $ID:$
33 */
34 class Tx_Extbase_Configuration_FrontendConfigurationManager extends Tx_Extbase_Configuration_AbstractConfigurationManager {
35
36 /**
37 * Returns TypoScript Setup array from current Environment.
38 *
39 * @return array the raw TypoScript setup
40 */
41 public function getTypoScriptSetup() {
42 return $GLOBALS['TSFE']->tmpl->setup;
43 }
44
45 /**
46 * Returns the TypoScript configuration found in plugin.tx_yourextension_yourplugin
47 * merged with the global configuration of your extension from plugin.tx_yourextension
48 *
49 * @param string $extensionName
50 * @param string $pluginName
51 * @return array
52 */
53 protected function getPluginConfiguration($extensionName, $pluginName) {
54 $setup = $this->getTypoScriptSetup();
55 $pluginConfiguration = array();
56 if (is_array($setup['plugin.']['tx_' . strtolower($extensionName) . '.'])) {
57 $pluginConfiguration = Tx_Extbase_Utility_TypoScript::convertTypoScriptArrayToPlainArray($setup['plugin.']['tx_' . strtolower($extensionName) . '.']);
58 }
59 $pluginSignature = strtolower($extensionName . '_' . $pluginName);
60 if (is_array($setup['plugin.']['tx_' . $pluginSignature . '.'])) {
61 $pluginConfiguration = t3lib_div::array_merge_recursive_overrule($pluginConfiguration, Tx_Extbase_Utility_TypoScript::convertTypoScriptArrayToPlainArray($setup['plugin.']['tx_' . $pluginSignature . '.']));
62 }
63 return $pluginConfiguration;
64 }
65
66 /**
67 * Returns the configured controller/action pairs of the specified plugin in the format
68 * array(
69 * 'Controller1' => array('action1', 'action2'),
70 * 'Controller2' => array('action3', 'action4')
71 * )
72 *
73 * @param string $extensionName
74 * @param string $pluginName
75 * @return array
76 */
77 protected function getSwitchableControllerActions($extensionName, $pluginName) {
78 $switchableControllerActions = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins'][$pluginName]['controllers'];
79 if (!is_array($switchableControllerActions)) {
80 $switchableControllerActions = array();
81 }
82 return $switchableControllerActions;
83 }
84
85 /**
86 * Get context specific framework configuration.
87 * - Overrides storage PID with setting "Startingpoint"
88 * - merge flexform configuration, if needed
89 *
90 * @param array $frameworkConfiguration The framework configuration to modify
91 * @return array the modified framework configuration
92 */
93 protected function getContextSpecificFrameworkConfiguration(array $frameworkConfiguration) {
94 $frameworkConfiguration = $this->overrideStoragePidIfStartingPointIsSet($frameworkConfiguration);
95 $frameworkConfiguration = $this->overrideConfigurationFromPlugin($frameworkConfiguration);
96 $frameworkConfiguration = $this->overrideConfigurationFromFlexform($frameworkConfiguration);
97
98 return $frameworkConfiguration;
99 }
100
101 /**
102 * Overrides the storage PID settings, in case the "Startingpoint" settings
103 * is set in the plugin configuration.
104 *
105 * @param array $frameworkConfiguration the framework configurations
106 * @return array the framework configuration with overriden storagePid
107 */
108 protected function overrideStoragePidIfStartingPointIsSet(array $frameworkConfiguration) {
109 $pages = $this->contentObject->data['pages'];
110 if (is_string($pages) && strlen($pages) > 0) {
111 $list = array();
112 if($this->contentObject->data['recursive'] > 0) {
113 $explodedPages = t3lib_div::trimExplode(',', $pages);
114 foreach($explodedPages as $pid) {
115 $list[] = trim($this->contentObject->getTreeList($pid, $this->contentObject->data['recursive']), ',');
116 }
117 }
118 if (count($list) > 0) {
119 $pages = $pages . ',' . implode(',', $list);
120 }
121 $frameworkConfiguration = t3lib_div::array_merge_recursive_overrule($frameworkConfiguration, array(
122 'persistence' => array(
123 'storagePid' => $pages
124 )
125 ));
126 }
127 return $frameworkConfiguration;
128 }
129
130 /**
131 * Overrides configuration settings from the plugin typoscript (plugin.tx_myext_pi1.)
132 *
133 * @param array the framework configuration
134 * @return array the framework configuration with overridden data from typoscript
135 */
136 protected function overrideConfigurationFromPlugin(array $frameworkConfiguration) {
137 $setup = $this->getTypoScriptSetup();
138 $pluginSignature = strtolower($frameworkConfiguration['extensionName'] . '_' . $frameworkConfiguration['pluginName']);
139 $pluginConfiguration = $setup['plugin.']['tx_' . $pluginSignature . '.'];
140 if (is_array($pluginConfiguration)) {
141 $pluginConfiguration = Tx_Extbase_Utility_TypoScript::convertTypoScriptArrayToPlainArray($pluginConfiguration);
142 $frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $pluginConfiguration, 'settings');
143 $frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $pluginConfiguration, 'persistence');
144 $frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $pluginConfiguration, 'view');
145 }
146 return $frameworkConfiguration;
147 }
148
149 /**
150 * Overrides configuration settings from flexforms.
151 * This merges the whole flexform data, and overrides switchable controller actions.
152 *
153 * @param array the framework configuration
154 * @return array the framework configuration with overridden data from flexform
155 */
156 protected function overrideConfigurationFromFlexform(array $frameworkConfiguration) {
157 if (strlen($this->contentObject->data['pi_flexform']) > 0) {
158 $flexformConfiguration = $this->convertFlexformContentToArray($this->contentObject->data['pi_flexform']);
159
160 $frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $flexformConfiguration, 'settings');
161 $frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $flexformConfiguration, 'persistence');
162 $frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $flexformConfiguration, 'view');
163
164 $frameworkConfiguration = $this->overrideSwitchableControllerActionsFromFlexform($frameworkConfiguration, $flexformConfiguration);
165 }
166 return $frameworkConfiguration;
167 }
168
169 /**
170 * Parses the FlexForm content and converts it to an array
171 * The resulting array will be multi-dimensional, as a value "bla.blubb"
172 * results in two levels, and a value "bla.blubb.bla" results in three levels.
173 *
174 * Note: multi-language FlexForms are not supported yet
175 *
176 * @param string $flexFormContent FlexForm xml string
177 * @return array the processed array
178 */
179 protected function convertFlexformContentToArray($flexFormContent) {
180 $settings = array();
181 $languagePointer = 'lDEF';
182 $valuePointer = 'vDEF';
183
184 $flexFormArray = t3lib_div::xml2array($flexFormContent);
185 $flexFormArray = isset($flexFormArray['data']) ? $flexFormArray['data'] : array();
186 foreach(array_values($flexFormArray) as $languages) {
187 if (!is_array($languages[$languagePointer])) {
188 continue;
189 }
190
191 foreach($languages[$languagePointer] as $valueKey => $valueDefinition) {
192 if (strpos($valueKey, '.') === false) {
193 $settings[$valueKey] = $this->walkFlexformNode($valueDefinition, $valuePointer);
194 } else {
195 $valueKeyParts = explode('.', $valueKey);
196 $currentNode =& $settings;
197 foreach ($valueKeyParts as $valueKeyPart) {
198 $currentNode =& $currentNode[$valueKeyPart];
199 }
200 if (is_array($valueDefinition)) {
201 if (array_key_exists($valuePointer, $valueDefinition)) {
202 $currentNode = $valueDefinition[$valuePointer];
203 } else {
204 $currentNode = $this->walkFlexformNode($valueDefinition, $valuePointer);
205 }
206 } else {
207 $currentNode = $valueDefinition;
208 }
209 }
210 }
211 }
212 return $settings;
213 }
214
215 /**
216 * Parses a flexform node recursively and takes care of sections etc
217 * @param array $nodeArray The flexform node to parse
218 * @param string $valuePointer The valuePointer to use for value retrieval
219 */
220 protected function walkFlexformNode($nodeArray, $valuePointer = 'vDEF') {
221 if (is_array($nodeArray)) {
222 $return = array();
223
224 foreach ($nodeArray as $nodeKey => $nodeValue) {
225 if (in_array($nodeKey, array('el', '_arrayContainer'))) {
226 return $this->walkFlexformNode($nodeValue, $valuePointer);
227 }
228
229 if (substr($nodeKey, 0, 1) === '_') {
230 continue;
231 }
232
233 if (strpos($nodeKey, '.')) {
234 $nodeKeyParts = explode('.', $nodeKey);
235 $currentNode =& $return;
236 for ($i = 0; $i < count($nodeKeyParts) - 1; $i++) {
237 $currentNode =& $currentNode[$nodeKeyParts[$i]];
238 }
239 $newNode = array(next($nodeKeyParts) => $nodeValue);
240 $currentNode = $this->walkFlexformNode($newNode, $valuePointer);
241 } else if (is_array($nodeValue)) {
242 if (array_key_exists($valuePointer, $nodeValue)) {
243 $return[$nodeKey] = $nodeValue[$valuePointer];
244 } else {
245 $return[$nodeKey] = $this->walkFlexformNode($nodeValue, $valuePointer);
246 }
247 } else {
248 $return[$nodeKey] = $nodeValue;
249 }
250 }
251 return $return;
252 }
253
254 return $nodeArray;
255 }
256
257 /**
258 * Merge a configuration into the framework configuration.
259 *
260 * @param array $frameworkConfiguration the framework configuration to merge the data on
261 * @param array $configuration The configuration
262 * @param string $configurationPartName The name of the configuration part which should be merged.
263 * @return array the processed framework configuration
264 */
265 protected function mergeConfigurationIntoFrameworkConfiguration(array $frameworkConfiguration, array $configuration, $configurationPartName) {
266 if (is_array($frameworkConfiguration[$configurationPartName]) && is_array($configuration[$configurationPartName])) {
267 $frameworkConfiguration[$configurationPartName] = t3lib_div::array_merge_recursive_overrule($frameworkConfiguration[$configurationPartName], $configuration[$configurationPartName]);
268 }
269 return $frameworkConfiguration;
270 }
271
272
273 /**
274 * Overrides the switchable controller actions from the flexform.
275 *
276 * @param array $frameworkConfiguration The original framework configuration
277 * @param array $flexformConfiguration The full flexform configuration
278 * @return array the modified framework configuration, if needed
279 * @todo: Check that the controller has been before inside the switchableControllerActions.
280 */
281 protected function overrideSwitchableControllerActionsFromFlexform(array $frameworkConfiguration, array $flexformConfiguration) {
282 if (!isset($flexformConfiguration['switchableControllerActions']) || is_array($flexformConfiguration['switchableControllerActions'])) {
283 return $frameworkConfiguration;
284 }
285
286 // As "," is the flexform field value delimiter, we need to use ";" as in-field delimiter. That's why we need to replace ; by , first.
287 $switchableControllerActionPartsFromFlexform = t3lib_div::trimExplode(',', str_replace(';', ',', $flexformConfiguration['switchableControllerActions']), TRUE);
288
289 $newSwitchableControllerActionsFromFlexform = array();
290 foreach ($switchableControllerActionPartsFromFlexform as $switchableControllerActionPartFromFlexform) {
291 list($controller, $action) = explode('->', $switchableControllerActionPartFromFlexform);
292 if (empty($controller) || empty($action)) {
293 throw new Tx_Extbase_Configuration_Exception_ParseError('Controller or action were empty when overriding switchableControllerActions from flexform.', 1257146403);
294 }
295 $newSwitchableControllerActionsFromFlexform[$controller][] = $action;
296 }
297
298 if (count($newSwitchableControllerActionsFromFlexform)) {
299 $this->overrideSwitchableControllerActions($frameworkConfiguration, $newSwitchableControllerActionsFromFlexform);
300 }
301 return $frameworkConfiguration;
302 }
303 }
304 ?>