2 declare(strict_types
=1);
3 namespace TYPO3\CMS\Install\Controller
;
6 * This file is part of the TYPO3 CMS project.
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
15 * The TYPO3 project - inspiring people to share!
18 use Psr\Http\Message\ResponseInterface
;
19 use Psr\Http\Message\ServerRequestInterface
;
20 use TYPO3\CMS\Core\Configuration\ConfigurationManager
;
21 use TYPO3\CMS\Core\Http\HtmlResponse
;
22 use TYPO3\CMS\Core\Http\JsonResponse
;
23 use TYPO3\CMS\Install\Service\Exception\ConfigurationChangedException
;
24 use TYPO3\CMS\Install\Service\ExtensionConfigurationService
;
25 use TYPO3\CMS\Install\Service\SilentConfigurationUpgradeService
;
30 * Renders a first "load the Javascript in <head>" view, and the
31 * main layout of the install tool in second action.
33 class LayoutController
extends AbstractController
36 * The init action renders an HTML response with HTML view having <head> section
37 * containing resources to main .js routing.
39 * @param ServerRequestInterface $request
40 * @return ResponseInterface
42 public function initAction(ServerRequestInterface
$request): ResponseInterface
44 $view = $this->initializeStandaloneView($request, 'Layout/Init.html');
45 $view->assignMultiple([
46 // time is used as cache bust for js and css resources
48 'siteName' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'],
50 return new HtmlResponse(
54 'Cache-Control' => 'no-cache, must-revalidate',
55 'Pragma' => 'no-cache'
61 * Return a json response with the main HTML layout body: Toolbar, main menu and
62 * doc header in standalone, doc header only in backend context. Silent updaters
63 * are executed before this main view is loaded.
65 * @param ServerRequestInterface $request
66 * @return ResponseInterface
68 public function mainLayoutAction(ServerRequestInterface
$request): ResponseInterface
70 $view = $this->initializeStandaloneView($request, 'Layout/MainLayout.html');
71 return new JsonResponse([
73 'html' => $view->render(),
78 * Execute silent configuration update. May be called multiple times until success = true is returned.
80 * @return ResponseInterface success = true if no change has been done
82 public function executeSilentConfigurationUpdateAction(): ResponseInterface
84 $silentUpdate = new SilentConfigurationUpgradeService();
87 $silentUpdate->execute();
88 } catch (ConfigurationChangedException
$e) {
91 return new JsonResponse([
92 'success' => $success,
97 * Legacy ajax call. This silent updater takes care that all extensions configured in LocalConfiguration
98 * EXT/extConf serialized array are "upmerged" to arrays within EXTENSIONS if this extension does not
99 * exist in EXTENSIONS yet.
101 * @return ResponseInterface
102 * @deprecated since core v9, will be removed with core v10
104 public function executeSilentLegacyExtConfExtensionConfigurationUpdateAction(): ResponseInterface
106 $configurationManager = new ConfigurationManager();
108 $oldExtConfSettings = $configurationManager->getConfigurationValueByPath('EXT/extConf');
109 } catch (\RuntimeException
$e) {
110 // The old 'extConf' array may not exist anymore, set to empty array if so.
111 $oldExtConfSettings = [];
113 $newExtensionSettings = $configurationManager->getConfigurationValueByPath('EXTENSIONS');
114 foreach ($oldExtConfSettings as $extensionName => $extensionSettings) {
115 if (!array_key_exists($extensionName, $newExtensionSettings)) {
116 $newExtensionSettings = $this->removeDotsFromArrayKeysRecursive(unserialize($extensionSettings, ['allowed_classes' => false]));
117 $configurationManager->setLocalConfigurationValueByPath('EXTENSIONS/' . $extensionName, $newExtensionSettings);
120 return new JsonResponse([
126 * Synchronize TYPO3_CONF_VARS['EXTENSIONS'] with possibly new defaults from extensions
127 * ext_conf_template.txt files. This make LocalConfiguration the only source of truth for
128 * extension configuration and it is always up to date, also if an extension has been
131 * @return ResponseInterface
133 public function executeSilentExtensionConfigurationSynchronizationAction(): ResponseInterface
135 $extensionConfigurationService = new ExtensionConfigurationService();
136 $extensionConfigurationService->synchronizeExtConfTemplateWithLocalConfigurationOfAllExtensions();
137 return new JsonResponse([
143 * Helper method for executeSilentLegacyExtConfExtensionConfigurationUpdateAction(). Old EXT/extConf
144 * settings have dots at the end of array keys if nested arrays were used. The new configuration does
145 * not use this funny nested representation anymore. The method removes all dots at the end of given
146 * array keys recursive to do this transition.
148 * @param array $settings
149 * @return array New settings
150 * @deprecated since core v9, will be removed with core v10 along with executeSilentLegacyExtConfExtensionConfigurationUpdateAction()
152 private function removeDotsFromArrayKeysRecursive(array $settings): array
154 $settingsWithoutDots = [];
155 foreach ($settings as $key => $value) {
156 if (is_array($value)) {
157 $settingsWithoutDots[rtrim($key, '.')] = $this->removeDotsFromArrayKeysRecursive($value);
159 $settingsWithoutDots[$key] = $value;
162 return $settingsWithoutDots;