‪TYPO3CMS  10.4
SilentConfigurationUpgradeService.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
18 use TYPO3\CMS\Core\Configuration\ConfigurationManager;
30 
44 {
48  protected ‪$configurationManager;
49 
59  // #72400
60  'BE/spriteIconGenerator_handler',
61  // #72417
62  'SYS/lockingMode',
63  // #72473
64  'FE/secureFormmail',
65  'FE/strictFormmail',
66  'FE/formmailMaxAttachmentSize',
67  // #72337
68  'SYS/t3lib_cs_utils',
69  'SYS/t3lib_cs_convMethod',
70  // #72604
71  'SYS/maxFileNameLength',
72  // #72602
73  'BE/unzip_path',
74  // #72615
75  'BE/notificationPrefix',
76  // #72616
77  'BE/XCLASS',
78  'FE/XCLASS',
79  // #43085
80  'GFX/image_processing',
81  // #70056
82  'SYS/curlUse',
83  'SYS/curlProxyNTLM',
84  'SYS/curlProxyServer',
85  'SYS/curlProxyTunnel',
86  'SYS/curlProxyUserPass',
87  'SYS/curlTimeout',
88  // #75355
89  'BE/niceFlexFormXMLtags',
90  'BE/compactFlexFormXML',
91  // #75625
92  'SYS/clearCacheSystem',
93  // #77411
94  'SYS/caching/cacheConfigurations/extbase_typo3dbbackend_tablecolumns',
95  // #77460
96  'SYS/caching/cacheConfigurations/extbase_typo3dbbackend_queries',
97  // #79513
98  'FE/lockHashKeyWords',
99  'BE/lockHashKeyWords',
100  // #78835
101  'SYS/cookieHttpOnly',
102  // #71095
103  'BE/lang',
104  // #80050
105  'FE/cHashIncludePageId',
106  // #80711
107  'FE/noPHPscriptInclude',
108  'FE/maxSessionDataSize',
109  // #82162
110  'SYS/enable_errorDLOG',
111  'SYS/enable_exceptionDLOG',
112  // #82377
113  'EXT/allowSystemInstall',
114  // #82421
115  'SYS/sqlDebug',
116  'SYS/no_pconnect',
117  'SYS/setDBinit',
118  'SYS/dbClientCompress',
119  // #82430
120  'SYS/syslogErrorReporting',
121  // #82639
122  'SYS/enable_DLOG',
123  'SC_OPTIONS/t3lib/class.t3lib_userauth.php/writeDevLog',
124  'SC_OPTIONS/t3lib/class.t3lib_userauth.php/writeDevLogBE',
125  'SC_OPTIONS/t3lib/class.t3lib_userauth.php/writeDevLogFE',
126  // #82438
127  'SYS/enableDeprecationLog',
128  // #82680
129  'GFX/png_truecolor',
130  // #82803
131  'FE/content_doktypes',
132  // #83081
133  'BE/fileExtensions',
134  // #83768
135  'SYS/doNotCheckReferer',
136  // #83878
137  'SYS/isInitialInstallationInProgress',
138  'SYS/isInitialDatabaseImportDone',
139  // #84810
140  'BE/explicitConfirmationOfTranslation',
141  // #87482
142  'EXT/extConf',
143  // #87767
144  'SYS/recursiveDomainSearch',
145  // #88376
146  'FE/pageNotFound_handling',
147  'FE/pageNotFound_handling_statheader',
148  'FE/pageNotFound_handling_accessdeniedheader',
149  'FE/pageUnavailable_handling',
150  'FE/pageUnavailable_handling_statheader',
151  // #88458
152  'FE/get_url_id_token',
153  // #88500
154  'BE/RTE_imageStorageDir',
155  // #89645
156  'SYS/systemLog',
157  'SYS/systemLogLevel',
158  ];
159 
160  public function ‪__construct(ConfigurationManager ‪$configurationManager)
161  {
162  $this->configurationManager = ‪$configurationManager;
163  }
164 
171  public function ‪execute()
172  {
177  $this->‪transferHttpSettings();
181  $this->‪migrateLockSslSetting();
185  $this->‪migrateLangDebug();
187  $this->‪migrateExceptionErrors();
193 
194  // Should run at the end to prevent obsolete settings are removed before migration
196  }
197 
207  {
208  $removed = $this->configurationManager->removeLocalConfigurationKeysByPath($this->obsoleteLocalConfigurationSettings);
209 
210  // If something was changed: Trigger a reload to have new values in next request
211  if ($removed) {
213  }
214  }
215 
223  protected function ‪configureBackendLoginSecurity()
224  {
225  $rsaauthLoaded = ‪ExtensionManagementUtility::isLoaded('rsaauth');
226  try {
227  $currentLoginSecurityLevelValue = $this->configurationManager->getLocalConfigurationValueByPath('BE/loginSecurityLevel');
228  if ($rsaauthLoaded && $currentLoginSecurityLevelValue !== 'rsa') {
229  $this->configurationManager->setLocalConfigurationValueByPath('BE/loginSecurityLevel', 'rsa');
231  } elseif (!$rsaauthLoaded && $currentLoginSecurityLevelValue !== 'normal') {
232  $this->configurationManager->setLocalConfigurationValueByPath('BE/loginSecurityLevel', 'normal');
234  }
235  } catch (MissingArrayPathException $e) {
236  // If an exception is thrown, the value is not set in LocalConfiguration
237  $this->configurationManager->setLocalConfigurationValueByPath(
238  'BE/loginSecurityLevel',
239  $rsaauthLoaded ? 'rsa' : 'normal'
240  );
242  }
243  }
244 
251  protected function ‪configureFrontendLoginSecurity()
252  {
253  $rsaauthLoaded = ‪ExtensionManagementUtility::isLoaded('rsaauth');
254  try {
255  $currentLoginSecurityLevelValue = $this->configurationManager->getLocalConfigurationValueByPath('FE/loginSecurityLevel');
256  if (!$rsaauthLoaded && $currentLoginSecurityLevelValue !== 'normal') {
257  $this->configurationManager->setLocalConfigurationValueByPath('FE/loginSecurityLevel', 'normal');
259  }
260  } catch (MissingArrayPathException $e) {
261  // no value set, just ignore
262  }
263  }
264 
273  protected function ‪generateEncryptionKeyIfNeeded()
274  {
275  try {
276  $currentValue = $this->configurationManager->getLocalConfigurationValueByPath('SYS/encryptionKey');
277  } catch (MissingArrayPathException $e) {
278  // If an exception is thrown, the value is not set in LocalConfiguration
279  $currentValue = '';
280  }
281 
282  if (empty($currentValue)) {
283  $randomKey = GeneralUtility::makeInstance(Random::class)->generateRandomHexString(96);
284  $this->configurationManager->setLocalConfigurationValueByPath('SYS/encryptionKey', $randomKey);
286  }
287  }
288 
294  protected function ‪transferHttpSettings()
295  {
296  $changed = false;
297  $newParameters = [];
298  $obsoleteParameters = [];
299 
300  // Remove / migrate options to new options
301  try {
302  // Check if the adapter option is set, if so, set it to the parameters that are obsolete
303  $this->configurationManager->getLocalConfigurationValueByPath('HTTP/adapter');
304  $obsoleteParameters[] = 'HTTP/adapter';
305  } catch (MissingArrayPathException $e) {
306  // Migration done already
307  }
308  try {
309  $newParameters['HTTP/version'] = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/protocol_version');
310  $obsoleteParameters[] = 'HTTP/protocol_version';
311  } catch (MissingArrayPathException $e) {
312  // Migration done already
313  }
314  try {
315  $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_verify_host');
316  $obsoleteParameters[] = 'HTTP/ssl_verify_host';
317  } catch (MissingArrayPathException $e) {
318  // Migration done already
319  }
320  try {
321  $legacyUserAgent = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/userAgent');
322  $newParameters['HTTP/headers/User-Agent'] = $legacyUserAgent;
323  $obsoleteParameters[] = 'HTTP/userAgent';
324  } catch (MissingArrayPathException $e) {
325  // Migration done already
326  }
327 
328  // Redirects
329  try {
330  $legacyFollowRedirects = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/follow_redirects');
331  $obsoleteParameters[] = 'HTTP/follow_redirects';
332  } catch (MissingArrayPathException $e) {
333  $legacyFollowRedirects = '';
334  }
335  try {
336  $legacyMaximumRedirects = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/max_redirects');
337  $obsoleteParameters[] = 'HTTP/max_redirects';
338  } catch (MissingArrayPathException $e) {
339  $legacyMaximumRedirects = '';
340  }
341  try {
342  $legacyStrictRedirects = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/strict_redirects');
343  $obsoleteParameters[] = 'HTTP/strict_redirects';
344  } catch (MissingArrayPathException $e) {
345  $legacyStrictRedirects = '';
346  }
347 
348  // Check if redirects have been disabled
349  if ($legacyFollowRedirects !== '' && (bool)$legacyFollowRedirects === false) {
350  $newParameters['HTTP/allow_redirects'] = false;
351  } elseif ($legacyMaximumRedirects !== '' || $legacyStrictRedirects !== '') {
352  $newParameters['HTTP/allow_redirects'] = [];
353  if ($legacyMaximumRedirects !== '' && (int)$legacyMaximumRedirects !== 5) {
354  $newParameters['HTTP/allow_redirects']['max'] = (int)$legacyMaximumRedirects;
355  }
356  if ($legacyStrictRedirects !== '' && (bool)$legacyStrictRedirects === true) {
357  $newParameters['HTTP/allow_redirects']['strict'] = true;
358  }
359  // defaults are used, no need to set the option in LocalConfiguration.php
360  if (empty($newParameters['HTTP/allow_redirects'])) {
361  unset($newParameters['HTTP/allow_redirects']);
362  }
363  }
364 
365  // Migrate Proxy settings
366  try {
367  // Currently without protocol or port
368  $legacyProxyHost = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_host');
369  $obsoleteParameters[] = 'HTTP/proxy_host';
370  } catch (MissingArrayPathException $e) {
371  $legacyProxyHost = '';
372  }
373  try {
374  $legacyProxyPort = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_port');
375  $obsoleteParameters[] = 'HTTP/proxy_port';
376  } catch (MissingArrayPathException $e) {
377  $legacyProxyPort = '';
378  }
379  try {
380  $legacyProxyUser = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_user');
381  $obsoleteParameters[] = 'HTTP/proxy_user';
382  } catch (MissingArrayPathException $e) {
383  $legacyProxyUser = '';
384  }
385  try {
386  $legacyProxyPassword = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_password');
387  $obsoleteParameters[] = 'HTTP/proxy_password';
388  } catch (MissingArrayPathException $e) {
389  $legacyProxyPassword = '';
390  }
391  // Auth Scheme: Basic, digest etc.
392  try {
393  $legacyProxyAuthScheme = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_auth_scheme');
394  $obsoleteParameters[] = 'HTTP/proxy_auth_scheme';
395  } catch (MissingArrayPathException $e) {
396  $legacyProxyAuthScheme = '';
397  }
398 
399  if ($legacyProxyHost !== '') {
400  $proxy = 'http://';
401  if ($legacyProxyAuthScheme !== '' && $legacyProxyUser !== '' && $legacyProxyPassword !== '') {
402  $proxy .= $legacyProxyUser . ':' . $legacyProxyPassword . '@';
403  }
404  $proxy .= $legacyProxyHost;
405  if ($legacyProxyPort !== '') {
406  $proxy .= ':' . $legacyProxyPort;
407  }
408  $newParameters['HTTP/proxy'] = $proxy;
409  }
410 
411  // Verify peers
412  // see http://docs.guzzlephp.org/en/latest/request-options.html#verify
413  try {
414  $legacySslVerifyPeer = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_verify_peer');
415  $obsoleteParameters[] = 'HTTP/ssl_verify_peer';
416  } catch (MissingArrayPathException $e) {
417  $legacySslVerifyPeer = '';
418  }
419 
420  // Directory holding multiple Certificate Authority files
421  try {
422  $legacySslCaPath = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_capath');
423  $obsoleteParameters[] = 'HTTP/ssl_capath';
424  } catch (MissingArrayPathException $e) {
425  $legacySslCaPath = '';
426  }
427  // Certificate Authority file to verify the peer with (use when ssl_verify_peer is TRUE)
428  try {
429  $legacySslCaFile = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_cafile');
430  $obsoleteParameters[] = 'HTTP/ssl_cafile';
431  } catch (MissingArrayPathException $e) {
432  $legacySslCaFile = '';
433  }
434  if ($legacySslVerifyPeer !== '') {
435  if ($legacySslCaFile !== '' && $legacySslCaPath !== '') {
436  $newParameters['HTTP/verify'] = $legacySslCaPath . $legacySslCaFile;
437  } elseif ((bool)$legacySslVerifyPeer === false) {
438  $newParameters['HTTP/verify'] = false;
439  }
440  }
441 
442  // SSL Key + Passphrase
443  // Name of a file containing local certificate
444  try {
445  $legacySslLocalCert = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_local_cert');
446  $obsoleteParameters[] = 'HTTP/ssl_local_cert';
447  } catch (MissingArrayPathException $e) {
448  $legacySslLocalCert = '';
449  }
450 
451  // Passphrase with which local certificate was encoded
452  try {
453  $legacySslPassphrase = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_passphrase');
454  $obsoleteParameters[] = 'HTTP/ssl_passphrase';
455  } catch (MissingArrayPathException $e) {
456  $legacySslPassphrase = '';
457  }
458 
459  if ($legacySslLocalCert !== '') {
460  if ($legacySslPassphrase !== '') {
461  $newParameters['HTTP/ssl_key'] = [
462  $legacySslLocalCert,
463  $legacySslPassphrase
464  ];
465  } else {
466  $newParameters['HTTP/ssl_key'] = $legacySslLocalCert;
467  }
468  }
469 
470  // Update the LocalConfiguration file if obsolete parameters or new parameters are set
471  if (!empty($obsoleteParameters)) {
472  $this->configurationManager->removeLocalConfigurationKeysByPath($obsoleteParameters);
473  $changed = true;
474  }
475  if (!empty($newParameters)) {
476  $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($newParameters);
477  $changed = true;
478  }
479  if ($changed) {
481  }
482  }
483 
495  {
496  $changedValues = [];
497  try {
498  $currentEnabledValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_enabled');
499  } catch (MissingArrayPathException $e) {
500  $currentEnabledValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_enabled');
501  }
502 
503  try {
504  $currentPathValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_path');
505  } catch (MissingArrayPathException $e) {
506  $currentPathValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_path');
507  }
508 
509  try {
510  $currentPathLzwValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_path_lzw');
511  } catch (MissingArrayPathException $e) {
512  $currentPathLzwValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_path_lzw');
513  }
514 
515  try {
516  $currentImageFileExtValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/imagefile_ext');
517  } catch (MissingArrayPathException $e) {
518  $currentImageFileExtValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/imagefile_ext');
519  }
520 
521  try {
522  $currentThumbnailsValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/thumbnails');
523  } catch (MissingArrayPathException $e) {
524  $currentThumbnailsValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/thumbnails');
525  }
526 
527  if (!$currentEnabledValue) {
528  if ($currentPathValue != '') {
529  $changedValues['GFX/processor_path'] = '';
530  }
531  if ($currentPathLzwValue != '') {
532  $changedValues['GFX/processor_path_lzw'] = '';
533  }
534  if ($currentImageFileExtValue !== 'gif,jpg,jpeg,png') {
535  $changedValues['GFX/imagefile_ext'] = 'gif,jpg,jpeg,png';
536  }
537  if ($currentThumbnailsValue != 0) {
538  $changedValues['GFX/thumbnails'] = 0;
539  }
540  }
541  if (!empty($changedValues)) {
542  $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($changedValues);
544  }
545  }
546 
557  protected function ‪setImageMagickDetailSettings()
558  {
559  $changedValues = [];
560  try {
561  $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor');
562  } catch (MissingArrayPathException $e) {
563  $currentProcessorValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor');
564  }
565 
566  try {
567  $currentProcessorMaskValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_allowTemporaryMasksAsPng');
568  } catch (MissingArrayPathException $e) {
569  $currentProcessorMaskValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_allowTemporaryMasksAsPng');
570  }
571 
572  try {
573  $currentProcessorEffectsValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_effects');
574  } catch (MissingArrayPathException $e) {
575  $currentProcessorEffectsValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_effects');
576  }
577 
578  if ((string)$currentProcessorValue !== '') {
579  if (!is_bool($currentProcessorEffectsValue)) {
580  $changedValues['GFX/processor_effects'] = (int)$currentProcessorEffectsValue > 0;
581  }
582 
583  if ($currentProcessorMaskValue != 0) {
584  $changedValues['GFX/processor_allowTemporaryMasksAsPng'] = 0;
585  }
586  }
587  if (!empty($changedValues)) {
588  $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($changedValues);
590  }
591  }
592 
599  protected function ‪migrateImageProcessorSetting()
600  {
601  $changedSettings = [];
602  $settingsToRename = [
603  'GFX/im' => 'GFX/processor_enabled',
604  'GFX/im_version_5' => 'GFX/processor',
605  'GFX/im_v5effects' => 'GFX/processor_effects',
606  'GFX/im_path' => 'GFX/processor_path',
607  'GFX/im_path_lzw' => 'GFX/processor_path_lzw',
608  'GFX/im_mask_temp_ext_gif' => 'GFX/processor_allowTemporaryMasksAsPng',
609  'GFX/im_noScaleUp' => 'GFX/processor_allowUpscaling',
610  'GFX/im_noFramePrepended' => 'GFX/processor_allowFrameSelection',
611  'GFX/im_stripProfileCommand' => 'GFX/processor_stripColorProfileCommand',
612  'GFX/im_useStripProfileByDefault' => 'GFX/processor_stripColorProfileByDefault',
613  'GFX/colorspace' => 'GFX/processor_colorspace',
614  ];
615 
616  foreach ($settingsToRename as $oldPath => $newPath) {
617  try {
618  $value = $this->configurationManager->getLocalConfigurationValueByPath($oldPath);
619  $this->configurationManager->setLocalConfigurationValueByPath($newPath, $value);
620  $changedSettings[$oldPath] = true;
621  } catch (MissingArrayPathException $e) {
622  // If an exception is thrown, the value is not set in LocalConfiguration
623  $changedSettings[$oldPath] = false;
624  }
625  }
626 
627  if (!empty($changedSettings['GFX/im_version_5'])) {
628  $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_version_5');
629  $newProcessorValue = $currentProcessorValue === 'gm' ? 'GraphicsMagick' : 'ImageMagick';
630  $this->configurationManager->setLocalConfigurationValueByPath('GFX/processor', $newProcessorValue);
631  }
632 
633  if (!empty($changedSettings['GFX/im_noScaleUp'])) {
634  $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_noScaleUp');
635  $newProcessorValue = !$currentProcessorValue;
636  $this->configurationManager->setLocalConfigurationValueByPath(
637  'GFX/processor_allowUpscaling',
638  $newProcessorValue
639  );
640  }
641 
642  if (!empty($changedSettings['GFX/im_noFramePrepended'])) {
643  $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_noFramePrepended');
644  $newProcessorValue = !$currentProcessorValue;
645  $this->configurationManager->setLocalConfigurationValueByPath(
646  'GFX/processor_allowFrameSelection',
647  $newProcessorValue
648  );
649  }
650 
651  if (!empty($changedSettings['GFX/im_mask_temp_ext_gif'])) {
652  $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_mask_temp_ext_gif');
653  $newProcessorValue = !$currentProcessorValue;
654  $this->configurationManager->setLocalConfigurationValueByPath(
655  'GFX/processor_allowTemporaryMasksAsPng',
656  $newProcessorValue
657  );
658  }
659 
660  if (!empty(array_filter($changedSettings))) {
661  $this->configurationManager->removeLocalConfigurationKeysByPath(array_keys($changedSettings));
663  }
664  }
665 
671  protected function ‪throwConfigurationChangedException()
672  {
673  throw new ConfigurationChangedException(
674  'Configuration updated, reload needed',
675  1379024938
676  );
677  }
678 
684  protected function ‪migrateThumbnailsPngSetting()
685  {
686  $changedValues = [];
687  try {
688  $currentThumbnailsPngValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/thumbnails_png');
689  } catch (MissingArrayPathException $e) {
690  $currentThumbnailsPngValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/thumbnails_png');
691  }
692 
693  if (is_int($currentThumbnailsPngValue) && $currentThumbnailsPngValue > 0) {
694  $changedValues['GFX/thumbnails_png'] = true;
695  }
696  if (!empty($changedValues)) {
697  $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($changedValues);
699  }
700  }
701 
707  protected function ‪migrateLockSslSetting()
708  {
709  try {
710  $currentOption = $this->configurationManager->getLocalConfigurationValueByPath('BE/lockSSL');
711  // check if the current option is an integer/string and if it is active
712  if (!is_bool($currentOption) && (int)$currentOption > 0) {
713  $this->configurationManager->setLocalConfigurationValueByPath('BE/lockSSL', true);
715  }
716  } catch (MissingArrayPathException $e) {
717  // no change inside the LocalConfiguration.php found, so nothing needs to be modified
718  }
719  }
720 
726  protected function ‪migrateDatabaseConnectionSettings()
727  {
728  $confManager = ‪$this->configurationManager;
729 
730  $newSettings = [];
731  $removeSettings = [];
732 
733  try {
734  $value = $confManager->getLocalConfigurationValueByPath('DB/username');
735  $removeSettings[] = 'DB/username';
736  $newSettings['DB/Connections/Default/user'] = $value;
737  } catch (MissingArrayPathException $e) {
738  // Old setting does not exist, do nothing
739  }
740 
741  try {
742  $value = $confManager->getLocalConfigurationValueByPath('DB/password');
743  $removeSettings[] = 'DB/password';
744  $newSettings['DB/Connections/Default/password'] = $value;
745  } catch (MissingArrayPathException $e) {
746  // Old setting does not exist, do nothing
747  }
748 
749  try {
750  $value = $confManager->getLocalConfigurationValueByPath('DB/host');
751  $removeSettings[] = 'DB/host';
752  $newSettings['DB/Connections/Default/host'] = $value;
753  } catch (MissingArrayPathException $e) {
754  // Old setting does not exist, do nothing
755  }
756 
757  try {
758  $value = $confManager->getLocalConfigurationValueByPath('DB/port');
759  $removeSettings[] = 'DB/port';
760  $newSettings['DB/Connections/Default/port'] = $value;
761  } catch (MissingArrayPathException $e) {
762  // Old setting does not exist, do nothing
763  }
764 
765  try {
766  $value = $confManager->getLocalConfigurationValueByPath('DB/socket');
767  $removeSettings[] = 'DB/socket';
768  // Remove empty socket connects
769  if (!empty($value)) {
770  $newSettings['DB/Connections/Default/unix_socket'] = $value;
771  }
772  } catch (MissingArrayPathException $e) {
773  // Old setting does not exist, do nothing
774  }
775 
776  try {
777  $value = $confManager->getLocalConfigurationValueByPath('DB/database');
778  $removeSettings[] = 'DB/database';
779  $newSettings['DB/Connections/Default/dbname'] = $value;
780  } catch (MissingArrayPathException $e) {
781  // Old setting does not exist, do nothing
782  }
783 
784  try {
785  $value = (bool)$confManager->getLocalConfigurationValueByPath('SYS/dbClientCompress');
786  $removeSettings[] = 'SYS/dbClientCompress';
787  if ($value) {
788  $newSettings['DB/Connections/Default/driverOptions'] = [
789  'flags' => MYSQLI_CLIENT_COMPRESS,
790  ];
791  }
792  } catch (MissingArrayPathException $e) {
793  // Old setting does not exist, do nothing
794  }
795 
796  try {
797  $value = (bool)$confManager->getLocalConfigurationValueByPath('SYS/no_pconnect');
798  $removeSettings[] = 'SYS/no_pconnect';
799  if (!$value) {
800  $newSettings['DB/Connections/Default/persistentConnection'] = true;
801  }
802  } catch (MissingArrayPathException $e) {
803  // Old setting does not exist, do nothing
804  }
805 
806  try {
807  $value = $confManager->getLocalConfigurationValueByPath('SYS/setDBinit');
808  $removeSettings[] = 'SYS/setDBinit';
809  $newSettings['DB/Connections/Default/initCommands'] = $value;
810  } catch (MissingArrayPathException $e) {
811  // Old setting does not exist, do nothing
812  }
813 
814  try {
815  $confManager->getLocalConfigurationValueByPath('DB/Connections/Default/charset');
816  } catch (MissingArrayPathException $e) {
817  // If there is no charset option yet, add it.
818  $newSettings['DB/Connections/Default/charset'] = 'utf8';
819  }
820 
821  try {
822  $confManager->getLocalConfigurationValueByPath('DB/Connections/Default/driver');
823  } catch (MissingArrayPathException $e) {
824  // Use the mysqli driver by default if no value has been provided yet
825  $newSettings['DB/Connections/Default/driver'] = 'mysqli';
826  }
827 
828  // Add new settings and remove old ones
829  if (!empty($newSettings)) {
830  $confManager->setLocalConfigurationValuesByPathValuePairs($newSettings);
831  }
832  if (!empty($removeSettings)) {
833  $confManager->removeLocalConfigurationKeysByPath($removeSettings);
834  }
835 
836  // Throw redirect if something was changed
837  if (!empty($newSettings) || !empty($removeSettings)) {
839  }
840  }
841 
848  protected function ‪migrateDatabaseConnectionCharset()
849  {
850  $confManager = ‪$this->configurationManager;
851  try {
852  $driver = $confManager->getLocalConfigurationValueByPath('DB/Connections/Default/driver');
853  $charset = $confManager->getLocalConfigurationValueByPath('DB/Connections/Default/charset');
854  if (in_array($driver, ['mysqli', 'pdo_mysql', 'drizzle_pdo_mysql'], true) && $charset === 'utf-8') {
855  $confManager->setLocalConfigurationValueByPath('DB/Connections/Default/charset', 'utf8');
857  }
858  } catch (MissingArrayPathException $e) {
859  // no incompatible charset configuration found, so nothing needs to be modified
860  }
861  }
862 
868  protected function ‪migrateDatabaseDriverOptions()
869  {
870  $confManager = ‪$this->configurationManager;
871  try {
872  $options = $confManager->getLocalConfigurationValueByPath('DB/Connections/Default/driverOptions');
873  if (!is_array($options)) {
874  $confManager->setLocalConfigurationValueByPath(
875  'DB/Connections/Default/driverOptions',
876  ['flags' => (int)$options]
877  );
879  }
880  } catch (MissingArrayPathException $e) {
881  // no driver options found, nothing needs to be modified
882  }
883  }
884 
890  protected function ‪migrateLangDebug()
891  {
892  $confManager = ‪$this->configurationManager;
893  try {
894  $currentOption = $confManager->getLocalConfigurationValueByPath('BE/lang/debug');
895  // check if the current option is set and boolean
896  if (isset($currentOption) && is_bool($currentOption)) {
897  $confManager->setLocalConfigurationValueByPath('BE/languageDebug', $currentOption);
899  }
900  } catch (MissingArrayPathException $e) {
901  // no change inside the LocalConfiguration.php found, so nothing needs to be modified
902  }
903  }
904 
910  protected function ‪migrateCacheHashOptions()
911  {
912  $confManager = ‪$this->configurationManager;
913  $removeSettings = [];
914  $newSettings = [];
915 
916  try {
917  $value = $confManager->getLocalConfigurationValueByPath('FE/cHashOnlyForParameters');
918  $removeSettings[] = 'FE/cHashOnlyForParameters';
919  $newSettings['FE/cacheHash/cachedParametersWhiteList'] = ‪GeneralUtility::trimExplode(',', $value, true);
920  } catch (MissingArrayPathException $e) {
921  // Migration done already
922  }
923 
924  try {
925  $value = $confManager->getLocalConfigurationValueByPath('FE/cHashExcludedParameters');
926  $removeSettings[] = 'FE/cHashExcludedParameters';
927  $newSettings['FE/cacheHash/excludedParameters'] = ‪GeneralUtility::trimExplode(',', $value, true);
928  } catch (MissingArrayPathException $e) {
929  // Migration done already
930  }
931 
932  try {
933  $value = $confManager->getLocalConfigurationValueByPath('FE/cHashRequiredParameters');
934  $removeSettings[] = 'FE/cHashRequiredParameters';
935  $newSettings['FE/cacheHash/requireCacheHashPresenceParameters'] = ‪GeneralUtility::trimExplode(',', $value, true);
936  } catch (MissingArrayPathException $e) {
937  // Migration done already
938  }
939 
940  try {
941  $value = $confManager->getLocalConfigurationValueByPath('FE/cHashExcludedParametersIfEmpty');
942  $removeSettings[] = 'FE/cHashExcludedParametersIfEmpty';
943  if (trim($value) === '*') {
944  $newSettings['FE/cacheHash/excludeAllEmptyParameters'] = true;
945  } else {
946  $newSettings['FE/cacheHash/excludedParametersIfEmpty'] = ‪GeneralUtility::trimExplode(',', $value, true);
947  }
948  } catch (MissingArrayPathException $e) {
949  // Migration done already
950  }
951 
952  // Add new settings and remove old ones
953  if (!empty($newSettings)) {
954  $confManager->setLocalConfigurationValuesByPathValuePairs($newSettings);
955  }
956  if (!empty($removeSettings)) {
957  $confManager->removeLocalConfigurationKeysByPath($removeSettings);
958  }
959 
960  // Throw redirect if something was changed
961  if (!empty($newSettings) || !empty($removeSettings)) {
963  }
964  }
965 
971  protected function ‪migrateExceptionErrors()
972  {
973  $confManager = ‪$this->configurationManager;
974  try {
975  $currentOption = (int)$confManager->getLocalConfigurationValueByPath('SYS/exceptionalErrors');
976  // make sure E_USER_DEPRECATED is not part of the exceptionalErrors
977  if ($currentOption & E_USER_DEPRECATED) {
978  $confManager->setLocalConfigurationValueByPath('SYS/exceptionalErrors', $currentOption & ~E_USER_DEPRECATED);
980  }
981  } catch (MissingArrayPathException $e) {
982  // no change inside the LocalConfiguration.php found, so nothing needs to be modified
983  }
984  }
985 
991  protected function ‪migrateDisplayErrorsSetting()
992  {
993  $confManager = ‪$this->configurationManager;
994  try {
995  $currentOption = (int)$confManager->getLocalConfigurationValueByPath('SYS/displayErrors');
996  // make sure displayErrors is set to 2
997  if ($currentOption === 2) {
998  $confManager->setLocalConfigurationValueByPath('SYS/displayErrors', -1);
1000  }
1001  } catch (MissingArrayPathException $e) {
1002  // no change inside the LocalConfiguration.php found, so nothing needs to be modified
1003  }
1004  }
1005 
1011  protected function ‪migrateSaltedPasswordsSettings()
1012  {
1013  $confManager = ‪$this->configurationManager;
1014  $configsToRemove = [];
1015  try {
1016  $extensionConfiguration = (array)$confManager->getLocalConfigurationValueByPath('EXTENSIONS/saltedpasswords');
1017  $configsToRemove[] = 'EXTENSIONS/saltedpasswords';
1018  } catch (MissingArrayPathException $e) {
1019  $extensionConfiguration = [];
1020  }
1021  // Migration already done
1022  if (empty($extensionConfiguration)) {
1023  return;
1024  }
1025  // Upgrade to best available hash method. This is only done once since that code will no longer be reached
1026  // after first migration because extConf and EXTENSIONS array entries are gone then. Thus, a manual selection
1027  // to some different hash mechanism will not be touched again after first upgrade.
1028  // Phpass is always available, so we have some last fallback if the others don't kick in
1029  $okHashMethods = [
1030  Argon2iPasswordHash::class,
1031  Argon2idPasswordHash::class,
1032  BcryptPasswordHash::class,
1033  Pbkdf2PasswordHash::class,
1034  PhpassPasswordHash::class,
1035  ];
1036  $newMethods = [];
1037  foreach (['BE', 'FE'] as $mode) {
1038  foreach ($okHashMethods as $className) {
1040  $instance = GeneralUtility::makeInstance($className);
1041  if ($instance->isAvailable()) {
1042  $newMethods[$mode] = $className;
1043  break;
1044  }
1045  }
1046  }
1047  // We only need to write to LocalConfiguration if method is different than Argon2i from DefaultConfiguration
1048  $newConfig = [];
1049  if ($newMethods['BE'] !== Argon2iPasswordHash::class) {
1050  $newConfig['BE/passwordHashing/className'] = $newMethods['BE'];
1051  }
1052  if ($newMethods['FE'] !== Argon2iPasswordHash::class) {
1053  $newConfig['FE/passwordHashing/className'] = $newMethods['FE'];
1054  }
1055  if (!empty($newConfig)) {
1056  $confManager->setLocalConfigurationValuesByPathValuePairs($newConfig);
1057  }
1058  $confManager->removeLocalConfigurationKeysByPath($configsToRemove);
1060  }
1061 
1066  protected function ‪migrateCachingFrameworkCaches()
1067  {
1068  $confManager = ‪$this->configurationManager;
1069  try {
1070  $cacheConfigurations = (array)$confManager->getLocalConfigurationValueByPath('SYS/caching/cacheConfigurations');
1071  $newConfig = [];
1072  $hasBeenModified = false;
1073  foreach ($cacheConfigurations as $identifier => $cacheConfiguration) {
1074  if (strpos($identifier, 'cache_') === 0) {
1075  $identifier = substr($identifier, 6);
1076  $hasBeenModified = true;
1077  }
1078  $newConfig[$identifier] = $cacheConfiguration;
1079  }
1080 
1081  if ($hasBeenModified) {
1082  $confManager->setLocalConfigurationValueByPath('SYS/caching/cacheConfigurations', $newConfig);
1084  }
1085  } catch (MissingArrayPathException $e) {
1086  // no change inside the LocalConfiguration.php found, so nothing needs to be modified
1087  }
1088  }
1089 
1095  protected function ‪migrateMailSettingsToSendmail()
1096  {
1097  $confManager = ‪$this->configurationManager;
1098  try {
1099  $transport = $confManager->getLocalConfigurationValueByPath('MAIL/transport');
1100  if ($transport === 'mail') {
1101  $confManager->setLocalConfigurationValueByPath('MAIL/transport', 'sendmail');
1102  $confManager->setLocalConfigurationValueByPath('MAIL/transport_sendmail_command', (string)@ini_get('sendmail_path'));
1104  }
1105  } catch (MissingArrayPathException $e) {
1106  // no change inside the LocalConfiguration.php found, so nothing needs to be modified
1107  }
1108  }
1109 
1114  protected function ‪migrateMailSmtpEncryptSetting()
1115  {
1116  $confManager = ‪$this->configurationManager;
1117  try {
1118  $transport = $confManager->getLocalConfigurationValueByPath('MAIL/transport');
1119  if ($transport === 'smtp') {
1120  $encrypt = $confManager->getLocalConfigurationValueByPath('MAIL/transport_smtp_encrypt');
1121  if (is_string($encrypt)) {
1122  // SwiftMailer used 'tls' as identifier to connect with STARTTLS via SMTP (as usually used with port 587).
1123  // See https://github.com/swiftmailer/swiftmailer/blob/v5.4.10/lib/classes/Swift/Transport/EsmtpTransport.php#L144
1124  if ($encrypt === 'tls') {
1125  // With TYPO3 v10 the MAIL/transport_smtp_encrypt option is passed as constructor parameter $tls to
1126  // Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport
1127  // $tls = true instructs to start a SMTPS connection – that means SSL/TLS via SMTPS, not STARTTLS via SMTP.
1128  // That means symfony/mailer will use STARTTLS when $tls = false or ($tls = null with port != 465) is passed.
1129  // Actually symfony/mailer will use STARTTLS by default now.
1130  // Due to the misleading name (transport_smtp_encrypt) we avoid to set the option to false, but rather remove it.
1131  // Note: symfony/mailer provides no way to enforce STARTTLS usage, see https://github.com/symfony/symfony/commit/5b8c4676d059
1132  $confManager->removeLocalConfigurationKeysByPath(['MAIL/transport_smtp_encrypt']);
1133  } elseif ($encrypt === '') {
1134  $confManager->setLocalConfigurationValueByPath('MAIL/transport_smtp_encrypt', false);
1135  } else {
1136  $confManager->setLocalConfigurationValueByPath('MAIL/transport_smtp_encrypt', true);
1137  }
1139  }
1140  }
1141  } catch (MissingArrayPathException $e) {
1142  // no change inside the LocalConfiguration.php found, so nothing needs to be modified
1143  }
1144  }
1145 }
‪TYPO3\CMS\Core\Crypto\PasswordHashing\BcryptPasswordHash
Definition: BcryptPasswordHash.php:32
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\configureBackendLoginSecurity
‪configureBackendLoginSecurity()
Definition: SilentConfigurationUpgradeService.php:221
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateLockSslSetting
‪migrateLockSslSetting()
Definition: SilentConfigurationUpgradeService.php:705
‪TYPO3\CMS\Install\Service\Exception\ConfigurationChangedException
Definition: ConfigurationChangedException.php:26
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService
Definition: SilentConfigurationUpgradeService.php:44
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateMailSettingsToSendmail
‪migrateMailSettingsToSendmail()
Definition: SilentConfigurationUpgradeService.php:1093
‪TYPO3\CMS\Core\Utility\Exception\MissingArrayPathException
Definition: MissingArrayPathException.php:28
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\disableImageMagickDetailSettingsIfImageMagickIsDisabled
‪disableImageMagickDetailSettingsIfImageMagickIsDisabled()
Definition: SilentConfigurationUpgradeService.php:492
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateExceptionErrors
‪migrateExceptionErrors()
Definition: SilentConfigurationUpgradeService.php:969
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\generateEncryptionKeyIfNeeded
‪generateEncryptionKeyIfNeeded()
Definition: SilentConfigurationUpgradeService.php:271
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateThumbnailsPngSetting
‪migrateThumbnailsPngSetting()
Definition: SilentConfigurationUpgradeService.php:682
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\throwConfigurationChangedException
‪throwConfigurationChangedException()
Definition: SilentConfigurationUpgradeService.php:669
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\$configurationManager
‪ConfigurationManager $configurationManager
Definition: SilentConfigurationUpgradeService.php:47
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\__construct
‪__construct(ConfigurationManager $configurationManager)
Definition: SilentConfigurationUpgradeService.php:158
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateDatabaseConnectionCharset
‪migrateDatabaseConnectionCharset()
Definition: SilentConfigurationUpgradeService.php:846
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:43
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\$obsoleteLocalConfigurationSettings
‪array $obsoleteLocalConfigurationSettings
Definition: SilentConfigurationUpgradeService.php:56
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateImageProcessorSetting
‪migrateImageProcessorSetting()
Definition: SilentConfigurationUpgradeService.php:597
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\execute
‪execute()
Definition: SilentConfigurationUpgradeService.php:169
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateDatabaseConnectionSettings
‪migrateDatabaseConnectionSettings()
Definition: SilentConfigurationUpgradeService.php:724
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateCacheHashOptions
‪migrateCacheHashOptions()
Definition: SilentConfigurationUpgradeService.php:908
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Pbkdf2PasswordHash
Definition: Pbkdf2PasswordHash.php:28
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateSaltedPasswordsSettings
‪migrateSaltedPasswordsSettings()
Definition: SilentConfigurationUpgradeService.php:1009
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\transferHttpSettings
‪transferHttpSettings()
Definition: SilentConfigurationUpgradeService.php:292
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateCachingFrameworkCaches
‪migrateCachingFrameworkCaches()
Definition: SilentConfigurationUpgradeService.php:1064
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateLangDebug
‪migrateLangDebug()
Definition: SilentConfigurationUpgradeService.php:888
‪TYPO3\CMS\Core\Crypto\PasswordHashing\PhpassPasswordHash
Definition: PhpassPasswordHash.php:35
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static string[] trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:1059
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\setImageMagickDetailSettings
‪setImageMagickDetailSettings()
Definition: SilentConfigurationUpgradeService.php:555
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateDatabaseDriverOptions
‪migrateDatabaseDriverOptions()
Definition: SilentConfigurationUpgradeService.php:866
‪TYPO3\CMS\Core\Crypto\Random
Definition: Random.php:24
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateDisplayErrorsSetting
‪migrateDisplayErrorsSetting()
Definition: SilentConfigurationUpgradeService.php:989
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\removeObsoleteLocalConfigurationSettings
‪removeObsoleteLocalConfigurationSettings()
Definition: SilentConfigurationUpgradeService.php:204
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashInterface
Definition: PasswordHashInterface.php:25
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isLoaded
‪static bool isLoaded($key)
Definition: ExtensionManagementUtility.php:114
‪TYPO3\CMS\Install\Service
Definition: ClearCacheService.php:16
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2idPasswordHash
Definition: Argon2idPasswordHash.php:31
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2iPasswordHash
Definition: Argon2iPasswordHash.php:31
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateMailSmtpEncryptSetting
‪migrateMailSmtpEncryptSetting()
Definition: SilentConfigurationUpgradeService.php:1112
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\configureFrontendLoginSecurity
‪configureFrontendLoginSecurity()
Definition: SilentConfigurationUpgradeService.php:249