f5bb3dd42f5e59856ef4a11157693c44b64a099e
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Service / SilentConfigurationUpgradeService.php
1 <?php
2 namespace TYPO3\CMS\Install\Service;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Configuration\ConfigurationManager;
18 use TYPO3\CMS\Core\Crypto\Random;
19 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21 use TYPO3\CMS\Install\Controller\Exception\RedirectException;
22
23 /**
24 * Execute "silent" LocalConfiguration upgrades if needed.
25 *
26 * Some LocalConfiguration settings are obsolete or changed over time.
27 * This class handles upgrades of these settings. It is called by
28 * the step controller at an early point.
29 *
30 * Every change is encapsulated in one method an must throw a RedirectException
31 * if new data is written to LocalConfiguration. This is caught by above
32 * step controller to initiate a redirect and start again with adapted configuration.
33 */
34 class SilentConfigurationUpgradeService
35 {
36 /**
37 * @var \TYPO3\CMS\Core\Configuration\ConfigurationManager
38 */
39 protected $configurationManager;
40
41 /**
42 * List of obsolete configuration options in LocalConfiguration to be removed
43 * Example:
44 * // #forge-ticket
45 * 'BE/somesetting',
46 *
47 * @var array
48 */
49 protected $obsoleteLocalConfigurationSettings = array(
50 // #72367
51 'INSTALL/wizardDone/TYPO3\\CMS\\Install\\Updates\\AccessRightParametersUpdate',
52 'INSTALL/wizardDone/TYPO3\\CMS\\Install\\Updates\\BackendUserStartModuleUpdate',
53 'INSTALL/wizardDone/TYPO3\\CMS\\Install\\Updates\\Compatibility6ExtractionUpdate',
54 'INSTALL/wizardDone/TYPO3\\CMS\\Install\\Updates\\ContentTypesToTextMediaUpdate',
55 'INSTALL/wizardDone/TYPO3\\CMS\\Install\\Updates\\FileListIsStartModuleUpdate',
56 'INSTALL/wizardDone/TYPO3\\CMS\\Install\\Updates\\FilesReplacePermissionUpdate',
57 'INSTALL/wizardDone/TYPO3\\CMS\\Install\\Updates\\LanguageIsoCodeUpdate',
58 'INSTALL/wizardDone/TYPO3\\CMS\\Install\\Updates\\MediaceExtractionUpdate',
59 'INSTALL/wizardDone/TYPO3\\CMS\\Install\\Updates\\MigrateMediaToAssetsForTextMediaCe',
60 'INSTALL/wizardDone/TYPO3\\CMS\\Install\\Updates\\MigrateShortcutUrlsAgainUpdate',
61 'INSTALL/wizardDone/TYPO3\\CMS\\Install\\Updates\\OpenidExtractionUpdate',
62 'INSTALL/wizardDone/TYPO3\\CMS\\Install\\Updates\\PageShortcutParentUpdate',
63 'INSTALL/wizardDone/TYPO3\\CMS\\Install\\Updates\\ProcessedFileChecksumUpdate',
64 'INSTALL/wizardDone/TYPO3\\CMS\\Install\\Updates\\TableFlexFormToTtContentFieldsUpdate',
65 'INSTALL/wizardDone/TYPO3\\CMS\\Install\\Updates\\WorkspacesNotificationSettingsUpdate',
66 'INSTALL/wizardDone/TYPO3\\CMS\\Rtehtmlarea\\Hook\\Install\\DeprecatedRteProperties',
67 'INSTALL/wizardDone/TYPO3\\CMS\\Rtehtmlarea\\Hook\\Install\\RteAcronymButtonRenamedToAbbreviation',
68 // #72400
69 'BE/spriteIconGenerator_handler',
70 // #72417
71 'SYS/lockingMode',
72 // #72473
73 'FE/secureFormmail',
74 'FE/strictFormmail',
75 'FE/formmailMaxAttachmentSize',
76 // #72337
77 'SYS/t3lib_cs_utils',
78 'SYS/t3lib_cs_convMethod',
79 // #72604
80 'SYS/maxFileNameLength',
81 // #72602
82 'BE/unzip_path',
83 // #72615
84 'BE/notificationPrefix',
85 // #72616
86 'BE/XCLASS',
87 'FE/XCLASS',
88 // #43085
89 'GFX/image_processing',
90 // #70056
91 'SYS/curlUse',
92 'SYS/curlProxyNTLM',
93 'SYS/curlProxyServer',
94 'SYS/curlProxyTunnel',
95 'SYS/curlProxyUserPass',
96 'SYS/curlTimeout',
97 );
98
99 public function __construct(ConfigurationManager $configurationManager = null)
100 {
101 $this->configurationManager = $configurationManager ?: GeneralUtility::makeInstance(ConfigurationManager::class);
102 }
103
104 /**
105 * Executed configuration upgrades. Single upgrade methods must throw a
106 * RedirectException if something was written to LocalConfiguration.
107 *
108 * @return void
109 */
110 public function execute()
111 {
112 $this->generateEncryptionKeyIfNeeded();
113 $this->configureBackendLoginSecurity();
114 $this->configureSaltedPasswords();
115 $this->migrateImageProcessorSetting();
116 $this->transferHttpSettings();
117 $this->disableImageMagickDetailSettingsIfImageMagickIsDisabled();
118 $this->setImageMagickDetailSettings();
119 $this->removeObsoleteLocalConfigurationSettings();
120 $this->migrateThumbnailsPngSetting();
121 }
122
123 /**
124 * Some settings in LocalConfiguration vanished in DefaultConfiguration
125 * and have no impact on the core anymore.
126 * To keep the configuration clean, those old settings are just silently
127 * removed from LocalConfiguration if set.
128 *
129 * @return void
130 */
131 protected function removeObsoleteLocalConfigurationSettings()
132 {
133 $removed = $this->configurationManager->removeLocalConfigurationKeysByPath($this->obsoleteLocalConfigurationSettings);
134
135 // If something was changed: Trigger a reload to have new values in next request
136 if ($removed) {
137 $this->throwRedirectException();
138 }
139 }
140
141 /**
142 * Backend login security is set to rsa if rsaauth
143 * is installed (but not used) otherwise the default value "normal" has to be used.
144 * This forces either 'normal' or 'rsa' to be set in LocalConfiguration.
145 *
146 * @return void
147 */
148 protected function configureBackendLoginSecurity()
149 {
150 $rsaauthLoaded = ExtensionManagementUtility::isLoaded('rsaauth');
151 try {
152 $currentLoginSecurityLevelValue = $this->configurationManager->getLocalConfigurationValueByPath('BE/loginSecurityLevel');
153 if ($rsaauthLoaded && $currentLoginSecurityLevelValue !== 'rsa') {
154 $this->configurationManager->setLocalConfigurationValueByPath('BE/loginSecurityLevel', 'rsa');
155 $this->throwRedirectException();
156 } elseif (!$rsaauthLoaded && $currentLoginSecurityLevelValue !== 'normal') {
157 $this->configurationManager->setLocalConfigurationValueByPath('BE/loginSecurityLevel', 'normal');
158 $this->throwRedirectException();
159 }
160 } catch (\RuntimeException $e) {
161 // If an exception is thrown, the value is not set in LocalConfiguration
162 $this->configurationManager->setLocalConfigurationValueByPath('BE/loginSecurityLevel', $rsaauthLoaded ? 'rsa' : 'normal');
163 $this->throwRedirectException();
164 }
165 }
166
167 /**
168 * Check the settings for salted passwords extension to load it as a required extension.
169 * Unset obsolete configuration options if given.
170 *
171 * @return void
172 */
173 protected function configureSaltedPasswords()
174 {
175 $defaultConfiguration = $this->configurationManager->getDefaultConfiguration();
176 $defaultExtensionConfiguration = unserialize($defaultConfiguration['EXT']['extConf']['saltedpasswords']);
177 try {
178 $extensionConfiguration = @unserialize($this->configurationManager->getLocalConfigurationValueByPath('EXT/extConf/saltedpasswords'));
179 } catch (\RuntimeException $e) {
180 $extensionConfiguration = array();
181 }
182 if (is_array($extensionConfiguration) && !empty($extensionConfiguration)) {
183 if (isset($extensionConfiguration['BE.']['enabled'])) {
184 if ($extensionConfiguration['BE.']['enabled']) {
185 unset($extensionConfiguration['BE.']['enabled']);
186 } else {
187 $extensionConfiguration['BE.'] = $defaultExtensionConfiguration['BE.'];
188 }
189 $this->configurationManager->setLocalConfigurationValueByPath(
190 'EXT/extConf/saltedpasswords',
191 serialize($extensionConfiguration)
192 );
193 $this->throwRedirectException();
194 }
195 } else {
196 $this->configurationManager->setLocalConfigurationValueByPath(
197 'EXT/extConf/saltedpasswords',
198 serialize($defaultExtensionConfiguration)
199 );
200 $this->throwRedirectException();
201 }
202 }
203
204 /**
205 * The encryption key is crucial for securing form tokens
206 * and the whole TYPO3 link rendering later on. A random key is set here in
207 * LocalConfiguration if it does not exist yet. This might possible happen
208 * during upgrading and will happen during first install.
209 *
210 * @return void
211 */
212 protected function generateEncryptionKeyIfNeeded()
213 {
214 try {
215 $currentValue = $this->configurationManager->getLocalConfigurationValueByPath('SYS/encryptionKey');
216 } catch (\RuntimeException $e) {
217 // If an exception is thrown, the value is not set in LocalConfiguration
218 $currentValue = '';
219 }
220
221 if (empty($currentValue)) {
222 $randomKey = GeneralUtility::makeInstance(Random::class)->generateRandomHexString(96);
223 $this->configurationManager->setLocalConfigurationValueByPath('SYS/encryptionKey', $randomKey);
224 $this->throwRedirectException();
225 }
226 }
227
228 /**
229 * Parse old curl and HTTP options and set new HTTP options, related to Guzzle
230 *
231 * @return void
232 */
233 protected function transferHttpSettings()
234 {
235 $changed = false;
236 $newParameters = [];
237 $obsoleteParameters = [];
238
239 // Remove / migrate options to new options
240 try {
241 // Check if the adapter option is set, if so, set it to the parameters that are obsolete
242 $this->configurationManager->getLocalConfigurationValueByPath('HTTP/adapter');
243 $obsoleteParameters[] = 'HTTP/adapter';
244 } catch (\RuntimeException $e) {
245 }
246 try {
247 $newParameters['HTTP/version'] = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/protocol_version');
248 $obsoleteParameters[] = 'HTTP/protocol_version';
249 } catch (\RuntimeException $e) {
250 }
251 try {
252 $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_verify_host');
253 $obsoleteParameters[] = 'HTTP/ssl_verify_host';
254 } catch (\RuntimeException $e) {
255 }
256 try {
257 $legacyUserAgent = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/userAgent');
258 $newParameters['HTTP/headers/User-Agent'] = $legacyUserAgent;
259 $obsoleteParameters[] = 'HTTP/userAgent';
260 } catch (\RuntimeException $e) {
261 }
262
263 // Redirects
264 try {
265 $legacyFollowRedirects = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/follow_redirects');
266 $obsoleteParameters[] = 'HTTP/follow_redirects';
267 } catch (\RuntimeException $e) {
268 $legacyFollowRedirects = '';
269 }
270 try {
271 $legacyMaximumRedirects = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/max_redirects');
272 $obsoleteParameters[] = 'HTTP/max_redirects';
273 } catch (\RuntimeException $e) {
274 $legacyMaximumRedirects = '';
275 }
276 try {
277 $legacyStrictRedirects = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/strict_redirects');
278 $obsoleteParameters[] = 'HTTP/strict_redirects';
279 } catch (\RuntimeException $e) {
280 $legacyStrictRedirects = '';
281 }
282
283 // Check if redirects have been disabled
284 if ($legacyFollowRedirects !== '' && (bool)$legacyFollowRedirects === false) {
285 $newParameters['HTTP/allow_redirects'] = false;
286 } elseif ($legacyMaximumRedirects !== '' || $legacyStrictRedirects !== '') {
287 $newParameters['HTTP/allow_redirects'] = [];
288 if ($legacyMaximumRedirects !== '' && (int)$legacyMaximumRedirects !== 5) {
289 $newParameters['HTTP/allow_redirects']['max'] = (int)$legacyMaximumRedirects;
290 }
291 if ($legacyStrictRedirects !== '' && (bool)$legacyStrictRedirects === true) {
292 $newParameters['HTTP/allow_redirects']['strict'] = true;
293 }
294 // defaults are used, no need to set the option in LocalConfiguration.php
295 if (empty($newParameters['HTTP/allow_redirects'])) {
296 unset($newParameters['HTTP/allow_redirects']);
297 }
298 }
299
300 // Migrate Proxy settings
301 try {
302 // Currently without protocol or port
303 $legacyProxyHost = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_host');
304 $obsoleteParameters[] = 'HTTP/proxy_host';
305 } catch (\RuntimeException $e) {
306 $legacyProxyHost = '';
307 }
308 try {
309 $legacyProxyPort = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_port');
310 $obsoleteParameters[] = 'HTTP/proxy_port';
311 } catch (\RuntimeException $e) {
312 $legacyProxyPort = '';
313 }
314 try {
315 $legacyProxyUser = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_user');
316 $obsoleteParameters[] = 'HTTP/proxy_user';
317 } catch (\RuntimeException $e) {
318 $legacyProxyUser = '';
319 }
320 try {
321 $legacyProxyPassword = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_password');
322 $obsoleteParameters[] = 'HTTP/proxy_password';
323 } catch (\RuntimeException $e) {
324 $legacyProxyPassword = '';
325 }
326 // Auth Scheme: Basic, digest etc.
327 try {
328 $legacyProxyAuthScheme = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_auth_scheme');
329 $obsoleteParameters[] = 'HTTP/proxy_auth_scheme';
330 } catch (\RuntimeException $e) {
331 $legacyProxyAuthScheme = '';
332 }
333
334 if ($legacyProxyHost !== '') {
335 $proxy = 'http://';
336 if ($legacyProxyAuthScheme !== '' && $legacyProxyUser !== '' && $legacyProxyPassword !== '') {
337 $proxy .= $legacyProxyUser . ':' . $legacyProxyPassword . '@';
338 }
339 $proxy .= $legacyProxyHost;
340 if ($legacyProxyPort !== '') {
341 $proxy .= ':' . $legacyProxyPort;
342 }
343 $newParameters['HTTP/proxy'] = $proxy;
344 }
345
346 // Verify peers
347 // see http://docs.guzzlephp.org/en/latest/request-options.html#verify
348 try {
349 $legacySslVerifyPeer = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_verify_peer');
350 $obsoleteParameters[] = 'HTTP/ssl_verify_peer';
351 } catch (\RuntimeException $e) {
352 $legacySslVerifyPeer = '';
353 }
354
355 // Directory holding multiple Certificate Authority files
356 try {
357 $legacySslCaPath = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_capath');
358 $obsoleteParameters[] = 'HTTP/ssl_capath';
359 } catch (\RuntimeException $e) {
360 $legacySslCaPath = '';
361 }
362 // Certificate Authority file to verify the peer with (use when ssl_verify_peer is TRUE)
363 try {
364 $legacySslCaFile = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_cafile');
365 $obsoleteParameters[] = 'HTTP/ssl_cafile';
366 } catch (\RuntimeException $e) {
367 $legacySslCaFile = '';
368 }
369 if ($legacySslVerifyPeer !== '') {
370 if ($legacySslCaFile !== '' && $legacySslCaPath !== '') {
371 $newParameters['HTTP/verify'] = $legacySslCaPath . $legacySslCaFile;
372 } elseif ((bool)$legacySslVerifyPeer === false) {
373 $newParameters['HTTP/verify'] = false;
374 }
375 }
376
377 // SSL Key + Passphrase
378 // Name of a file containing local certificate
379 try {
380 $legacySslLocalCert = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_local_cert');
381 $obsoleteParameters[] = 'HTTP/ssl_local_cert';
382 } catch (\RuntimeException $e) {
383 $legacySslLocalCert = '';
384 }
385
386 // Passphrase with which local certificate was encoded
387 try {
388 $legacySslPassphrase = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_passphrase');
389 $obsoleteParameters[] = 'HTTP/ssl_passphrase';
390 } catch (\RuntimeException $e) {
391 $legacySslPassphrase = '';
392 }
393
394 if ($legacySslLocalCert !== '') {
395 if ($legacySslPassphrase !== '') {
396 $newParameters['HTTP/ssl_key'] = [
397 $legacySslLocalCert,
398 $legacySslPassphrase
399 ];
400 } else {
401 $newParameters['HTTP/ssl_key'] = $legacySslLocalCert;
402 }
403 }
404
405 // Update the LocalConfiguration file if obsolete parameters or new parameters are set
406 if (!empty($obsoleteParameters)) {
407 $this->configurationManager->removeLocalConfigurationKeysByPath($obsoleteParameters);
408 $changed = true;
409 }
410 if (!empty($newParameters)) {
411 $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($newParameters);
412 $changed = true;
413 }
414 if ($changed) {
415 $this->throwRedirectException();
416 }
417 }
418
419 /**
420 * Detail configuration of Image Magick settings must be cleared
421 * if Image Magick handling is disabled.
422 *
423 * "Configuration presets" in install tool is not type safe, so value
424 * comparisons here are not type safe too, to not trigger changes to
425 * LocalConfiguration again.
426 *
427 * @return void
428 */
429 protected function disableImageMagickDetailSettingsIfImageMagickIsDisabled()
430 {
431 $changedValues = array();
432 try {
433 $currentImValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_enabled');
434 } catch (\RuntimeException $e) {
435 $currentImValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_enabled');
436 }
437
438 try {
439 $currentImPathValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_path');
440 } catch (\RuntimeException $e) {
441 $currentImPathValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_path');
442 }
443
444 try {
445 $currentImPathLzwValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_path_lzw');
446 } catch (\RuntimeException $e) {
447 $currentImPathLzwValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_path_lzw');
448 }
449
450 try {
451 $currentImageFileExtValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/imagefile_ext');
452 } catch (\RuntimeException $e) {
453 $currentImageFileExtValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/imagefile_ext');
454 }
455
456 try {
457 $currentThumbnailsValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/thumbnails');
458 } catch (\RuntimeException $e) {
459 $currentThumbnailsValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/thumbnails');
460 }
461
462 if (!$currentImValue) {
463 if ($currentImPathValue != '') {
464 $changedValues['GFX/processor_path'] = '';
465 }
466 if ($currentImPathLzwValue != '') {
467 $changedValues['GFX/processor_path_lzw'] = '';
468 }
469 if ($currentImageFileExtValue !== 'gif,jpg,jpeg,png') {
470 $changedValues['GFX/imagefile_ext'] = 'gif,jpg,jpeg,png';
471 }
472 if ($currentThumbnailsValue != 0) {
473 $changedValues['GFX/thumbnails'] = 0;
474 }
475 }
476 if (!empty($changedValues)) {
477 $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($changedValues);
478 $this->throwRedirectException();
479 }
480 }
481
482 /**
483 * Detail configuration of Image Magick and Graphics Magick settings
484 * depending on main values.
485 *
486 * "Configuration presets" in install tool is not type safe, so value
487 * comparisons here are not type safe too, to not trigger changes to
488 * LocalConfiguration again.
489 *
490 * @return void
491 */
492 protected function setImageMagickDetailSettings()
493 {
494 $changedValues = array();
495 try {
496 $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor');
497 } catch (\RuntimeException $e) {
498 $currentProcessorValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor');
499 }
500
501 try {
502 $currentProcessorMaskValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_allowTemporaryMasksAsPng');
503 } catch (\RuntimeException $e) {
504 $currentProcessorMaskValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_allowTemporaryMasksAsPng');
505 }
506
507 try {
508 $currentProcessorEffectsValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_effects');
509 } catch (\RuntimeException $e) {
510 $currentProcessorEffectsValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_effects');
511 }
512
513 if ((string)$currentProcessorValue !== '') {
514 if ($currentProcessorMaskValue != 0) {
515 $changedValues['GFX/processor_allowTemporaryMasksAsPng'] = 0;
516 }
517 if ($currentProcessorValue === 'GraphicsMagick') {
518 if ($currentProcessorEffectsValue != -1) {
519 $changedValues['GFX/processor_effects'] = -1;
520 }
521 }
522 }
523 if (!empty($changedValues)) {
524 $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($changedValues);
525 $this->throwRedirectException();
526 }
527 }
528
529 /**
530 * Migrate the definition of the image processor from the configuration value
531 * im_version_5 to the setting processor.
532 *
533 * @return void
534 */
535 protected function migrateImageProcessorSetting()
536 {
537 $changedSettings = array();
538 $settingsToRename = array(
539 'GFX/im' => 'GFX/processor_enabled',
540 'GFX/im_version_5' => 'GFX/processor',
541 'GFX/im_v5effects' => 'GFX/processor_effects',
542 'GFX/im_path' => 'GFX/processor_path',
543 'GFX/im_path_lzw' => 'GFX/processor_path_lzw',
544 'GFX/im_mask_temp_ext_gif' => 'GFX/processor_allowTemporaryMasksAsPng',
545 'GFX/im_noScaleUp' => 'GFX/processor_allowUpscaling',
546 'GFX/im_noFramePrepended' => 'GFX/processor_allowFrameSelection',
547 'GFX/im_stripProfileCommand' => 'GFX/processor_stripColorProfileCommand',
548 'GFX/im_useStripProfileByDefault' => 'GFX/processor_stripColorProfileByDefault',
549 'GFX/colorspace' => 'GFX/processor_colorspace',
550 );
551
552 foreach ($settingsToRename as $oldPath => $newPath) {
553 try {
554 $value = $this->configurationManager->getLocalConfigurationValueByPath($oldPath);
555 $this->configurationManager->setLocalConfigurationValueByPath($newPath, $value);
556 $changedSettings[$oldPath] = true;
557 } catch (\RuntimeException $e) {
558 // If an exception is thrown, the value is not set in LocalConfiguration
559 $changedSettings[$oldPath] = false;
560 }
561 }
562
563 if (!empty($changedSettings['GFX/im_version_5'])) {
564 $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_version_5');
565 $newProcessorValue = $currentProcessorValue === 'gm' ? 'GraphicsMagick' : 'ImageMagick';
566 $this->configurationManager->setLocalConfigurationValueByPath('GFX/processor', $newProcessorValue);
567 }
568
569 if (!empty($changedSettings['GFX/im_noScaleUp'])) {
570 $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_noScaleUp');
571 $newProcessorValue = !$currentProcessorValue;
572 $this->configurationManager->setLocalConfigurationValueByPath('GFX/processor_allowUpscaling', $newProcessorValue);
573 }
574
575 if (!empty($changedSettings['GFX/im_noFramePrepended'])) {
576 $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_noFramePrepended');
577 $newProcessorValue = !$currentProcessorValue;
578 $this->configurationManager->setLocalConfigurationValueByPath('GFX/processor_allowFrameSelection', $newProcessorValue);
579 }
580
581 if (!empty($changedSettings['GFX/im_mask_temp_ext_gif'])) {
582 $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_mask_temp_ext_gif');
583 $newProcessorValue = !$currentProcessorValue;
584 $this->configurationManager->setLocalConfigurationValueByPath('GFX/processor_allowTemporaryMasksAsPng', $newProcessorValue);
585 }
586
587 if (!empty(array_filter($changedSettings))) {
588 $this->configurationManager->removeLocalConfigurationKeysByPath(array_keys($changedSettings));
589 $this->throwRedirectException();
590 }
591 }
592
593 /**
594 * Throw exception after configuration change to trigger a redirect.
595 *
596 * @throws RedirectException
597 */
598 protected function throwRedirectException()
599 {
600 throw new RedirectException(
601 'Configuration updated, reload needed',
602 1379024938
603 );
604 }
605
606 /**
607 * Migrate the configuration value thumbnails_png to a boolean value.
608 *
609 * @return void
610 */
611 protected function migrateThumbnailsPngSetting()
612 {
613 $changedValues = array();
614 try {
615 $currentThumbnailsPngValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/thumbnails_png');
616 } catch (\RuntimeException $e) {
617 $currentThumbnailsPngValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/thumbnails_png');
618 }
619
620 if (is_int($currentThumbnailsPngValue) && $currentThumbnailsPngValue > 0) {
621 $changedValues['GFX/thumbnails_png'] = true;
622 }
623 if (!empty($changedValues)) {
624 $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($changedValues);
625 $this->throwRedirectException();
626 }
627 }
628 }