[FEATURE] Recursive starting point/storage pid via TypoScript
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Configuration / FrontendConfigurationManager.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Configuration;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2010-2012 Extbase Team (http://forge.typo3.org/projects/typo3v4-mvc)
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the textfile GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29 /**
30 * A general purpose configuration manager used in frontend mode.
31 *
32 * Should NOT be singleton, as a new configuration manager is needed per plugin.
33 */
34 class FrontendConfigurationManager extends \TYPO3\CMS\Extbase\Configuration\AbstractConfigurationManager {
35
36 /**
37 * @var \TYPO3\CMS\Extbase\Service\FlexFormService
38 */
39 protected $flexFormService;
40
41 /**
42 * @param \TYPO3\CMS\Extbase\Service\FlexFormService $flexFormService
43 * @return void
44 */
45 public function injectFlexFormService(\TYPO3\CMS\Extbase\Service\FlexFormService $flexFormService) {
46 $this->flexFormService = $flexFormService;
47 }
48
49 /**
50 * Returns TypoScript Setup array from current Environment.
51 *
52 * @return array the raw TypoScript setup
53 */
54 public function getTypoScriptSetup() {
55 return $GLOBALS['TSFE']->tmpl->setup;
56 }
57
58 /**
59 * Returns the TypoScript configuration found in plugin.tx_yourextension_yourplugin
60 * merged with the global configuration of your extension from plugin.tx_yourextension
61 *
62 * @param string $extensionName
63 * @param string $pluginName
64 * @return array
65 */
66 protected function getPluginConfiguration($extensionName, $pluginName = NULL) {
67 $setup = $this->getTypoScriptSetup();
68 $pluginConfiguration = array();
69 if (is_array($setup['plugin.']['tx_' . strtolower($extensionName) . '.'])) {
70 $pluginConfiguration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($setup['plugin.']['tx_' . strtolower($extensionName) . '.']);
71 }
72 if ($pluginName !== NULL) {
73 $pluginSignature = strtolower($extensionName . '_' . $pluginName);
74 if (is_array($setup['plugin.']['tx_' . $pluginSignature . '.'])) {
75 $pluginConfiguration = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($pluginConfiguration, $this->typoScriptService->convertTypoScriptArrayToPlainArray($setup['plugin.']['tx_' . $pluginSignature . '.']));
76 }
77 }
78 return $pluginConfiguration;
79 }
80
81 /**
82 * Returns the configured controller/action pairs of the specified plugin in the format
83 * array(
84 * 'Controller1' => array('action1', 'action2'),
85 * 'Controller2' => array('action3', 'action4')
86 * )
87 *
88 * @param string $extensionName
89 * @param string $pluginName
90 * @return array
91 */
92 protected function getSwitchableControllerActions($extensionName, $pluginName) {
93 $switchableControllerActions = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins'][$pluginName]['controllers'];
94 if (!is_array($switchableControllerActions)) {
95 $switchableControllerActions = array();
96 }
97 return $switchableControllerActions;
98 }
99
100 /**
101 * Get context specific framework configuration.
102 * - Overrides storage PID with setting "Startingpoint"
103 * - merge flexForm configuration, if needed
104 *
105 * @param array $frameworkConfiguration The framework configuration to modify
106 * @return array the modified framework configuration
107 */
108 protected function getContextSpecificFrameworkConfiguration(array $frameworkConfiguration) {
109 $frameworkConfiguration = $this->overrideStoragePidIfStartingPointIsSet($frameworkConfiguration);
110 $frameworkConfiguration = $this->overrideConfigurationFromPlugin($frameworkConfiguration);
111 $frameworkConfiguration = $this->overrideConfigurationFromFlexForm($frameworkConfiguration);
112 return $frameworkConfiguration;
113 }
114
115 /**
116 * Overrides the storage PID settings, in case the "Startingpoint" settings
117 * is set in the plugin configuration.
118 *
119 * @param array $frameworkConfiguration the framework configurations
120 * @return array the framework configuration with overriden storagePid
121 */
122 protected function overrideStoragePidIfStartingPointIsSet(array $frameworkConfiguration) {
123 $pages = $this->contentObject->data['pages'];
124 if (is_string($pages) && strlen($pages) > 0) {
125 $list = array();
126 if ($this->contentObject->data['recursive'] > 0) {
127 $explodedPages = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $pages);
128 foreach ($explodedPages as $pid) {
129 $list[] = trim($this->contentObject->getTreeList($pid, $this->contentObject->data['recursive']), ',');
130 }
131 }
132 if (count($list) > 0) {
133 $pages = $pages . ',' . implode(',', $list);
134 }
135 $frameworkConfiguration = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($frameworkConfiguration, array(
136 'persistence' => array(
137 'storagePid' => $pages
138 )
139 ));
140 }
141 return $frameworkConfiguration;
142 }
143
144 /**
145 * Overrides configuration settings from the plugin typoscript (plugin.tx_myext_pi1.)
146 *
147 * @param array $frameworkConfiguration the framework configuration
148 * @return array the framework configuration with overridden data from typoscript
149 */
150 protected function overrideConfigurationFromPlugin(array $frameworkConfiguration) {
151 $setup = $this->getTypoScriptSetup();
152 $pluginSignature = strtolower($frameworkConfiguration['extensionName'] . '_' . $frameworkConfiguration['pluginName']);
153 $pluginConfiguration = $setup['plugin.']['tx_' . $pluginSignature . '.'];
154 if (is_array($pluginConfiguration)) {
155 $pluginConfiguration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($pluginConfiguration);
156 $frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $pluginConfiguration, 'settings');
157 $frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $pluginConfiguration, 'persistence');
158 $frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $pluginConfiguration, 'view');
159 }
160 return $frameworkConfiguration;
161 }
162
163 /**
164 * Overrides configuration settings from flexForms.
165 * This merges the whole flexForm data, and overrides switchable controller actions.
166 *
167 * @param array $frameworkConfiguration the framework configuration
168 * @return array the framework configuration with overridden data from flexForm
169 */
170 protected function overrideConfigurationFromFlexForm(array $frameworkConfiguration) {
171 if (strlen($this->contentObject->data['pi_flexform']) > 0) {
172 $flexFormConfiguration = $this->flexFormService->convertFlexFormContentToArray($this->contentObject->data['pi_flexform']);
173 $frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $flexFormConfiguration, 'settings');
174 $frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $flexFormConfiguration, 'persistence');
175 $frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $flexFormConfiguration, 'view');
176 $frameworkConfiguration = $this->overrideSwitchableControllerActionsFromFlexForm($frameworkConfiguration, $flexFormConfiguration);
177 }
178 return $frameworkConfiguration;
179 }
180
181 /**
182 * Merge a configuration into the framework configuration.
183 *
184 * @param array $frameworkConfiguration the framework configuration to merge the data on
185 * @param array $configuration The configuration
186 * @param string $configurationPartName The name of the configuration part which should be merged.
187 * @return array the processed framework configuration
188 */
189 protected function mergeConfigurationIntoFrameworkConfiguration(array $frameworkConfiguration, array $configuration, $configurationPartName) {
190 if (is_array($frameworkConfiguration[$configurationPartName]) && is_array($configuration[$configurationPartName])) {
191 $frameworkConfiguration[$configurationPartName] = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($frameworkConfiguration[$configurationPartName], $configuration[$configurationPartName]);
192 }
193 return $frameworkConfiguration;
194 }
195
196 /**
197 * Overrides the switchable controller actions from the flexForm.
198 *
199 * @param array $frameworkConfiguration The original framework configuration
200 * @param array $flexFormConfiguration The full flexForm configuration
201 * @throws Exception\ParseErrorException
202 * @return array the modified framework configuration, if needed
203 */
204 protected function overrideSwitchableControllerActionsFromFlexForm(array $frameworkConfiguration, array $flexFormConfiguration) {
205 if (!isset($flexFormConfiguration['switchableControllerActions']) || is_array($flexFormConfiguration['switchableControllerActions'])) {
206 return $frameworkConfiguration;
207 }
208 // As "," is the flexForm field value delimiter, we need to use ";" as in-field delimiter. That's why we need to replace ; by , first.
209 // The expected format is: "Controller1->action2;Controller2->action3;Controller2->action1"
210 $switchableControllerActionPartsFromFlexForm = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', str_replace(';', ',', $flexFormConfiguration['switchableControllerActions']), TRUE);
211 $newSwitchableControllerActionsFromFlexForm = array();
212 foreach ($switchableControllerActionPartsFromFlexForm as $switchableControllerActionPartFromFlexForm) {
213 list($controller, $action) = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode('->', $switchableControllerActionPartFromFlexForm);
214 if (empty($controller) || empty($action)) {
215 throw new \TYPO3\CMS\Extbase\Configuration\Exception\ParseErrorException('Controller or action were empty when overriding switchableControllerActions from flexForm.', 1257146403);
216 }
217 $newSwitchableControllerActionsFromFlexForm[$controller][] = $action;
218 }
219 if (count($newSwitchableControllerActionsFromFlexForm) > 0) {
220 $this->overrideSwitchableControllerActions($frameworkConfiguration, $newSwitchableControllerActionsFromFlexForm);
221 }
222 return $frameworkConfiguration;
223 }
224
225 /**
226 * Returns a comma separated list of storagePid that are below a certain storage pid.
227 *
228 * @param string $storagePid Storage PID to start at; multiple PIDs possible as comma-separated list
229 * @param integer $recursionDepth Maximum number of levels to search, 0 to disable recursive lookup
230 * @return string storage PIDs
231 */
232 protected function getRecursiveStoragePids($storagePid, $recursionDepth = 0) {
233 if ($recursionDepth <= 0) {
234 return $storagePid;
235 }
236
237 $recursiveStoragePids = '';
238 $storagePids = \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode(',', $storagePid);
239 foreach ($storagePids as $startPid) {
240 $pids = $this->getContentObject()->getTreeList($startPid, $recursionDepth, 0);
241 if (strlen($pids) > 0) {
242 $recursiveStoragePids .= $pids . ',';
243 }
244 }
245 return rtrim($recursiveStoragePids, ',');
246 }
247 }
248
249 ?>