fa0af872c7ce97babd7a99004542b72c5e3d2bda
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Service / SilentConfigurationUpgradeService.php
1 <?php
2 namespace TYPO3\CMS\Install\Service;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2013 Christian Kuhn <lolli@schwarzbu.ch>
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 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26
27 use TYPO3\CMS\Core\Utility\GeneralUtility;
28
29 /**
30 * Execute "silent" LocalConfiguration upgrades if needed.
31 *
32 * Some LocalConfiguration settings are obsolete or changed over time.
33 * This class handles upgrades of these settings. It is called by
34 * the step controller at an early point.
35 *
36 * Every change is encapsulated in one method an must throw a RedirectException
37 * if new data is written to LocalConfiguration. This is catched by above
38 * step controller to initiate a redirect and start again with adapted configuration.
39 */
40 class SilentConfigurationUpgradeService {
41
42 /**
43 * @var \TYPO3\CMS\Extbase\Object\ObjectManager
44 * @inject
45 */
46 protected $objectManager = NULL;
47
48 /**
49 * @var \TYPO3\CMS\Core\Configuration\ConfigurationManager
50 * @inject
51 */
52 protected $configurationManager = NULL;
53
54 /**
55 * @var array List of obsolete configuration options in LocalConfiguration to be removed
56 */
57 protected $obsoleteLocalConfigurationSettings = array(
58 // #34092
59 'BE/forceCharset',
60 // #26519
61 'BE/loginLabels',
62 // #44506
63 'BE/loginNews',
64 // #52013
65 'BE/TSconfigConditions',
66 // #30613
67 'BE/useOnContextMenuHandler',
68 // #48179
69 'EXT/em_mirrorListURL',
70 'EXT/em_wsdlURL',
71 // #43094
72 'EXT/extList',
73 // #35877
74 'EXT/extList_FE',
75 // #41813
76 'EXT/noEdit',
77 // #26090
78 'FE/defaultTypoScript_editorcfg',
79 'FE/defaultTypoScript_editorcfg.',
80 // #25099
81 'FE/simulateStaticDocuments',
82 // #52011
83 'GFX/im_combine_filename',
84 // #52088
85 'GFX/im_imvMaskState',
86 // #22687
87 'GFX/gdlib_2',
88 // #52012
89 'GFX/im_mask_temp_ext_noloss',
90 // #52088
91 'GFX/im_negate_mask',
92 // #52010
93 'GFX/im_no_effects',
94 // #18431
95 'GFX/noIconProc',
96 // #17606
97 'GFX/TTFLocaleConv',
98 // #39164
99 'SYS/additionalAllowedClassPrefixes',
100 // #27689
101 'SYS/caching/cacheBackends',
102 'SYS/caching/cacheFrontends',
103 // #38414
104 'SYS/extCache',
105 // #35923
106 'SYS/multiplyDBfieldSize',
107 // #46993
108 'SYS/T3instID',
109 );
110
111 /**
112 * Executed configuration upgrades. Single upgrade methods must throw a
113 * RedirectException if something was written to LocalConfiguration.
114 *
115 * @return void
116 */
117 public function execute() {
118 $this->generateEncryptionKeyIfNeeded();
119 $this->configureBackendLoginSecurity();
120 $this->configureSaltedPasswords();
121 $this->setProxyAuthScheme();
122 $this->disableImageMagickAndGdlibIfImageProcessingIsDisabled();
123 $this->disableImageMagickDetailSettingsIfImageMagickIsDisabled();
124 $this->setImageMagickDetailSettings();
125 $this->removeObsoleteLocalConfigurationSettings();
126 }
127
128 /**
129 * Some settings in LocalConfiguration vanished in DefaultConfiguration
130 * and have no impact on the core anymore.
131 * To keep the configuration clean, those old settings are just silently
132 * removed from LocalConfiguration if set.
133 *
134 * @return void
135 */
136 protected function removeObsoleteLocalConfigurationSettings() {
137 $removed = $this->configurationManager->removeLocalConfigurationKeysByPath($this->obsoleteLocalConfigurationSettings);
138 // If something was changed: Trigger a reload to have new values in next request
139 if ($removed) {
140 $this->throwRedirectException();
141 }
142 }
143
144 /**
145 * Backend login security is set to rsa if rsaauth
146 * is installed (but not used) otherwise the default value "normal" has to be used.
147 *
148 * @return void
149 */
150 protected function configureBackendLoginSecurity() {
151 if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('rsaauth')
152 && $GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel'] !== 'rsa')
153 {
154 $this->configurationManager->setLocalConfigurationValueByPath('BE/loginSecurityLevel', 'rsa');
155 $this->throwRedirectException();
156 } elseif (!\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('rsaauth')
157 && $GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel'] !== 'normal'
158 ) {
159 $configurationManager = $this->objectManager->get('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager');
160 $configurationManager->setLocalConfigurationValueByPath('BE/loginSecurityLevel', 'normal');
161 $this->throwRedirectException();
162 }
163 }
164
165 /**
166 * Check the settings for salted passwords extension to
167 * load it as a required extension.
168 *
169 * @return void
170 */
171 protected function configureSaltedPasswords() {
172 $defaultConfiguration = $this->configurationManager->getDefaultConfiguration();
173 $defaultExtensionConfiguration = unserialize($defaultConfiguration['EXT']['extConf']['saltedpasswords']);
174 $extensionConfiguration = @unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['saltedpasswords']);
175 if (is_array($extensionConfiguration) && !empty($extensionConfiguration)) {
176 if (isset($extensionConfiguration['BE.']['enabled'])) {
177 if ($extensionConfiguration['BE.']['enabled']) {
178 unset($extensionConfiguration['BE.']['enabled']);
179 } else {
180 $extensionConfiguration['BE.'] = $defaultExtensionConfiguration['BE.'];
181 }
182 $this->configurationManager->setLocalConfigurationValueByPath(
183 'EXT/extConf/saltedpasswords',
184 serialize($extensionConfiguration)
185 );
186 $this->throwRedirectException();
187 }
188 } else {
189 $this->configurationManager->setLocalConfigurationValueByPath(
190 'EXT/extConf/saltedpasswords',
191 serialize($defaultExtensionConfiguration)
192 );
193 $this->throwRedirectException();
194 }
195 }
196
197 /**
198 * The encryption key is crucial for securing form tokens
199 * and the whole TYPO3 link rendering later on. A random key is set here in
200 * LocalConfiguration if it does not exist yet. This might possible happen
201 * during upgrading and will happen during first install.
202 *
203 * @return void
204 */
205 protected function generateEncryptionKeyIfNeeded() {
206 if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
207 $randomKey = GeneralUtility::getRandomHexString(96);
208 $this->configurationManager->setLocalConfigurationValueByPath('SYS/encryptionKey', $randomKey);
209 $this->throwRedirectException();
210 }
211 }
212
213 /**
214 * $GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_auth_scheme'] must be either
215 * 'digest' or 'basic'. 'basic' is default in DefaultConfiguration, so the
216 * setting can be removed from LocalConfiguration if it is not set to 'digest'.
217 *
218 * @return void
219 */
220 protected function setProxyAuthScheme() {
221 // Get current value from LocalConfiguration
222 try {
223 $currentValueInLocalConfiguration = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_auth_scheme');
224 } catch (\RuntimeException $e) {
225 // If an exception is thrown, the value is not set in LocalConfiguration, so we don't need to do anything
226 return;
227 }
228 if ($currentValueInLocalConfiguration !== 'digest') {
229 $this->configurationManager->removeLocalConfigurationKeysByPath(array('HTTP/proxy_auth_scheme'));
230 $this->throwRedirectException();
231 }
232 }
233
234 /**
235 * GFX/im and GFX/gdlib must be set to 0 if image_processing is disabled.
236 *
237 * "Configuration presets" in install tool is not type safe, so value
238 * comparisons here are not type safe too, to not trigger changes to
239 * LocalConfiguration again.
240 *
241 * @return void
242 */
243 protected function disableImageMagickAndGdlibIfImageProcessingIsDisabled() {
244 $changedValues = array();
245 // If image processing is fully disabled, im and gdlib sub settings must be 0
246 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['image_processing']) {
247 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] != 0) {
248 $changedValues['GFX/im'] = 0;
249 }
250 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'] != 0) {
251 $changedValues['GFX/gdlib'] = 0;
252 }
253 }
254 if (count($changedValues) > 0) {
255 $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($changedValues);
256 $this->throwRedirectException();
257 }
258 }
259
260 /**
261 * Detail configuration of Image Magick settings must be cleared
262 * if Image Magick handling is disabled.
263 *
264 * "Configuration presets" in install tool is not type safe, so value
265 * comparisons here are not type safe too, to not trigger changes to
266 * LocalConfiguration again.
267 *
268 * @return void
269 */
270 protected function disableImageMagickDetailSettingsIfImageMagickIsDisabled() {
271 $changedValues = array();
272 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) {
273 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path'] != '') {
274 $changedValues['GFX/im_path'] = '';
275 }
276 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'] != '') {
277 $changedValues['GFX/im_path_lzw'] = '';
278 }
279 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] !== 'gif,jpg,jpeg,png') {
280 $changedValues['GFX/imagefile_ext'] = 'gif,jpg,jpeg,png';
281 }
282 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['thumbnails'] != 0) {
283 $changedValues['GFX/thumbnails'] = 0;
284 }
285 }
286 if (count($changedValues) > 0) {
287 $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($changedValues);
288 $this->throwRedirectException();
289 }
290 }
291
292 /**
293 * Detail configuration of Image Magick and Graphics Magick settings
294 * depending on main values.
295 *
296 * "Configuration presets" in install tool is not type safe, so value
297 * comparisons here are not type safe too, to not trigger changes to
298 * LocalConfiguration again.
299 *
300 * @return void
301 */
302 protected function setImageMagickDetailSettings() {
303 $changedValues = array();
304 if (isset($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'])
305 && strlen($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']) > 0
306 ) {
307 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_mask_temp_ext_gif'] != 1) {
308 $changedValues['GFX/im_mask_temp_ext_gif'] = 1;
309 }
310 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] === 'gm') {
311 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_v5effects'] != -1) {
312 $changedValues['GFX/im_v5effects'] = -1;
313 }
314 }
315 }
316 if (count($changedValues) > 0) {
317 $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($changedValues);
318 $this->throwRedirectException();
319 }
320 }
321
322 /**
323 * Throw exception after configuration change to trigger a redirect.
324 *
325 * @throws \TYPO3\CMS\Install\Controller\Exception\RedirectException
326 */
327 protected function throwRedirectException() {
328 throw new \TYPO3\CMS\Install\Controller\Exception\RedirectException(
329 'Configuration updated, reload needed',
330 1379024938
331 );
332 }
333 }