diff --git a/typo3/sysext/core/Classes/Context/Context.php b/typo3/sysext/core/Classes/Context/Context.php index e4e03f2e6f1cafc776d8caf3435af1620814200a..2d6e923a26764d31667694f19c0b71a66fe20ed8 100644 --- a/typo3/sysext/core/Classes/Context/Context.php +++ b/typo3/sysext/core/Classes/Context/Context.php @@ -164,4 +164,16 @@ class Context implements SingletonInterface { $this->aspects[$name] = $aspect; } + + /** + * @internal Using this method is a sign of a technical debt. It is used by RedirectService, + * but may vanish any time when this is fixed, and thus internal. + * In general, Context aspects should never have to be unset. + * When a middleware has to use this method, it is either located + * at the wrong position in the chain, or has some other dependency issue. + */ + public function unsetAspect(string $name): void + { + unset($this->aspects[$name]); + } } diff --git a/typo3/sysext/redirects/Classes/Service/RedirectService.php b/typo3/sysext/redirects/Classes/Service/RedirectService.php index 9e7659a72ba94108a72dcafb732b2f8706dfda7e..56c0d911470c57974dfeda1055c33d2f9bfe37e1 100644 --- a/typo3/sysext/redirects/Classes/Service/RedirectService.php +++ b/typo3/sysext/redirects/Classes/Service/RedirectService.php @@ -338,6 +338,7 @@ class RedirectService implements LoggerAwareInterface $configuration['additionalParams'] = HttpUtility::buildQueryString($queryParams, '&'); } $result = $linkBuilder->build($linkDetails, '', '', $configuration); + $this->cleanupTSFE(); if (is_array($result)) { return new Uri($result[0] ?? ''); } @@ -348,6 +349,7 @@ class RedirectService implements LoggerAwareInterface } catch (UnableToLinkException $e) { // This exception is also thrown by the DatabaseRecordTypolinkBuilder $url = $controller->cObj->lastTypoLinkUrl; + $this->cleanupTSFE(); if (!empty($url)) { return new Uri($url); } @@ -431,4 +433,18 @@ class RedirectService implements LoggerAwareInterface return null; } + + /** + * @todo: Needs to vanish. The existence of this method is a side-effect of the technical debt that + * a TSFE has to be set up for link generation, see the comment on bootFrontendController() + * for more details. + */ + private function cleanupTSFE(): void + { + $context = GeneralUtility::makeInstance(Context::class); + $context->unsetAspect('language'); + $context->unsetAspect('typoscript'); + $context->unsetAspect('frontend.preview'); + unset($GLOBALS['TSFE']); + } }