[!!!][TASK] Remove devlog constants
[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 = [
50 // #72400
51 'BE/spriteIconGenerator_handler',
52 // #72417
53 'SYS/lockingMode',
54 // #72473
55 'FE/secureFormmail',
56 'FE/strictFormmail',
57 'FE/formmailMaxAttachmentSize',
58 // #72337
59 'SYS/t3lib_cs_utils',
60 'SYS/t3lib_cs_convMethod',
61 // #72604
62 'SYS/maxFileNameLength',
63 // #72602
64 'BE/unzip_path',
65 // #72615
66 'BE/notificationPrefix',
67 // #72616
68 'BE/XCLASS',
69 'FE/XCLASS',
70 // #43085
71 'GFX/image_processing',
72 // #70056
73 'SYS/curlUse',
74 'SYS/curlProxyNTLM',
75 'SYS/curlProxyServer',
76 'SYS/curlProxyTunnel',
77 'SYS/curlProxyUserPass',
78 'SYS/curlTimeout',
79 // #75355
80 'BE/niceFlexFormXMLtags',
81 'BE/compactFlexFormXML',
82 // #75625
83 'SYS/clearCacheSystem',
84 // #77411
85 'SYS/caching/cacheConfigurations/extbase_typo3dbbackend_tablecolumns',
86 // #77460
87 'SYS/caching/cacheConfigurations/extbase_typo3dbbackend_queries',
88 // #79513
89 'FE/lockHashKeyWords',
90 'BE/lockHashKeyWords',
91 // #78835
92 'SYS/cookieHttpOnly',
93 // #71095
94 'BE/lang',
95 // #80050
96 'FE/cHashIncludePageId',
97 // #80711
98 'FE/noPHPscriptInclude',
99 'FE/maxSessionDataSize',
100 // #82162
101 'SYS/enable_errorDLOG',
102 'SYS/enable_exceptionDLOG',
103 ];
104
105 public function __construct(ConfigurationManager $configurationManager = null)
106 {
107 $this->configurationManager = $configurationManager ?: GeneralUtility::makeInstance(ConfigurationManager::class);
108 }
109
110 /**
111 * Executed configuration upgrades. Single upgrade methods must throw a
112 * RedirectException if something was written to LocalConfiguration.
113 */
114 public function execute()
115 {
116 $this->generateEncryptionKeyIfNeeded();
117 $this->configureBackendLoginSecurity();
118 $this->migrateImageProcessorSetting();
119 $this->transferHttpSettings();
120 $this->disableImageMagickDetailSettingsIfImageMagickIsDisabled();
121 $this->setImageMagickDetailSettings();
122 $this->migrateThumbnailsPngSetting();
123 $this->migrateLockSslSetting();
124 $this->migrateDatabaseConnectionSettings();
125 $this->migrateDatabaseConnectionCharset();
126 $this->migrateDatabaseDriverOptions();
127 $this->migrateLangDebug();
128
129 // Should run at the end to prevent that obsolete settings are removed before migration
130 $this->removeObsoleteLocalConfigurationSettings();
131 }
132
133 /**
134 * Some settings in LocalConfiguration vanished in DefaultConfiguration
135 * and have no impact on the core anymore.
136 * To keep the configuration clean, those old settings are just silently
137 * removed from LocalConfiguration if set.
138 */
139 protected function removeObsoleteLocalConfigurationSettings()
140 {
141 $removed = $this->configurationManager->removeLocalConfigurationKeysByPath($this->obsoleteLocalConfigurationSettings);
142
143 // If something was changed: Trigger a reload to have new values in next request
144 if ($removed) {
145 $this->throwRedirectException();
146 }
147 }
148
149 /**
150 * Backend login security is set to rsa if rsaauth
151 * is installed (but not used) otherwise the default value "normal" has to be used.
152 * This forces either 'normal' or 'rsa' to be set in LocalConfiguration.
153 */
154 protected function configureBackendLoginSecurity()
155 {
156 $rsaauthLoaded = ExtensionManagementUtility::isLoaded('rsaauth');
157 try {
158 $currentLoginSecurityLevelValue = $this->configurationManager->getLocalConfigurationValueByPath('BE/loginSecurityLevel');
159 if ($rsaauthLoaded && $currentLoginSecurityLevelValue !== 'rsa') {
160 $this->configurationManager->setLocalConfigurationValueByPath('BE/loginSecurityLevel', 'rsa');
161 $this->throwRedirectException();
162 } elseif (!$rsaauthLoaded && $currentLoginSecurityLevelValue !== 'normal') {
163 $this->configurationManager->setLocalConfigurationValueByPath('BE/loginSecurityLevel', 'normal');
164 $this->throwRedirectException();
165 }
166 } catch (\RuntimeException $e) {
167 // If an exception is thrown, the value is not set in LocalConfiguration
168 $this->configurationManager->setLocalConfigurationValueByPath(
169 'BE/loginSecurityLevel',
170 $rsaauthLoaded ? 'rsa' : 'normal'
171 );
172 $this->throwRedirectException();
173 }
174 }
175
176 /**
177 * The encryption key is crucial for securing form tokens
178 * and the whole TYPO3 link rendering later on. A random key is set here in
179 * LocalConfiguration if it does not exist yet. This might possible happen
180 * during upgrading and will happen during first install.
181 */
182 protected function generateEncryptionKeyIfNeeded()
183 {
184 try {
185 $currentValue = $this->configurationManager->getLocalConfigurationValueByPath('SYS/encryptionKey');
186 } catch (\RuntimeException $e) {
187 // If an exception is thrown, the value is not set in LocalConfiguration
188 $currentValue = '';
189 }
190
191 if (empty($currentValue)) {
192 $randomKey = GeneralUtility::makeInstance(Random::class)->generateRandomHexString(96);
193 $this->configurationManager->setLocalConfigurationValueByPath('SYS/encryptionKey', $randomKey);
194 $this->throwRedirectException();
195 }
196 }
197
198 /**
199 * Parse old curl and HTTP options and set new HTTP options, related to Guzzle
200 */
201 protected function transferHttpSettings()
202 {
203 $changed = false;
204 $newParameters = [];
205 $obsoleteParameters = [];
206
207 // Remove / migrate options to new options
208 try {
209 // Check if the adapter option is set, if so, set it to the parameters that are obsolete
210 $this->configurationManager->getLocalConfigurationValueByPath('HTTP/adapter');
211 $obsoleteParameters[] = 'HTTP/adapter';
212 } catch (\RuntimeException $e) {
213 }
214 try {
215 $newParameters['HTTP/version'] = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/protocol_version');
216 $obsoleteParameters[] = 'HTTP/protocol_version';
217 } catch (\RuntimeException $e) {
218 }
219 try {
220 $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_verify_host');
221 $obsoleteParameters[] = 'HTTP/ssl_verify_host';
222 } catch (\RuntimeException $e) {
223 }
224 try {
225 $legacyUserAgent = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/userAgent');
226 $newParameters['HTTP/headers/User-Agent'] = $legacyUserAgent;
227 $obsoleteParameters[] = 'HTTP/userAgent';
228 } catch (\RuntimeException $e) {
229 }
230
231 // Redirects
232 try {
233 $legacyFollowRedirects = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/follow_redirects');
234 $obsoleteParameters[] = 'HTTP/follow_redirects';
235 } catch (\RuntimeException $e) {
236 $legacyFollowRedirects = '';
237 }
238 try {
239 $legacyMaximumRedirects = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/max_redirects');
240 $obsoleteParameters[] = 'HTTP/max_redirects';
241 } catch (\RuntimeException $e) {
242 $legacyMaximumRedirects = '';
243 }
244 try {
245 $legacyStrictRedirects = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/strict_redirects');
246 $obsoleteParameters[] = 'HTTP/strict_redirects';
247 } catch (\RuntimeException $e) {
248 $legacyStrictRedirects = '';
249 }
250
251 // Check if redirects have been disabled
252 if ($legacyFollowRedirects !== '' && (bool)$legacyFollowRedirects === false) {
253 $newParameters['HTTP/allow_redirects'] = false;
254 } elseif ($legacyMaximumRedirects !== '' || $legacyStrictRedirects !== '') {
255 $newParameters['HTTP/allow_redirects'] = [];
256 if ($legacyMaximumRedirects !== '' && (int)$legacyMaximumRedirects !== 5) {
257 $newParameters['HTTP/allow_redirects']['max'] = (int)$legacyMaximumRedirects;
258 }
259 if ($legacyStrictRedirects !== '' && (bool)$legacyStrictRedirects === true) {
260 $newParameters['HTTP/allow_redirects']['strict'] = true;
261 }
262 // defaults are used, no need to set the option in LocalConfiguration.php
263 if (empty($newParameters['HTTP/allow_redirects'])) {
264 unset($newParameters['HTTP/allow_redirects']);
265 }
266 }
267
268 // Migrate Proxy settings
269 try {
270 // Currently without protocol or port
271 $legacyProxyHost = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_host');
272 $obsoleteParameters[] = 'HTTP/proxy_host';
273 } catch (\RuntimeException $e) {
274 $legacyProxyHost = '';
275 }
276 try {
277 $legacyProxyPort = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_port');
278 $obsoleteParameters[] = 'HTTP/proxy_port';
279 } catch (\RuntimeException $e) {
280 $legacyProxyPort = '';
281 }
282 try {
283 $legacyProxyUser = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_user');
284 $obsoleteParameters[] = 'HTTP/proxy_user';
285 } catch (\RuntimeException $e) {
286 $legacyProxyUser = '';
287 }
288 try {
289 $legacyProxyPassword = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_password');
290 $obsoleteParameters[] = 'HTTP/proxy_password';
291 } catch (\RuntimeException $e) {
292 $legacyProxyPassword = '';
293 }
294 // Auth Scheme: Basic, digest etc.
295 try {
296 $legacyProxyAuthScheme = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_auth_scheme');
297 $obsoleteParameters[] = 'HTTP/proxy_auth_scheme';
298 } catch (\RuntimeException $e) {
299 $legacyProxyAuthScheme = '';
300 }
301
302 if ($legacyProxyHost !== '') {
303 $proxy = 'http://';
304 if ($legacyProxyAuthScheme !== '' && $legacyProxyUser !== '' && $legacyProxyPassword !== '') {
305 $proxy .= $legacyProxyUser . ':' . $legacyProxyPassword . '@';
306 }
307 $proxy .= $legacyProxyHost;
308 if ($legacyProxyPort !== '') {
309 $proxy .= ':' . $legacyProxyPort;
310 }
311 $newParameters['HTTP/proxy'] = $proxy;
312 }
313
314 // Verify peers
315 // see http://docs.guzzlephp.org/en/latest/request-options.html#verify
316 try {
317 $legacySslVerifyPeer = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_verify_peer');
318 $obsoleteParameters[] = 'HTTP/ssl_verify_peer';
319 } catch (\RuntimeException $e) {
320 $legacySslVerifyPeer = '';
321 }
322
323 // Directory holding multiple Certificate Authority files
324 try {
325 $legacySslCaPath = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_capath');
326 $obsoleteParameters[] = 'HTTP/ssl_capath';
327 } catch (\RuntimeException $e) {
328 $legacySslCaPath = '';
329 }
330 // Certificate Authority file to verify the peer with (use when ssl_verify_peer is TRUE)
331 try {
332 $legacySslCaFile = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_cafile');
333 $obsoleteParameters[] = 'HTTP/ssl_cafile';
334 } catch (\RuntimeException $e) {
335 $legacySslCaFile = '';
336 }
337 if ($legacySslVerifyPeer !== '') {
338 if ($legacySslCaFile !== '' && $legacySslCaPath !== '') {
339 $newParameters['HTTP/verify'] = $legacySslCaPath . $legacySslCaFile;
340 } elseif ((bool)$legacySslVerifyPeer === false) {
341 $newParameters['HTTP/verify'] = false;
342 }
343 }
344
345 // SSL Key + Passphrase
346 // Name of a file containing local certificate
347 try {
348 $legacySslLocalCert = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_local_cert');
349 $obsoleteParameters[] = 'HTTP/ssl_local_cert';
350 } catch (\RuntimeException $e) {
351 $legacySslLocalCert = '';
352 }
353
354 // Passphrase with which local certificate was encoded
355 try {
356 $legacySslPassphrase = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_passphrase');
357 $obsoleteParameters[] = 'HTTP/ssl_passphrase';
358 } catch (\RuntimeException $e) {
359 $legacySslPassphrase = '';
360 }
361
362 if ($legacySslLocalCert !== '') {
363 if ($legacySslPassphrase !== '') {
364 $newParameters['HTTP/ssl_key'] = [
365 $legacySslLocalCert,
366 $legacySslPassphrase
367 ];
368 } else {
369 $newParameters['HTTP/ssl_key'] = $legacySslLocalCert;
370 }
371 }
372
373 // Update the LocalConfiguration file if obsolete parameters or new parameters are set
374 if (!empty($obsoleteParameters)) {
375 $this->configurationManager->removeLocalConfigurationKeysByPath($obsoleteParameters);
376 $changed = true;
377 }
378 if (!empty($newParameters)) {
379 $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($newParameters);
380 $changed = true;
381 }
382 if ($changed) {
383 $this->throwRedirectException();
384 }
385 }
386
387 /**
388 * Detail configuration of Image Magick settings must be cleared
389 * if Image Magick handling is disabled.
390 *
391 * "Configuration presets" in install tool is not type safe, so value
392 * comparisons here are not type safe too, to not trigger changes to
393 * LocalConfiguration again.
394 */
395 protected function disableImageMagickDetailSettingsIfImageMagickIsDisabled()
396 {
397 $changedValues = [];
398 try {
399 $currentImValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_enabled');
400 } catch (\RuntimeException $e) {
401 $currentImValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_enabled');
402 }
403
404 try {
405 $currentImPathValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_path');
406 } catch (\RuntimeException $e) {
407 $currentImPathValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_path');
408 }
409
410 try {
411 $currentImPathLzwValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_path_lzw');
412 } catch (\RuntimeException $e) {
413 $currentImPathLzwValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_path_lzw');
414 }
415
416 try {
417 $currentImageFileExtValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/imagefile_ext');
418 } catch (\RuntimeException $e) {
419 $currentImageFileExtValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/imagefile_ext');
420 }
421
422 try {
423 $currentThumbnailsValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/thumbnails');
424 } catch (\RuntimeException $e) {
425 $currentThumbnailsValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/thumbnails');
426 }
427
428 if (!$currentImValue) {
429 if ($currentImPathValue != '') {
430 $changedValues['GFX/processor_path'] = '';
431 }
432 if ($currentImPathLzwValue != '') {
433 $changedValues['GFX/processor_path_lzw'] = '';
434 }
435 if ($currentImageFileExtValue !== 'gif,jpg,jpeg,png') {
436 $changedValues['GFX/imagefile_ext'] = 'gif,jpg,jpeg,png';
437 }
438 if ($currentThumbnailsValue != 0) {
439 $changedValues['GFX/thumbnails'] = 0;
440 }
441 }
442 if (!empty($changedValues)) {
443 $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($changedValues);
444 $this->throwRedirectException();
445 }
446 }
447
448 /**
449 * Detail configuration of Image Magick and Graphics Magick settings
450 * depending on main values.
451 *
452 * "Configuration presets" in install tool is not type safe, so value
453 * comparisons here are not type safe too, to not trigger changes to
454 * LocalConfiguration again.
455 */
456 protected function setImageMagickDetailSettings()
457 {
458 $changedValues = [];
459 try {
460 $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor');
461 } catch (\RuntimeException $e) {
462 $currentProcessorValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor');
463 }
464
465 try {
466 $currentProcessorMaskValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_allowTemporaryMasksAsPng');
467 } catch (\RuntimeException $e) {
468 $currentProcessorMaskValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_allowTemporaryMasksAsPng');
469 }
470
471 try {
472 $currentProcessorEffectsValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_effects');
473 } catch (\RuntimeException $e) {
474 $currentProcessorEffectsValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_effects');
475 }
476
477 if ((string)$currentProcessorValue !== '') {
478 if ($currentProcessorMaskValue != 0) {
479 $changedValues['GFX/processor_allowTemporaryMasksAsPng'] = 0;
480 }
481 if ($currentProcessorValue === 'GraphicsMagick') {
482 if ($currentProcessorEffectsValue != -1) {
483 $changedValues['GFX/processor_effects'] = -1;
484 }
485 }
486 }
487 if (!empty($changedValues)) {
488 $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($changedValues);
489 $this->throwRedirectException();
490 }
491 }
492
493 /**
494 * Migrate the definition of the image processor from the configuration value
495 * im_version_5 to the setting processor.
496 */
497 protected function migrateImageProcessorSetting()
498 {
499 $changedSettings = [];
500 $settingsToRename = [
501 'GFX/im' => 'GFX/processor_enabled',
502 'GFX/im_version_5' => 'GFX/processor',
503 'GFX/im_v5effects' => 'GFX/processor_effects',
504 'GFX/im_path' => 'GFX/processor_path',
505 'GFX/im_path_lzw' => 'GFX/processor_path_lzw',
506 'GFX/im_mask_temp_ext_gif' => 'GFX/processor_allowTemporaryMasksAsPng',
507 'GFX/im_noScaleUp' => 'GFX/processor_allowUpscaling',
508 'GFX/im_noFramePrepended' => 'GFX/processor_allowFrameSelection',
509 'GFX/im_stripProfileCommand' => 'GFX/processor_stripColorProfileCommand',
510 'GFX/im_useStripProfileByDefault' => 'GFX/processor_stripColorProfileByDefault',
511 'GFX/colorspace' => 'GFX/processor_colorspace',
512 ];
513
514 foreach ($settingsToRename as $oldPath => $newPath) {
515 try {
516 $value = $this->configurationManager->getLocalConfigurationValueByPath($oldPath);
517 $this->configurationManager->setLocalConfigurationValueByPath($newPath, $value);
518 $changedSettings[$oldPath] = true;
519 } catch (\RuntimeException $e) {
520 // If an exception is thrown, the value is not set in LocalConfiguration
521 $changedSettings[$oldPath] = false;
522 }
523 }
524
525 if (!empty($changedSettings['GFX/im_version_5'])) {
526 $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_version_5');
527 $newProcessorValue = $currentProcessorValue === 'gm' ? 'GraphicsMagick' : 'ImageMagick';
528 $this->configurationManager->setLocalConfigurationValueByPath('GFX/processor', $newProcessorValue);
529 }
530
531 if (!empty($changedSettings['GFX/im_noScaleUp'])) {
532 $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_noScaleUp');
533 $newProcessorValue = !$currentProcessorValue;
534 $this->configurationManager->setLocalConfigurationValueByPath(
535 'GFX/processor_allowUpscaling',
536 $newProcessorValue
537 );
538 }
539
540 if (!empty($changedSettings['GFX/im_noFramePrepended'])) {
541 $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_noFramePrepended');
542 $newProcessorValue = !$currentProcessorValue;
543 $this->configurationManager->setLocalConfigurationValueByPath(
544 'GFX/processor_allowFrameSelection',
545 $newProcessorValue
546 );
547 }
548
549 if (!empty($changedSettings['GFX/im_mask_temp_ext_gif'])) {
550 $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_mask_temp_ext_gif');
551 $newProcessorValue = !$currentProcessorValue;
552 $this->configurationManager->setLocalConfigurationValueByPath(
553 'GFX/processor_allowTemporaryMasksAsPng',
554 $newProcessorValue
555 );
556 }
557
558 if (!empty(array_filter($changedSettings))) {
559 $this->configurationManager->removeLocalConfigurationKeysByPath(array_keys($changedSettings));
560 $this->throwRedirectException();
561 }
562 }
563
564 /**
565 * Throw exception after configuration change to trigger a redirect.
566 *
567 * @throws RedirectException
568 */
569 protected function throwRedirectException()
570 {
571 throw new RedirectException(
572 'Configuration updated, reload needed',
573 1379024938
574 );
575 }
576
577 /**
578 * Migrate the configuration value thumbnails_png to a boolean value.
579 */
580 protected function migrateThumbnailsPngSetting()
581 {
582 $changedValues = [];
583 try {
584 $currentThumbnailsPngValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/thumbnails_png');
585 } catch (\RuntimeException $e) {
586 $currentThumbnailsPngValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/thumbnails_png');
587 }
588
589 if (is_int($currentThumbnailsPngValue) && $currentThumbnailsPngValue > 0) {
590 $changedValues['GFX/thumbnails_png'] = true;
591 }
592 if (!empty($changedValues)) {
593 $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($changedValues);
594 $this->throwRedirectException();
595 }
596 }
597
598 /**
599 * Migrate the configuration setting BE/lockSSL to boolean if set in the LocalConfiguration.php file
600 */
601 protected function migrateLockSslSetting()
602 {
603 try {
604 $currentOption = $this->configurationManager->getLocalConfigurationValueByPath('BE/lockSSL');
605 // check if the current option is an integer/string and if it is active
606 if (!is_bool($currentOption) && (int)$currentOption > 0) {
607 $this->configurationManager->setLocalConfigurationValueByPath('BE/lockSSL', true);
608 $this->throwRedirectException();
609 }
610 } catch (\RuntimeException $e) {
611 // no change inside the LocalConfiguration.php found, so nothing needs to be modified
612 }
613 }
614
615 /**
616 * Move the database connection settings to a "Default" connection
617 */
618 protected function migrateDatabaseConnectionSettings()
619 {
620 $confManager = $this->configurationManager;
621
622 $newSettings = [];
623 $removeSettings = [];
624
625 try {
626 $value = $confManager->getLocalConfigurationValueByPath('DB/username');
627 $removeSettings[] = 'DB/username';
628 $newSettings['DB/Connections/Default/user'] = $value;
629 } catch (\RuntimeException $e) {
630 // Old setting does not exist, do nothing
631 }
632
633 try {
634 $value= $confManager->getLocalConfigurationValueByPath('DB/password');
635 $removeSettings[] = 'DB/password';
636 $newSettings['DB/Connections/Default/password'] = $value;
637 } catch (\RuntimeException $e) {
638 // Old setting does not exist, do nothing
639 }
640
641 try {
642 $value = $confManager->getLocalConfigurationValueByPath('DB/host');
643 $removeSettings[] = 'DB/host';
644 $newSettings['DB/Connections/Default/host'] = $value;
645 } catch (\RuntimeException $e) {
646 // Old setting does not exist, do nothing
647 }
648
649 try {
650 $value = $confManager->getLocalConfigurationValueByPath('DB/port');
651 $removeSettings[] = 'DB/port';
652 $newSettings['DB/Connections/Default/port'] = $value;
653 } catch (\RuntimeException $e) {
654 // Old setting does not exist, do nothing
655 }
656
657 try {
658 $value = $confManager->getLocalConfigurationValueByPath('DB/socket');
659 $removeSettings[] = 'DB/socket';
660 // Remove empty socket connects
661 if (!empty($value)) {
662 $newSettings['DB/Connections/Default/unix_socket'] = $value;
663 }
664 } catch (\RuntimeException $e) {
665 // Old setting does not exist, do nothing
666 }
667
668 try {
669 $value = $confManager->getLocalConfigurationValueByPath('DB/database');
670 $removeSettings[] = 'DB/database';
671 $newSettings['DB/Connections/Default/dbname'] = $value;
672 } catch (\RuntimeException $e) {
673 // Old setting does not exist, do nothing
674 }
675
676 try {
677 $value = (bool)$confManager->getLocalConfigurationValueByPath('SYS/dbClientCompress');
678 $removeSettings[] = 'SYS/dbClientCompress';
679 if ($value) {
680 $newSettings['DB/Connections/Default/driverOptions'] = [
681 'flags' => MYSQLI_CLIENT_COMPRESS,
682 ];
683 }
684 } catch (\RuntimeException $e) {
685 // Old setting does not exist, do nothing
686 }
687
688 try {
689 $value = (bool)$confManager->getLocalConfigurationValueByPath('SYS/no_pconnect');
690 $removeSettings[] = 'SYS/no_pconnect';
691 if (!$value) {
692 $newSettings['DB/Connections/Default/persistentConnection'] = true;
693 }
694 } catch (\RuntimeException $e) {
695 // Old setting does not exist, do nothing
696 }
697
698 try {
699 $value = $confManager->getLocalConfigurationValueByPath('SYS/setDBinit');
700 $removeSettings[] = 'SYS/setDBinit';
701 $newSettings['DB/Connections/Default/initCommands'] = $value;
702 } catch (\RuntimeException $e) {
703 // Old setting does not exist, do nothing
704 }
705
706 try {
707 $confManager->getLocalConfigurationValueByPath('DB/Connections/Default/charset');
708 } catch (\RuntimeException $e) {
709 // If there is no charset option yet, add it.
710 $newSettings['DB/Connections/Default/charset'] = 'utf8';
711 }
712
713 try {
714 $confManager->getLocalConfigurationValueByPath('DB/Connections/Default/driver');
715 } catch (\RuntimeException $e) {
716 // Use the mysqli driver by default if no value has been provided yet
717 $newSettings['DB/Connections/Default/driver'] = 'mysqli';
718 }
719
720 // Add new settings and remove old ones
721 if (!empty($newSettings)) {
722 $confManager->setLocalConfigurationValuesByPathValuePairs($newSettings);
723 }
724 if (!empty($removeSettings)) {
725 $confManager->removeLocalConfigurationKeysByPath($removeSettings);
726 }
727
728 // Throw redirect if something was changed
729 if (!empty($newSettings) || !empty($removeSettings)) {
730 $this->throwRedirectException();
731 }
732 }
733
734 /**
735 * Migrate the configuration setting DB/Connections/Default/charset to 'utf8' as
736 * 'utf-8' is not supported by all MySQL versions.
737 */
738 protected function migrateDatabaseConnectionCharset()
739 {
740 $confManager = $this->configurationManager;
741 try {
742 $driver = $confManager->getLocalConfigurationValueByPath('DB/Connections/Default/driver');
743 $charset = $confManager->getLocalConfigurationValueByPath('DB/Connections/Default/charset');
744 if (in_array($driver, ['mysqli', 'pdo_mysql', 'drizzle_pdo_mysql'], true) && $charset === 'utf-8') {
745 $confManager->setLocalConfigurationValueByPath('DB/Connections/Default/charset', 'utf8');
746 $this->throwRedirectException();
747 }
748 } catch (\RuntimeException $e) {
749 // no incompatible charset configuration found, so nothing needs to be modified
750 }
751 }
752
753 /**
754 * Migrate the configuration setting DB/Connections/Default/driverOptions to array type.
755 */
756 protected function migrateDatabaseDriverOptions()
757 {
758 $confManager = $this->configurationManager;
759 try {
760 $options = $confManager->getLocalConfigurationValueByPath('DB/Connections/Default/driverOptions');
761 if (!is_array($options)) {
762 $confManager->setLocalConfigurationValueByPath(
763 'DB/Connections/Default/driverOptions',
764 ['flags' => (int)$options]
765 );
766 }
767 } catch (\RuntimeException $e) {
768 // no driver options found, nothing needs to be modified
769 }
770 }
771
772 /**
773 * Migrate the configuration setting BE/lang/debug if set in the LocalConfiguration.php file
774 */
775 protected function migrateLangDebug()
776 {
777 $confManager = $this->configurationManager;
778 try {
779 $currentOption = $confManager->getLocalConfigurationValueByPath('BE/lang/debug');
780 // check if the current option is set and boolean
781 if (isset($currentOption) && is_bool($currentOption)) {
782 $confManager->setLocalConfigurationValueByPath('BE/languageDebug', $currentOption);
783 }
784 } catch (\RuntimeException $e) {
785 // no change inside the LocalConfiguration.php found, so nothing needs to be modified
786 }
787 }
788 }