[TASK] Remove extList from LocalConfiguration
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Configuration / ConfigurationManager.php
1 <?php
2 namespace TYPO3\CMS\Core\Configuration;
3 use TYPO3\CMS\Core\Utility;
4
5 /***************************************************************
6 * Copyright notice
7 *
8 * (c) 2012 Helge Funk <helge.funk@e-net.info>
9 * All rights reserved
10 *
11 * This script is part of the TYPO3 project. The TYPO3 project is
12 * free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Handle loading and writing of global and local (instance specific)
29 * configuration.
30 *
31 * This class handles the access to the files
32 * - t3lib/stddb/DefaultConfiguration.php (default TYPO3_CONF_VARS)
33 * - typo3conf/LocalConfiguration.php (overrides of TYPO3_CONF_VARS)
34 * - typo3conf/AdditionalConfiguration.php (optional additional local code blocks)
35 * - typo3conf/localconf.php (legacy configuration file)
36 *
37 * @author Helge Funk <helge.funk@e-net.info>
38 */
39 class ConfigurationManager implements \TYPO3\CMS\Core\SingletonInterface {
40
41 /**
42 * Path to default TYPO3_CONF_VARS file, relative to PATH_site
43 */
44 const DEFAULT_CONFIGURATION_FILE = 't3lib/stddb/DefaultConfiguration.php';
45
46 /**
47 * Path to local overload TYPO3_CONF_VARS file, relative to PATH_site
48 */
49 const LOCAL_CONFIGURATION_FILE = 'typo3conf/LocalConfiguration.php';
50
51 /**
52 * Path to additional local file, relative to PATH_site
53 */
54 const ADDITIONAL_CONFIGURATION_FILE = 'typo3conf/AdditionalConfiguration.php';
55
56 /**
57 * Path to legacy localconf.php file, relative to PATH_site
58 */
59 const LOCALCONF_FILE = 'typo3conf/localconf.php';
60
61 /**
62 * Writing to these configuration pathes is always allowed,
63 * even if the requested sub path does not exist yet.
64 *
65 * @var array
66 */
67 protected $whiteListedLocalConfigurationPaths = array(
68 'EXT/extConf',
69 'EXTCONF',
70 'INSTALL/wizardDone',
71 'DB'
72 );
73
74 /**
75 * Return default configuration array t3lib/stddb/DefaultConfiguration.php
76 *
77 * @return array
78 */
79 public function getDefaultConfiguration() {
80 return require $this->getDefaultConfigurationFileResource();
81 }
82
83 /**
84 * Get the file resource of the default configuration file,
85 * currently the path and filename.
86 *
87 * @return string
88 * @access private
89 */
90 public function getDefaultConfigurationFileResource() {
91 return PATH_site . self::DEFAULT_CONFIGURATION_FILE;
92 }
93
94 /**
95 * Return local configuration array typo3conf/LocalConfiguration.php
96 *
97 * @return array Content array of local configuration file
98 */
99 public function getLocalConfiguration() {
100 return require $this->getLocalConfigurationFileResource();
101 }
102
103 /**
104 * Get the file resource of the local configuration file,
105 * currently the path and filename.
106 *
107 * @return string
108 * @access private
109 */
110 public function getLocalConfigurationFileResource() {
111 return PATH_site . self::LOCAL_CONFIGURATION_FILE;
112 }
113
114 /**
115 * Get the file resource of the aditional configuration file,
116 * currently the path and filename.
117 *
118 * @return string
119 * @access private
120 */
121 public function getAdditionalConfigurationFileResource() {
122 return PATH_site . self::ADDITIONAL_CONFIGURATION_FILE;
123 }
124
125 /**
126 * Override local configuration with new values.
127 *
128 * @param array $configurationToMerge Override configuration array
129 * @return void
130 */
131 public function updateLocalConfiguration(array $configurationToMerge) {
132 $newLocalConfiguration = Utility\GeneralUtility::array_merge_recursive_overrule($this->getLocalConfiguration(), $configurationToMerge);
133 $this->writeLocalConfiguration($newLocalConfiguration);
134 }
135
136 /**
137 * Get a value at given path from default configuration
138 *
139 * @param string $path Path to search for
140 * @return mixed Value at path
141 */
142 public function getDefaultConfigurationValueByPath($path) {
143 return Utility\ArrayUtility::getValueByPath($this->getDefaultConfiguration(), $path);
144 }
145
146 /**
147 * Get a value at given path from local configuration
148 *
149 * @param string $path Path to search for
150 * @return mixed Value at path
151 */
152 public function getLocalConfigurationValueByPath($path) {
153 return Utility\ArrayUtility::getValueByPath($this->getLocalConfiguration(), $path);
154 }
155
156 /**
157 * Get a value from configuration, this is default configuration
158 * merged with local configuration
159 *
160 * @param string $path Path to search for
161 * @return mixed
162 */
163 public function getConfigurationValueByPath($path) {
164 return Utility\ArrayUtility::getValueByPath(Utility\GeneralUtility::array_merge_recursive_overrule($this->getDefaultConfiguration(), $this->getLocalConfiguration()), $path);
165 }
166
167 /**
168 * Update a given path in local configuration to a new value.
169 *
170 * @param string $path Path to update
171 * @param mixed $value Value to set
172 * @return boolean TRUE on success
173 */
174 public function setLocalConfigurationValueByPath($path, $value) {
175 $result = FALSE;
176 if ($this->isValidLocalConfigurationPath($path)) {
177 $localConfiguration = $this->getLocalConfiguration();
178 $localConfiguration = Utility\ArrayUtility::setValueByPath($localConfiguration, $path, $value);
179 $result = $this->writeLocalConfiguration($localConfiguration);
180 }
181 return $result;
182 }
183
184 /**
185 * Update / set a list of path and value pairs in local configuration file
186 *
187 * @param array $pairs Key is path, value is value to set
188 * @return boolean TRUE on success
189 */
190 public function setLocalConfigurationValuesByPathValuePairs(array $pairs) {
191 $localConfiguration = $this->getLocalConfiguration();
192 foreach ($pairs as $path => $value) {
193 if ($this->isValidLocalConfigurationPath($path)) {
194 $localConfiguration = Utility\ArrayUtility::setValueByPath($localConfiguration, $path, $value);
195 }
196 }
197 return $this->writeLocalConfiguration($localConfiguration);
198 }
199
200 /**
201 * Checks if the configuration can be written
202 *
203 * @return boolean
204 * @access private
205 */
206 public function canWriteConfiguration() {
207 $result = TRUE;
208 if (!@is_writable(PATH_typo3conf)) {
209 $result = FALSE;
210 }
211 if (!@is_writable(($this->getLocalConfigurationFileResource())) && !@is_writable((PATH_site . self::LOCALCONF_FILE))) {
212 $result = FALSE;
213 }
214 return $result;
215 }
216
217 /**
218 * Reads the configuration array and exports it to the global variable
219 *
220 * @access private
221 * @return void
222 */
223 public function exportConfiguration() {
224 if (@is_file(($this->getLocalConfigurationFileResource()))) {
225 $localConfiguration = $this->getLocalConfiguration();
226 if (is_array($localConfiguration)) {
227 $GLOBALS['TYPO3_CONF_VARS'] = Utility\GeneralUtility::array_merge_recursive_overrule($this->getDefaultConfiguration(), $localConfiguration);
228 } else {
229 throw new \UnexpectedValueException('LocalConfiguration invalid.', 1349272276);
230 }
231 if (@is_file((PATH_site . self::ADDITIONAL_CONFIGURATION_FILE))) {
232 require PATH_site . self::ADDITIONAL_CONFIGURATION_FILE;
233 }
234 // @deprecated since 6.0: Simulate old 'extList' as comma separated list of 'extListArray'
235 $GLOBALS['TYPO3_CONF_VARS']['EXT']['extList'] = implode(',', $GLOBALS['TYPO3_CONF_VARS']['EXT']['extListArray']);
236 } elseif (@is_file((PATH_site . self::LOCALCONF_FILE))) {
237 $GLOBALS['TYPO3_CONF_VARS'] = $this->getDefaultConfiguration();
238 // Legacy localconf.php handling
239 // @deprecated: Can be removed if old localconf.php is not supported anymore
240 global $TYPO3_CONF_VARS, $typo_db, $typo_db_username, $typo_db_password, $typo_db_host, $typo_db_extTableDef_script;
241 require PATH_site . self::LOCALCONF_FILE;
242 // If the localconf.php was not upgraded to LocalConfiguration.php, the default extListArray
243 // from t3lib/stddb/DefaultConfiguration.php is still set. In this case we just unset
244 // this key here, so t3lib_extMgm::getLoadedExtensionListArray() falls back to use extList string
245 // @deprecated: This case can be removed later if localconf.php is not supported anymore
246 unset($TYPO3_CONF_VARS['EXT']['extListArray']);
247 // Write the old globals into the new place in the configuration array
248 $GLOBALS['TYPO3_CONF_VARS']['DB'] = array();
249 $GLOBALS['TYPO3_CONF_VARS']['DB']['database'] = $typo_db;
250 $GLOBALS['TYPO3_CONF_VARS']['DB']['username'] = $typo_db_username;
251 $GLOBALS['TYPO3_CONF_VARS']['DB']['password'] = $typo_db_password;
252 $GLOBALS['TYPO3_CONF_VARS']['DB']['host'] = $typo_db_host;
253 $GLOBALS['TYPO3_CONF_VARS']['DB']['extTablesDefinitionScript'] = $typo_db_extTableDef_script;
254 unset($GLOBALS['typo_db']);
255 unset($GLOBALS['typo_db_username']);
256 unset($GLOBALS['typo_db_password']);
257 unset($GLOBALS['typo_db_host']);
258 unset($GLOBALS['typo_db_extTableDef_script']);
259 } else {
260 throw new \RuntimeException('Neither ' . self::LOCAL_CONFIGURATION_FILE . ' (recommended) nor ' . self::LOCALCONF_FILE . ' (obsolete) could be found!', 1349272337);
261 }
262 }
263
264 /**
265 * Write local configuration array to typo3conf/LocalConfiguration.php
266 *
267 * @param array $configuration The local configuration to be written
268 * @throws \RuntimeException
269 * @return boolean TRUE on success
270 * @access private
271 */
272 public function writeLocalConfiguration(array $configuration) {
273 $localConfigurationFile = $this->getLocalConfigurationFileResource();
274 if (!@is_file($localConfigurationFile) || !@is_writable($localConfigurationFile)) {
275 throw new \RuntimeException($localConfigurationFile . ' does not exist or is not writable.', 1346323822);
276 }
277 $configuration = Utility\ArrayUtility::sortByKeyRecursive($configuration);
278 $result = Utility\GeneralUtility::writeFile(
279 $localConfigurationFile,
280 '<?php' . LF . 'return ' . Utility\ArrayUtility::arrayExport($configuration) . ';' . LF . '?>'
281 );
282 return $result === FALSE ? FALSE : TRUE;
283 }
284
285 /**
286 * Write additional configuration array to typo3conf/AdditionalConfiguration.php
287 *
288 * @param array $additionalConfigurationLines The configuration lines to be written
289 * @throws \RuntimeException
290 * @return boolean TRUE on success
291 * @access private
292 */
293 public function writeAdditionalConfiguration(array $additionalConfigurationLines) {
294 $result = Utility\GeneralUtility::writeFile(PATH_site . self::ADDITIONAL_CONFIGURATION_FILE, '<?php' . LF . implode(LF, $additionalConfigurationLines) . LF . '?>');
295 return $result === FALSE ? FALSE : TRUE;
296 }
297
298 /**
299 * Check if access / write to given path in local configuration is allowed.
300 *
301 * @param string $path Path to search for
302 * @return boolean TRUE if access is allowed
303 */
304 protected function isValidLocalConfigurationPath($path) {
305 // Early return for white listed paths
306 foreach ($this->whiteListedLocalConfigurationPaths as $whiteListedPath) {
307 if (Utility\GeneralUtility::isFirstPartOfStr($path, $whiteListedPath)) {
308 return TRUE;
309 }
310 }
311 return Utility\ArrayUtility::isValidPath($this->getDefaultConfiguration(), $path);
312 }
313
314 }
315
316
317 ?>