From 141d185ea970157dcc1b42fd06476294250e4616 Mon Sep 17 00:00:00 2001 From: Christian Kuhn <lolli@schwarzbu.ch> Date: Sat, 15 Apr 2023 10:58:36 +0200 Subject: [PATCH] [BUGFIX] Extbase BackendConfigurationManager fakes sys_template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The TypoScript parser has to load TypoScript from globals ($GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_') and TypoScript from extension static files (ext_typoscript_*.typoscript) at some point. It usually adds this before the first "root" sys_template row. This is fine in frontend. Extbase backend modules rely on frontend TypoScript for configuration as well. This decision from the dark ages hurts us plenty, but is very hard to get rid of. The extbase BackendConfigurationManager does a lot of guesswork to calculate such frontend TypoScript: There are various special cases, especially when an extbase backend module is not loaded within page context. The ext:form extension triggers such a special case: When there is only a single page marked as "is_siteroot" without a sys_template record, configuration from globals is not included. The configuration is then incomplete and the module fails. The old TypoScript parser had a dedicated hack and toggle for this, which forced it to still include global configuration. The new TypoScript parser does not contain this hack. Instead, the extbase BackendConfigurationManager "fakes" a sys_template row to trigger the global inclusion. This works if there is no "is_siteroot" page at all, but is not triggered when a page could be determined. The patch slightly changes the extbase logic to also add the fake row if a page could be determined, but no sys_template record exists. Additionally, the ext:form backend controllers now throw a dedicated exception if configuration is incomplete. Resolves: #99458 Related: #97816 Releases: main Change-Id: Ie48cd5c97704c9c4a0ad7a5e555f49f181f88006 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/78650 Tested-by: Stefan Bürk <stefan@buerk.tech> Reviewed-by: Kevin Appelt <kevin.appelt@icloud.com> Tested-by: core-ci <typo3@b13.com> Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> Reviewed-by: Stefan Bürk <stefan@buerk.tech> Tested-by: Kevin Appelt <kevin.appelt@icloud.com> Tested-by: Christian Kuhn <lolli@schwarzbu.ch> --- .../BackendConfigurationManager.php | 42 ++++++++++--------- .../Controller/AbstractBackendController.php | 9 +++- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/typo3/sysext/extbase/Classes/Configuration/BackendConfigurationManager.php b/typo3/sysext/extbase/Classes/Configuration/BackendConfigurationManager.php index 8dcaac1a1ea6..7a24fcf32d8a 100644 --- a/typo3/sysext/extbase/Classes/Configuration/BackendConfigurationManager.php +++ b/typo3/sysext/extbase/Classes/Configuration/BackendConfigurationManager.php @@ -215,29 +215,33 @@ class BackendConfigurationManager implements SingletonInterface $site = $request?->getAttribute('site'); $rootLine = []; + $sysTemplateFakeRow = [ + 'uid' => 0, + 'pid' => 0, + 'title' => 'Fake sys_template row to force extension statics loading', + 'root' => 1, + 'clear' => 3, + 'include_static_file' => '', + 'basedOn' => '', + 'includeStaticAfterBasedOn' => 0, + 'static_file_mode' => false, + 'constants' => '', + 'config' => '', + 'deleted' => 0, + 'hidden' => 0, + 'starttime' => 0, + 'endtime' => 0, + 'sorting' => 0, + ]; if ($pageId > 0) { $rootLine = GeneralUtility::makeInstance(RootlineUtility::class, $pageId)->get(); $sysTemplateRows = $this->sysTemplateRepository->getSysTemplateRowsByRootline($rootLine, $request); ksort($rootLine); - } else { - $sysTemplateRows[] = [ - 'uid' => 0, - 'pid' => 0, - 'title' => 'Fake sys_template row to force extension statics loading', - 'root' => 1, - 'clear' => 3, - 'include_static_file' => '', - 'basedOn' => '', - 'includeStaticAfterBasedOn' => 0, - 'static_file_mode' => false, - 'constants' => '', - 'config' => '', - 'deleted' => 0, - 'hidden' => 0, - 'starttime' => 0, - 'endtime' => 0, - 'sorting' => 0, - ]; + } + if (empty($sysTemplateRows)) { + // If there is no page (pid 0 only), or if the first 'is_siteroot' site has no sys_template record, + // then we "fake" a sys_template row: This triggers inclusion of 'global' and 'extension static' TypoScript. + $sysTemplateRows[] = $sysTemplateFakeRow; } // We do cache tree and tokens, but don't cache full ast in this backend context for now: diff --git a/typo3/sysext/form/Classes/Controller/AbstractBackendController.php b/typo3/sysext/form/Classes/Controller/AbstractBackendController.php index 8953c8be8269..cc771f62c0f7 100644 --- a/typo3/sysext/form/Classes/Controller/AbstractBackendController.php +++ b/typo3/sysext/form/Classes/Controller/AbstractBackendController.php @@ -41,8 +41,13 @@ abstract class AbstractBackendController extends ActionController public function initializeObject() { - $this->formSettings = GeneralUtility::makeInstance(ConfigurationManagerInterface::class) - ->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_YAML_SETTINGS, 'form'); + $configurationManager = GeneralUtility::makeInstance(ConfigurationManagerInterface::class); + $this->formSettings = $configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_YAML_SETTINGS, 'form'); + if (!isset($this->formSettings['formManager'])) { + // Config sub array formManager is crucial and should always exist. If it does + // not, this indicates an issue in config loading logic. Except in this case. + throw new \LogicException('Configuration could not be loaded', 1681549038); + } } /** -- GitLab