‪TYPO3CMS  11.5
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;
29 
43 {
47  protected ‪$configurationManager;
48 
58  // #72400
59  'BE/spriteIconGenerator_handler',
60  // #72417
61  'SYS/lockingMode',
62  // #72473
63  'FE/secureFormmail',
64  'FE/strictFormmail',
65  'FE/formmailMaxAttachmentSize',
66  // #72337
67  'SYS/t3lib_cs_utils',
68  'SYS/t3lib_cs_convMethod',
69  // #72604
70  'SYS/maxFileNameLength',
71  // #72602
72  'BE/unzip_path',
73  // #72615
74  'BE/notificationPrefix',
75  // #72616
76  'BE/XCLASS',
77  'FE/XCLASS',
78  // #43085
79  'GFX/image_processing',
80  // #70056
81  'SYS/curlUse',
82  'SYS/curlProxyNTLM',
83  'SYS/curlProxyServer',
84  'SYS/curlProxyTunnel',
85  'SYS/curlProxyUserPass',
86  'SYS/curlTimeout',
87  // #75355
88  'BE/niceFlexFormXMLtags',
89  'BE/compactFlexFormXML',
90  // #75625
91  'SYS/clearCacheSystem',
92  // #77411
93  'SYS/caching/cacheConfigurations/extbase_typo3dbbackend_tablecolumns',
94  // #77460
95  'SYS/caching/cacheConfigurations/extbase_typo3dbbackend_queries',
96  // #79513
97  'FE/lockHashKeyWords',
98  'BE/lockHashKeyWords',
99  // #78835
100  'SYS/cookieHttpOnly',
101  // #71095
102  'BE/lang',
103  // #80050
104  'FE/cHashIncludePageId',
105  // #80711
106  'FE/noPHPscriptInclude',
107  'FE/maxSessionDataSize',
108  // #82162
109  'SYS/enable_errorDLOG',
110  'SYS/enable_exceptionDLOG',
111  // #82377
112  'EXT/allowSystemInstall',
113  // #82421
114  'SYS/sqlDebug',
115  'SYS/no_pconnect',
116  'SYS/setDBinit',
117  'SYS/dbClientCompress',
118  // #82430
119  'SYS/syslogErrorReporting',
120  // #82639
121  'SYS/enable_DLOG',
122  'SC_OPTIONS/t3lib/class.t3lib_userauth.php/writeDevLog',
123  'SC_OPTIONS/t3lib/class.t3lib_userauth.php/writeDevLogBE',
124  'SC_OPTIONS/t3lib/class.t3lib_userauth.php/writeDevLogFE',
125  // #82438
126  'SYS/enableDeprecationLog',
127  // #82680
128  'GFX/png_truecolor',
129  // #82803
130  'FE/content_doktypes',
131  // #83081
132  'BE/fileExtensions',
133  // #83768
134  'SYS/doNotCheckReferer',
135  // #83878
136  'SYS/isInitialInstallationInProgress',
137  'SYS/isInitialDatabaseImportDone',
138  // #84810
139  'BE/explicitConfirmationOfTranslation',
140  // #87482
141  'EXT/extConf',
142  // #87767
143  'SYS/recursiveDomainSearch',
144  // #88376
145  'FE/pageNotFound_handling',
146  'FE/pageNotFound_handling_statheader',
147  'FE/pageNotFound_handling_accessdeniedheader',
148  'FE/pageUnavailable_handling',
149  'FE/pageUnavailable_handling_statheader',
150  // #88458
151  'FE/get_url_id_token',
152  // #88500
153  'BE/RTE_imageStorageDir',
154  // #89645
155  'SYS/systemLog',
156  'SYS/systemLogLevel',
157  // #91974
158  'FE/IPmaskMountGroups',
159  // #87301
160  'SYS/cookieSecure',
161  // #92940
162  'BE/lockBeUserToDBmounts',
163  // #92941
164  'BE/enabledBeUserIPLock',
165  // #94312
166  'BE/loginSecurityLevel',
167  'FE/loginSecurityLevel',
168  // #94871
169  'SYS/features/form.legacyUploadMimeTypes',
170  ];
171 
172  public function ‪__construct(ConfigurationManager ‪$configurationManager)
173  {
174  $this->configurationManager = ‪$configurationManager;
175  }
176 
183  public function ‪execute()
184  {
187  $this->‪transferHttpSettings();
191  $this->‪migrateLockSslSetting();
195  $this->‪migrateLangDebug();
197  $this->‪migrateExceptionErrors();
203  $this->‪migrateExplicitADmode();
204 
205  // Should run at the end to prevent obsolete settings are removed before migration
207  }
208 
218  {
219  $removed = $this->configurationManager->removeLocalConfigurationKeysByPath($this->obsoleteLocalConfigurationSettings);
220 
221  // If something was changed: Trigger a reload to have new values in next request
222  if ($removed) {
224  }
225  }
226 
235  protected function ‪generateEncryptionKeyIfNeeded()
236  {
237  try {
238  $currentValue = $this->configurationManager->getLocalConfigurationValueByPath('SYS/encryptionKey');
239  } catch (MissingArrayPathException $e) {
240  // If an exception is thrown, the value is not set in LocalConfiguration
241  $currentValue = '';
242  }
243 
244  if (empty($currentValue)) {
245  $randomKey = GeneralUtility::makeInstance(Random::class)->generateRandomHexString(96);
246  $this->configurationManager->setLocalConfigurationValueByPath('SYS/encryptionKey', $randomKey);
248  }
249  }
250 
256  protected function ‪transferHttpSettings()
257  {
258  $changed = false;
259  $newParameters = [];
260  $obsoleteParameters = [];
261 
262  // Remove / migrate options to new options
263  try {
264  // Check if the adapter option is set, if so, set it to the parameters that are obsolete
265  $this->configurationManager->getLocalConfigurationValueByPath('HTTP/adapter');
266  $obsoleteParameters[] = 'HTTP/adapter';
267  } catch (MissingArrayPathException $e) {
268  // Migration done already
269  }
270  try {
271  $newParameters['HTTP/version'] = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/protocol_version');
272  $obsoleteParameters[] = 'HTTP/protocol_version';
273  } catch (MissingArrayPathException $e) {
274  // Migration done already
275  }
276  try {
277  $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_verify_host');
278  $obsoleteParameters[] = 'HTTP/ssl_verify_host';
279  } catch (MissingArrayPathException $e) {
280  // Migration done already
281  }
282  try {
283  $legacyUserAgent = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/userAgent');
284  $newParameters['HTTP/headers/User-Agent'] = $legacyUserAgent;
285  $obsoleteParameters[] = 'HTTP/userAgent';
286  } catch (MissingArrayPathException $e) {
287  // Migration done already
288  }
289 
290  // Redirects
291  try {
292  $legacyFollowRedirects = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/follow_redirects');
293  $obsoleteParameters[] = 'HTTP/follow_redirects';
294  } catch (MissingArrayPathException $e) {
295  $legacyFollowRedirects = '';
296  }
297  try {
298  $legacyMaximumRedirects = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/max_redirects');
299  $obsoleteParameters[] = 'HTTP/max_redirects';
300  } catch (MissingArrayPathException $e) {
301  $legacyMaximumRedirects = '';
302  }
303  try {
304  $legacyStrictRedirects = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/strict_redirects');
305  $obsoleteParameters[] = 'HTTP/strict_redirects';
306  } catch (MissingArrayPathException $e) {
307  $legacyStrictRedirects = '';
308  }
309 
310  // Check if redirects have been disabled
311  if ($legacyFollowRedirects !== '' && (bool)$legacyFollowRedirects === false) {
312  $newParameters['HTTP/allow_redirects'] = false;
313  } elseif ($legacyMaximumRedirects !== '' || $legacyStrictRedirects !== '') {
314  $newParameters['HTTP/allow_redirects'] = [];
315  if ($legacyMaximumRedirects !== '' && (int)$legacyMaximumRedirects !== 5) {
316  $newParameters['HTTP/allow_redirects']['max'] = (int)$legacyMaximumRedirects;
317  }
318  if ($legacyStrictRedirects !== '' && (bool)$legacyStrictRedirects === true) {
319  $newParameters['HTTP/allow_redirects']['strict'] = true;
320  }
321  // defaults are used, no need to set the option in LocalConfiguration.php
322  if (empty($newParameters['HTTP/allow_redirects'])) {
323  unset($newParameters['HTTP/allow_redirects']);
324  }
325  }
326 
327  // Migrate Proxy settings
328  try {
329  // Currently without protocol or port
330  $legacyProxyHost = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_host');
331  $obsoleteParameters[] = 'HTTP/proxy_host';
332  } catch (MissingArrayPathException $e) {
333  $legacyProxyHost = '';
334  }
335  try {
336  $legacyProxyPort = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_port');
337  $obsoleteParameters[] = 'HTTP/proxy_port';
338  } catch (MissingArrayPathException $e) {
339  $legacyProxyPort = '';
340  }
341  try {
342  $legacyProxyUser = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_user');
343  $obsoleteParameters[] = 'HTTP/proxy_user';
344  } catch (MissingArrayPathException $e) {
345  $legacyProxyUser = '';
346  }
347  try {
348  $legacyProxyPassword = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_password');
349  $obsoleteParameters[] = 'HTTP/proxy_password';
350  } catch (MissingArrayPathException $e) {
351  $legacyProxyPassword = '';
352  }
353  // Auth Scheme: Basic, digest etc.
354  try {
355  $legacyProxyAuthScheme = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/proxy_auth_scheme');
356  $obsoleteParameters[] = 'HTTP/proxy_auth_scheme';
357  } catch (MissingArrayPathException $e) {
358  $legacyProxyAuthScheme = '';
359  }
360 
361  if ($legacyProxyHost !== '') {
362  $proxy = 'http://';
363  if ($legacyProxyAuthScheme !== '' && $legacyProxyUser !== '' && $legacyProxyPassword !== '') {
364  $proxy .= $legacyProxyUser . ':' . $legacyProxyPassword . '@';
365  }
366  $proxy .= $legacyProxyHost;
367  if ($legacyProxyPort !== '') {
368  $proxy .= ':' . $legacyProxyPort;
369  }
370  $newParameters['HTTP/proxy'] = $proxy;
371  }
372 
373  // Verify peers
374  // see http://docs.guzzlephp.org/en/latest/request-options.html#verify
375  try {
376  $legacySslVerifyPeer = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_verify_peer');
377  $obsoleteParameters[] = 'HTTP/ssl_verify_peer';
378  } catch (MissingArrayPathException $e) {
379  $legacySslVerifyPeer = '';
380  }
381 
382  // Directory holding multiple Certificate Authority files
383  try {
384  $legacySslCaPath = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_capath');
385  $obsoleteParameters[] = 'HTTP/ssl_capath';
386  } catch (MissingArrayPathException $e) {
387  $legacySslCaPath = '';
388  }
389  // Certificate Authority file to verify the peer with (use when ssl_verify_peer is TRUE)
390  try {
391  $legacySslCaFile = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_cafile');
392  $obsoleteParameters[] = 'HTTP/ssl_cafile';
393  } catch (MissingArrayPathException $e) {
394  $legacySslCaFile = '';
395  }
396  if ($legacySslVerifyPeer !== '') {
397  if ($legacySslCaFile !== '' && $legacySslCaPath !== '') {
398  $newParameters['HTTP/verify'] = $legacySslCaPath . $legacySslCaFile;
399  } elseif ((bool)$legacySslVerifyPeer === false) {
400  $newParameters['HTTP/verify'] = false;
401  }
402  }
403 
404  // SSL Key + Passphrase
405  // Name of a file containing local certificate
406  try {
407  $legacySslLocalCert = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_local_cert');
408  $obsoleteParameters[] = 'HTTP/ssl_local_cert';
409  } catch (MissingArrayPathException $e) {
410  $legacySslLocalCert = '';
411  }
412 
413  // Passphrase with which local certificate was encoded
414  try {
415  $legacySslPassphrase = $this->configurationManager->getLocalConfigurationValueByPath('HTTP/ssl_passphrase');
416  $obsoleteParameters[] = 'HTTP/ssl_passphrase';
417  } catch (MissingArrayPathException $e) {
418  $legacySslPassphrase = '';
419  }
420 
421  if ($legacySslLocalCert !== '') {
422  if ($legacySslPassphrase !== '') {
423  $newParameters['HTTP/ssl_key'] = [
424  $legacySslLocalCert,
425  $legacySslPassphrase,
426  ];
427  } else {
428  $newParameters['HTTP/ssl_key'] = $legacySslLocalCert;
429  }
430  }
431 
432  // Update the LocalConfiguration file if obsolete parameters or new parameters are set
433  if (!empty($obsoleteParameters)) {
434  $this->configurationManager->removeLocalConfigurationKeysByPath($obsoleteParameters);
435  $changed = true;
436  }
437  if (!empty($newParameters)) {
438  $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($newParameters);
439  $changed = true;
440  }
441  if ($changed) {
443  }
444  }
445 
457  {
458  $changedValues = [];
459  try {
460  $currentEnabledValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_enabled');
461  } catch (MissingArrayPathException $e) {
462  $currentEnabledValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_enabled');
463  }
464 
465  try {
466  $currentPathValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_path');
467  } catch (MissingArrayPathException $e) {
468  $currentPathValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_path');
469  }
470 
471  try {
472  $currentPathLzwValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_path_lzw');
473  } catch (MissingArrayPathException $e) {
474  $currentPathLzwValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_path_lzw');
475  }
476 
477  try {
478  $currentImageFileExtValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/imagefile_ext');
479  } catch (MissingArrayPathException $e) {
480  $currentImageFileExtValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/imagefile_ext');
481  }
482 
483  try {
484  $currentThumbnailsValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/thumbnails');
485  } catch (MissingArrayPathException $e) {
486  $currentThumbnailsValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/thumbnails');
487  }
488 
489  if (!$currentEnabledValue) {
490  if ($currentPathValue != '') {
491  $changedValues['GFX/processor_path'] = '';
492  }
493  if ($currentPathLzwValue != '') {
494  $changedValues['GFX/processor_path_lzw'] = '';
495  }
496  if ($currentImageFileExtValue !== 'gif,jpg,jpeg,png') {
497  $changedValues['GFX/imagefile_ext'] = 'gif,jpg,jpeg,png';
498  }
499  if ($currentThumbnailsValue != 0) {
500  $changedValues['GFX/thumbnails'] = 0;
501  }
502  }
503  if (!empty($changedValues)) {
504  $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($changedValues);
506  }
507  }
508 
519  protected function ‪setImageMagickDetailSettings()
520  {
521  $changedValues = [];
522  try {
523  $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor');
524  } catch (MissingArrayPathException $e) {
525  $currentProcessorValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor');
526  }
527 
528  try {
529  $currentProcessorMaskValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_allowTemporaryMasksAsPng');
530  } catch (MissingArrayPathException $e) {
531  $currentProcessorMaskValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_allowTemporaryMasksAsPng');
532  }
533 
534  try {
535  $currentProcessorEffectsValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/processor_effects');
536  } catch (MissingArrayPathException $e) {
537  $currentProcessorEffectsValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/processor_effects');
538  }
539 
540  if ((string)$currentProcessorValue !== '') {
541  if (!is_bool($currentProcessorEffectsValue)) {
542  $changedValues['GFX/processor_effects'] = (int)$currentProcessorEffectsValue > 0;
543  }
544 
545  if ($currentProcessorMaskValue != 0) {
546  $changedValues['GFX/processor_allowTemporaryMasksAsPng'] = 0;
547  }
548  }
549  if (!empty($changedValues)) {
550  $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($changedValues);
552  }
553  }
554 
561  protected function ‪migrateImageProcessorSetting()
562  {
563  $changedSettings = [];
564  $settingsToRename = [
565  'GFX/im' => 'GFX/processor_enabled',
566  'GFX/im_version_5' => 'GFX/processor',
567  'GFX/im_v5effects' => 'GFX/processor_effects',
568  'GFX/im_path' => 'GFX/processor_path',
569  'GFX/im_path_lzw' => 'GFX/processor_path_lzw',
570  'GFX/im_mask_temp_ext_gif' => 'GFX/processor_allowTemporaryMasksAsPng',
571  'GFX/im_noScaleUp' => 'GFX/processor_allowUpscaling',
572  'GFX/im_noFramePrepended' => 'GFX/processor_allowFrameSelection',
573  'GFX/im_stripProfileCommand' => 'GFX/processor_stripColorProfileCommand',
574  'GFX/im_useStripProfileByDefault' => 'GFX/processor_stripColorProfileByDefault',
575  'GFX/colorspace' => 'GFX/processor_colorspace',
576  ];
577 
578  foreach ($settingsToRename as $oldPath => $newPath) {
579  try {
580  $value = $this->configurationManager->getLocalConfigurationValueByPath($oldPath);
581  $this->configurationManager->setLocalConfigurationValueByPath($newPath, $value);
582  $changedSettings[$oldPath] = true;
583  } catch (MissingArrayPathException $e) {
584  // If an exception is thrown, the value is not set in LocalConfiguration
585  $changedSettings[$oldPath] = false;
586  }
587  }
588 
589  if (!empty($changedSettings['GFX/im_version_5'])) {
590  $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_version_5');
591  $newProcessorValue = $currentProcessorValue === 'gm' ? 'GraphicsMagick' : 'ImageMagick';
592  $this->configurationManager->setLocalConfigurationValueByPath('GFX/processor', $newProcessorValue);
593  }
594 
595  if (!empty($changedSettings['GFX/im_noScaleUp'])) {
596  $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_noScaleUp');
597  $newProcessorValue = !$currentProcessorValue;
598  $this->configurationManager->setLocalConfigurationValueByPath(
599  'GFX/processor_allowUpscaling',
600  $newProcessorValue
601  );
602  }
603 
604  if (!empty($changedSettings['GFX/im_noFramePrepended'])) {
605  $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_noFramePrepended');
606  $newProcessorValue = !$currentProcessorValue;
607  $this->configurationManager->setLocalConfigurationValueByPath(
608  'GFX/processor_allowFrameSelection',
609  $newProcessorValue
610  );
611  }
612 
613  if (!empty($changedSettings['GFX/im_mask_temp_ext_gif'])) {
614  $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_mask_temp_ext_gif');
615  $newProcessorValue = !$currentProcessorValue;
616  $this->configurationManager->setLocalConfigurationValueByPath(
617  'GFX/processor_allowTemporaryMasksAsPng',
618  $newProcessorValue
619  );
620  }
621 
622  if (!empty(array_filter($changedSettings))) {
623  $this->configurationManager->removeLocalConfigurationKeysByPath(array_keys($changedSettings));
625  }
626  }
627 
633  protected function ‪throwConfigurationChangedException()
634  {
635  throw new ConfigurationChangedException(
636  'Configuration updated, reload needed',
637  1379024938
638  );
639  }
640 
646  protected function ‪migrateThumbnailsPngSetting()
647  {
648  $changedValues = [];
649  try {
650  $currentThumbnailsPngValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/thumbnails_png');
651  } catch (MissingArrayPathException $e) {
652  $currentThumbnailsPngValue = $this->configurationManager->getDefaultConfigurationValueByPath('GFX/thumbnails_png');
653  }
654 
655  if (is_int($currentThumbnailsPngValue) && $currentThumbnailsPngValue > 0) {
656  $changedValues['GFX/thumbnails_png'] = true;
657  }
658  if (!empty($changedValues)) {
659  $this->configurationManager->setLocalConfigurationValuesByPathValuePairs($changedValues);
661  }
662  }
663 
669  protected function ‪migrateLockSslSetting()
670  {
671  try {
672  $currentOption = $this->configurationManager->getLocalConfigurationValueByPath('BE/lockSSL');
673  // check if the current option is an integer/string and if it is active
674  if (!is_bool($currentOption) && (int)$currentOption > 0) {
675  $this->configurationManager->setLocalConfigurationValueByPath('BE/lockSSL', true);
677  }
678  } catch (MissingArrayPathException $e) {
679  // no change inside the LocalConfiguration.php found, so nothing needs to be modified
680  }
681  }
682 
688  protected function ‪migrateDatabaseConnectionSettings()
689  {
690  $confManager = ‪$this->configurationManager;
691 
692  $newSettings = [];
693  $removeSettings = [];
694 
695  try {
696  $value = $confManager->getLocalConfigurationValueByPath('DB/username');
697  $removeSettings[] = 'DB/username';
698  $newSettings['DB/Connections/Default/user'] = $value;
699  } catch (MissingArrayPathException $e) {
700  // Old setting does not exist, do nothing
701  }
702 
703  try {
704  $value = $confManager->getLocalConfigurationValueByPath('DB/password');
705  $removeSettings[] = 'DB/password';
706  $newSettings['DB/Connections/Default/password'] = $value;
707  } catch (MissingArrayPathException $e) {
708  // Old setting does not exist, do nothing
709  }
710 
711  try {
712  $value = $confManager->getLocalConfigurationValueByPath('DB/host');
713  $removeSettings[] = 'DB/host';
714  $newSettings['DB/Connections/Default/host'] = $value;
715  } catch (MissingArrayPathException $e) {
716  // Old setting does not exist, do nothing
717  }
718 
719  try {
720  $value = $confManager->getLocalConfigurationValueByPath('DB/port');
721  $removeSettings[] = 'DB/port';
722  $newSettings['DB/Connections/Default/port'] = $value;
723  } catch (MissingArrayPathException $e) {
724  // Old setting does not exist, do nothing
725  }
726 
727  try {
728  $value = $confManager->getLocalConfigurationValueByPath('DB/socket');
729  $removeSettings[] = 'DB/socket';
730  // Remove empty socket connects
731  if (!empty($value)) {
732  $newSettings['DB/Connections/Default/unix_socket'] = $value;
733  }
734  } catch (MissingArrayPathException $e) {
735  // Old setting does not exist, do nothing
736  }
737 
738  try {
739  $value = $confManager->getLocalConfigurationValueByPath('DB/database');
740  $removeSettings[] = 'DB/database';
741  $newSettings['DB/Connections/Default/dbname'] = $value;
742  } catch (MissingArrayPathException $e) {
743  // Old setting does not exist, do nothing
744  }
745 
746  try {
747  $value = (bool)$confManager->getLocalConfigurationValueByPath('SYS/dbClientCompress');
748  $removeSettings[] = 'SYS/dbClientCompress';
749  if ($value) {
750  $newSettings['DB/Connections/Default/driverOptions'] = [
751  'flags' => MYSQLI_CLIENT_COMPRESS,
752  ];
753  }
754  } catch (MissingArrayPathException $e) {
755  // Old setting does not exist, do nothing
756  }
757 
758  try {
759  $value = (bool)$confManager->getLocalConfigurationValueByPath('SYS/no_pconnect');
760  $removeSettings[] = 'SYS/no_pconnect';
761  if (!$value) {
762  $newSettings['DB/Connections/Default/persistentConnection'] = true;
763  }
764  } catch (MissingArrayPathException $e) {
765  // Old setting does not exist, do nothing
766  }
767 
768  try {
769  $value = $confManager->getLocalConfigurationValueByPath('SYS/setDBinit');
770  $removeSettings[] = 'SYS/setDBinit';
771  $newSettings['DB/Connections/Default/initCommands'] = $value;
772  } catch (MissingArrayPathException $e) {
773  // Old setting does not exist, do nothing
774  }
775 
776  try {
777  $confManager->getLocalConfigurationValueByPath('DB/Connections/Default/charset');
778  } catch (MissingArrayPathException $e) {
779  // If there is no charset option yet, add it.
780  $newSettings['DB/Connections/Default/charset'] = 'utf8';
781  }
782 
783  try {
784  $confManager->getLocalConfigurationValueByPath('DB/Connections/Default/driver');
785  } catch (MissingArrayPathException $e) {
786  // Use the mysqli driver by default if no value has been provided yet
787  $newSettings['DB/Connections/Default/driver'] = 'mysqli';
788  }
789 
790  // Add new settings and remove old ones
791  if (!empty($newSettings)) {
792  $confManager->setLocalConfigurationValuesByPathValuePairs($newSettings);
793  }
794  if (!empty($removeSettings)) {
795  $confManager->removeLocalConfigurationKeysByPath($removeSettings);
796  }
797 
798  // Throw redirect if something was changed
799  if (!empty($newSettings) || !empty($removeSettings)) {
801  }
802  }
803 
810  protected function ‪migrateDatabaseConnectionCharset()
811  {
812  $confManager = ‪$this->configurationManager;
813  try {
814  $driver = $confManager->getLocalConfigurationValueByPath('DB/Connections/Default/driver');
815  $charset = $confManager->getLocalConfigurationValueByPath('DB/Connections/Default/charset');
816  if (in_array($driver, ['mysqli', 'pdo_mysql', 'drizzle_pdo_mysql'], true) && $charset === 'utf-8') {
817  $confManager->setLocalConfigurationValueByPath('DB/Connections/Default/charset', 'utf8');
819  }
820  } catch (MissingArrayPathException $e) {
821  // no incompatible charset configuration found, so nothing needs to be modified
822  }
823  }
824 
830  protected function ‪migrateDatabaseDriverOptions()
831  {
832  $confManager = ‪$this->configurationManager;
833  try {
834  $options = $confManager->getLocalConfigurationValueByPath('DB/Connections/Default/driverOptions');
835  if (!is_array($options)) {
836  $confManager->setLocalConfigurationValueByPath(
837  'DB/Connections/Default/driverOptions',
838  ['flags' => (int)$options]
839  );
841  }
842  } catch (MissingArrayPathException $e) {
843  // no driver options found, nothing needs to be modified
844  }
845  }
846 
852  protected function ‪migrateLangDebug()
853  {
854  $confManager = ‪$this->configurationManager;
855  try {
856  $currentOption = $confManager->getLocalConfigurationValueByPath('BE/lang/debug');
857  // check if the current option is set and boolean
858  if (isset($currentOption) && is_bool($currentOption)) {
859  $confManager->setLocalConfigurationValueByPath('BE/languageDebug', $currentOption);
861  }
862  } catch (MissingArrayPathException $e) {
863  // no change inside the LocalConfiguration.php found, so nothing needs to be modified
864  }
865  }
866 
872  protected function ‪migrateCacheHashOptions()
873  {
874  $confManager = ‪$this->configurationManager;
875  $removeSettings = [];
876  $newSettings = [];
877 
878  try {
879  $value = $confManager->getLocalConfigurationValueByPath('FE/cHashOnlyForParameters');
880  $removeSettings[] = 'FE/cHashOnlyForParameters';
881  $newSettings['FE/cacheHash/cachedParametersWhiteList'] = ‪GeneralUtility::trimExplode(',', $value, true);
882  } catch (MissingArrayPathException $e) {
883  // Migration done already
884  }
885 
886  try {
887  $value = $confManager->getLocalConfigurationValueByPath('FE/cHashExcludedParameters');
888  $removeSettings[] = 'FE/cHashExcludedParameters';
889  $newSettings['FE/cacheHash/excludedParameters'] = ‪GeneralUtility::trimExplode(',', $value, true);
890  } catch (MissingArrayPathException $e) {
891  // Migration done already
892  }
893 
894  try {
895  $value = $confManager->getLocalConfigurationValueByPath('FE/cHashRequiredParameters');
896  $removeSettings[] = 'FE/cHashRequiredParameters';
897  $newSettings['FE/cacheHash/requireCacheHashPresenceParameters'] = ‪GeneralUtility::trimExplode(',', $value, true);
898  } catch (MissingArrayPathException $e) {
899  // Migration done already
900  }
901 
902  try {
903  $value = $confManager->getLocalConfigurationValueByPath('FE/cHashExcludedParametersIfEmpty');
904  $removeSettings[] = 'FE/cHashExcludedParametersIfEmpty';
905  if (trim($value) === '*') {
906  $newSettings['FE/cacheHash/excludeAllEmptyParameters'] = true;
907  } else {
908  $newSettings['FE/cacheHash/excludedParametersIfEmpty'] = ‪GeneralUtility::trimExplode(',', $value, true);
909  }
910  } catch (MissingArrayPathException $e) {
911  // Migration done already
912  }
913 
914  // Add new settings and remove old ones
915  if (!empty($newSettings)) {
916  $confManager->setLocalConfigurationValuesByPathValuePairs($newSettings);
917  }
918  if (!empty($removeSettings)) {
919  $confManager->removeLocalConfigurationKeysByPath($removeSettings);
920  }
921 
922  // Throw redirect if something was changed
923  if (!empty($newSettings) || !empty($removeSettings)) {
925  }
926  }
927 
933  protected function ‪migrateExceptionErrors()
934  {
935  $confManager = ‪$this->configurationManager;
936  try {
937  $currentOption = (int)$confManager->getLocalConfigurationValueByPath('SYS/exceptionalErrors');
938  // make sure E_USER_DEPRECATED is not part of the exceptionalErrors
939  if ($currentOption & E_USER_DEPRECATED) {
940  $confManager->setLocalConfigurationValueByPath('SYS/exceptionalErrors', $currentOption & ~E_USER_DEPRECATED);
942  }
943  } catch (MissingArrayPathException $e) {
944  // no change inside the LocalConfiguration.php found, so nothing needs to be modified
945  }
946  }
947 
953  protected function ‪migrateDisplayErrorsSetting()
954  {
955  $confManager = ‪$this->configurationManager;
956  try {
957  $currentOption = (int)$confManager->getLocalConfigurationValueByPath('SYS/displayErrors');
958  // make sure displayErrors is set to 2
959  if ($currentOption === 2) {
960  $confManager->setLocalConfigurationValueByPath('SYS/displayErrors', -1);
962  }
963  } catch (MissingArrayPathException $e) {
964  // no change inside the LocalConfiguration.php found, so nothing needs to be modified
965  }
966  }
967 
973  protected function ‪migrateSaltedPasswordsSettings()
974  {
975  $confManager = ‪$this->configurationManager;
976  $configsToRemove = [];
977  try {
978  $extensionConfiguration = (array)$confManager->getLocalConfigurationValueByPath('EXTENSIONS/saltedpasswords');
979  $configsToRemove[] = 'EXTENSIONS/saltedpasswords';
980  } catch (MissingArrayPathException $e) {
981  $extensionConfiguration = [];
982  }
983  // Migration already done
984  if (empty($extensionConfiguration)) {
985  return;
986  }
987  // Upgrade to best available hash method. This is only done once since that code will no longer be reached
988  // after first migration because extConf and EXTENSIONS array entries are gone then. Thus, a manual selection
989  // to some different hash mechanism will not be touched again after first upgrade.
990  // Phpass is always available, so we have some last fallback if the others don't kick in
991  $okHashMethods = [
992  Argon2iPasswordHash::class,
993  Argon2idPasswordHash::class,
994  BcryptPasswordHash::class,
995  Pbkdf2PasswordHash::class,
996  PhpassPasswordHash::class,
997  ];
998  $newMethods = [];
999  foreach (['BE', 'FE'] as $mode) {
1000  foreach ($okHashMethods as $className) {
1002  $instance = GeneralUtility::makeInstance($className);
1003  if ($instance->isAvailable()) {
1004  $newMethods[$mode] = $className;
1005  break;
1006  }
1007  }
1008  }
1009  // We only need to write to LocalConfiguration if method is different than Argon2i from DefaultConfiguration
1010  $newConfig = [];
1011  if ($newMethods['BE'] !== Argon2iPasswordHash::class) {
1012  $newConfig['BE/passwordHashing/className'] = $newMethods['BE'];
1013  }
1014  if ($newMethods['FE'] !== Argon2iPasswordHash::class) {
1015  $newConfig['FE/passwordHashing/className'] = $newMethods['FE'];
1016  }
1017  if (!empty($newConfig)) {
1018  $confManager->setLocalConfigurationValuesByPathValuePairs($newConfig);
1019  }
1020  $confManager->removeLocalConfigurationKeysByPath($configsToRemove);
1022  }
1023 
1028  protected function ‪migrateCachingFrameworkCaches()
1029  {
1030  $confManager = ‪$this->configurationManager;
1031  try {
1032  $cacheConfigurations = (array)$confManager->getLocalConfigurationValueByPath('SYS/caching/cacheConfigurations');
1033  $newConfig = [];
1034  $hasBeenModified = false;
1035  foreach ($cacheConfigurations as $identifier => $cacheConfiguration) {
1036  if (strpos($identifier, 'cache_') === 0) {
1037  $identifier = substr($identifier, 6);
1038  $hasBeenModified = true;
1039  }
1040  $newConfig[$identifier] = $cacheConfiguration;
1041  }
1042 
1043  if ($hasBeenModified) {
1044  $confManager->setLocalConfigurationValueByPath('SYS/caching/cacheConfigurations', $newConfig);
1046  }
1047  } catch (MissingArrayPathException $e) {
1048  // no change inside the LocalConfiguration.php found, so nothing needs to be modified
1049  }
1050  }
1051 
1057  protected function ‪migrateMailSettingsToSendmail()
1058  {
1059  $confManager = ‪$this->configurationManager;
1060  try {
1061  $transport = $confManager->getLocalConfigurationValueByPath('MAIL/transport');
1062  if ($transport === 'mail') {
1063  $confManager->setLocalConfigurationValueByPath('MAIL/transport', 'sendmail');
1064  $confManager->setLocalConfigurationValueByPath('MAIL/transport_sendmail_command', (string)@ini_get('sendmail_path'));
1066  }
1067  } catch (MissingArrayPathException $e) {
1068  // no change inside the LocalConfiguration.php found, so nothing needs to be modified
1069  }
1070  }
1071 
1076  protected function ‪migrateMailSmtpEncryptSetting()
1077  {
1078  $confManager = ‪$this->configurationManager;
1079  try {
1080  $transport = $confManager->getLocalConfigurationValueByPath('MAIL/transport');
1081  if ($transport === 'smtp') {
1082  $encrypt = $confManager->getLocalConfigurationValueByPath('MAIL/transport_smtp_encrypt');
1083  if (is_string($encrypt)) {
1084  // SwiftMailer used 'tls' as identifier to connect with STARTTLS via SMTP (as usually used with port 587).
1085  // See https://github.com/swiftmailer/swiftmailer/blob/v5.4.10/lib/classes/Swift/Transport/EsmtpTransport.php#L144
1086  if ($encrypt === 'tls') {
1087  // With TYPO3 v10 the MAIL/transport_smtp_encrypt option is passed as constructor parameter $tls to
1088  // Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport
1089  // $tls = true instructs to start a SMTPS connection – that means SSL/TLS via SMTPS, not STARTTLS via SMTP.
1090  // That means symfony/mailer will use STARTTLS when $tls = false or ($tls = null with port != 465) is passed.
1091  // Actually symfony/mailer will use STARTTLS by default now.
1092  // Due to the misleading name (transport_smtp_encrypt) we avoid to set the option to false, but rather remove it.
1093  // Note: symfony/mailer provides no way to enforce STARTTLS usage, see https://github.com/symfony/symfony/commit/5b8c4676d059
1094  $confManager->removeLocalConfigurationKeysByPath(['MAIL/transport_smtp_encrypt']);
1095  } elseif ($encrypt === '') {
1096  $confManager->setLocalConfigurationValueByPath('MAIL/transport_smtp_encrypt', false);
1097  } else {
1098  $confManager->setLocalConfigurationValueByPath('MAIL/transport_smtp_encrypt', true);
1099  }
1101  }
1102  }
1103  } catch (MissingArrayPathException $e) {
1104  // no change inside the LocalConfiguration.php found, so nothing needs to be modified
1105  }
1106  }
1107 
1115  protected function ‪migrateExplicitADmode(): void
1116  {
1117  $confManager = ‪$this->configurationManager;
1118  try {
1119  // If set in LocalConfiguration, just keep it:
1120  // If set to 'explicitAllow', which is what we want and prefer, it is in line with DefaultConfiguration,
1121  // but we still do not remove it, since a second call to the silent upgrade would then write 'explicitDeny'.
1122  // If set to 'explicitDeny', we also simply leave it as it, since this may have been written explicitly
1123  // already by a previous silent upgrade run.
1124  // If set to something else, we don't care about this here.
1125  $confManager->getLocalConfigurationValueByPath('BE/explicitADmode');
1126  } catch (MissingArrayPathException $e) {
1127  // No explicit setting in LocalConfiguration, yet. This means the system is currently being upgraded - a
1128  // "new" instance would have been set to 'explicitAllow' via FactoryConfiguration already. So we're catching
1129  // instances here that are being upgraded from a previous core version where explicitADmode has never been set
1130  // in LocalConfiguration, which then fell back to 'explicitDeny' with old cores due to the default in
1131  // DefaultConfiguration. This default has been changed to 'explicitAllow' with core v11.4, so we now need to
1132  // set this to 'explicitDeny' for those upgrading instances to keep their behavior.
1133  $confManager->setLocalConfigurationValueByPath('BE/explicitADmode', 'explicitDeny');
1135  }
1136  }
1137 }
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:999
‪TYPO3\CMS\Core\Crypto\PasswordHashing\BcryptPasswordHash
Definition: BcryptPasswordHash.php:32
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateLockSslSetting
‪migrateLockSslSetting()
Definition: SilentConfigurationUpgradeService.php:667
‪TYPO3\CMS\Install\Service\Exception\ConfigurationChangedException
Definition: ConfigurationChangedException.php:25
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService
Definition: SilentConfigurationUpgradeService.php:43
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateMailSettingsToSendmail
‪migrateMailSettingsToSendmail()
Definition: SilentConfigurationUpgradeService.php:1055
‪TYPO3\CMS\Core\Utility\Exception\MissingArrayPathException
Definition: MissingArrayPathException.php:27
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\disableImageMagickDetailSettingsIfImageMagickIsDisabled
‪disableImageMagickDetailSettingsIfImageMagickIsDisabled()
Definition: SilentConfigurationUpgradeService.php:454
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateExceptionErrors
‪migrateExceptionErrors()
Definition: SilentConfigurationUpgradeService.php:931
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\generateEncryptionKeyIfNeeded
‪generateEncryptionKeyIfNeeded()
Definition: SilentConfigurationUpgradeService.php:233
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateThumbnailsPngSetting
‪migrateThumbnailsPngSetting()
Definition: SilentConfigurationUpgradeService.php:644
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\throwConfigurationChangedException
‪throwConfigurationChangedException()
Definition: SilentConfigurationUpgradeService.php:631
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\$configurationManager
‪ConfigurationManager $configurationManager
Definition: SilentConfigurationUpgradeService.php:46
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\__construct
‪__construct(ConfigurationManager $configurationManager)
Definition: SilentConfigurationUpgradeService.php:170
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateDatabaseConnectionCharset
‪migrateDatabaseConnectionCharset()
Definition: SilentConfigurationUpgradeService.php:808
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\$obsoleteLocalConfigurationSettings
‪array $obsoleteLocalConfigurationSettings
Definition: SilentConfigurationUpgradeService.php:55
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateImageProcessorSetting
‪migrateImageProcessorSetting()
Definition: SilentConfigurationUpgradeService.php:559
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\execute
‪execute()
Definition: SilentConfigurationUpgradeService.php:181
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateExplicitADmode
‪migrateExplicitADmode()
Definition: SilentConfigurationUpgradeService.php:1113
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateDatabaseConnectionSettings
‪migrateDatabaseConnectionSettings()
Definition: SilentConfigurationUpgradeService.php:686
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateCacheHashOptions
‪migrateCacheHashOptions()
Definition: SilentConfigurationUpgradeService.php:870
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Pbkdf2PasswordHash
Definition: Pbkdf2PasswordHash.php:28
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateSaltedPasswordsSettings
‪migrateSaltedPasswordsSettings()
Definition: SilentConfigurationUpgradeService.php:971
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\transferHttpSettings
‪transferHttpSettings()
Definition: SilentConfigurationUpgradeService.php:254
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateCachingFrameworkCaches
‪migrateCachingFrameworkCaches()
Definition: SilentConfigurationUpgradeService.php:1026
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateLangDebug
‪migrateLangDebug()
Definition: SilentConfigurationUpgradeService.php:850
‪TYPO3\CMS\Core\Crypto\PasswordHashing\PhpassPasswordHash
Definition: PhpassPasswordHash.php:35
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\setImageMagickDetailSettings
‪setImageMagickDetailSettings()
Definition: SilentConfigurationUpgradeService.php:517
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateDatabaseDriverOptions
‪migrateDatabaseDriverOptions()
Definition: SilentConfigurationUpgradeService.php:828
‪TYPO3\CMS\Core\Crypto\Random
Definition: Random.php:24
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\migrateDisplayErrorsSetting
‪migrateDisplayErrorsSetting()
Definition: SilentConfigurationUpgradeService.php:951
‪TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService\removeObsoleteLocalConfigurationSettings
‪removeObsoleteLocalConfigurationSettings()
Definition: SilentConfigurationUpgradeService.php:215
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashInterface
Definition: PasswordHashInterface.php:25
‪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:1074