diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-85124-RedirectingUrlHandlerHookConcept.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-85124-RedirectingUrlHandlerHookConcept.rst new file mode 100644 index 0000000000000000000000000000000000000000..42025d10eb74b68ddf2986bdd5eb50a14dffb9b6 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-85124-RedirectingUrlHandlerHookConcept.rst @@ -0,0 +1,40 @@ +.. include:: ../../Includes.txt + +========================================================= +Deprecation: #85124 - Redirecting urlHandler Hook Concept +========================================================= + +See :issue:`85124` + +Description +=========== + +The URL handler concept introduced in TYPO3 v7 to allow pages to do redirects has been deprecated in favor +of using PSR-7 / PSR-15 middlewares. + +The Redirect URL handlers were used for e.g. jumpURLs, pages that should redirect to a external URL +or special handlings registered via the :php:`\TYPO3\CMS\Frontend\Http\UrlHandlerInterface`. + +All functionality and methods have been marked as deprecated and will be removed in TYPO3 v10.0. + + +Impact +====== + +Calling :php:`$TSFE->initializeRedirectUrlHandlers()` and :php:`$TSFE->redirectToExternalUrl()` will trigger +deprecation warnings. + + +Affected Installations +====================== + +TYPO3 Installations with extensions registering a urlHandler via +`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['urlProcessing']['urlHandlers']`. + + +Migration +========= + +Check the extension scanner if the site is affected and migrate to a PSR-15 middleware. + +.. index:: Frontend, PHP-API, FullyScanned diff --git a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php index 8f1e89b2dc7329d7c7b361eb2343ef717a847306..e005d0a9b92520ea3b97252d6e211de7fb7da2c6 100644 --- a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php +++ b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php @@ -155,6 +155,7 @@ class TypoScriptFrontendController implements LoggerAwareInterface * * @var \TYPO3\CMS\Frontend\Http\UrlHandlerInterface[] * @see initializeRedirectUrlHandlers() + * @deprecated since TYPO3 v9.3, will be removed in TYPO3 v10.0. */ protected $activeUrlHandlers = []; @@ -2758,14 +2759,20 @@ class TypoScriptFrontendController implements LoggerAwareInterface /** * Loops over all configured URL handlers and registers all active handlers in the redirect URL handler array. * + * @param bool $calledFromCore if set to true, no deprecation warning will be triggered * @see $activeRedirectUrlHandlers + * @deprecated since TYPO3 v9.3, will be removed in TYPO3 v10.0. Do not call this method anymore, and also ensure that all urlHandlers are migrated to PSR-15 middlewares. */ - public function initializeRedirectUrlHandlers() + public function initializeRedirectUrlHandlers($calledFromCore = false) { $urlHandlers = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['urlProcessing']['urlHandlers'] ?? false; if (!$urlHandlers) { + if (!$calledFromCore) { + trigger_error('The method $TSFE->initializeRedirectUrlHandlers() will be removed in TYPO3 v10.0. Do not call this method anymore and implement UrlHandlers by PSR-15 middlewares instead.', E_USER_DEPRECATED); + } return; } + trigger_error('The system has registered RedirectUrlHandlers via $TYPO3_CONF_VARS[SC_OPTIONS][urlProcessing][urlHandlers]. This functionality will be removed in TYPO3 v10.0. Ensure that extensions using this functionality switch to PSR-15 middelwares instead.', E_USER_DEPRECATED); foreach ($urlHandlers as $identifier => $configuration) { if (empty($configuration) || !is_array($configuration)) { @@ -2791,13 +2798,18 @@ class TypoScriptFrontendController implements LoggerAwareInterface * Loops over all registered URL handlers and lets them process the current URL. * * If no handler has stopped the current process (e.g. by redirecting) and a - * the redirectUrl propert is not empty, the user will be redirected to this URL. + * the redirectUrl property is not empty, the user will be redirected to this URL. * * @internal Should be called by the FrontendRequestHandler only. * @return ResponseInterface|null + * @param bool $calledFromCore if set to true, no deprecation warning will be triggered + * @deprecated since TYPO3 v9.3, will be removed in TYPO3 v10.0. Do not call this method anymore, and also ensure that all urlHandlers are migrated to PSR-15 middlewares. */ - public function redirectToExternalUrl() + public function redirectToExternalUrl($calledFromCore = false) { + if (!$calledFromCore) { + trigger_error('The method $TSFE->redirectToExternalUrl() will be removed in TYPO3 v10.0. Do not call this method anymore and implement UrlHandlers by PSR-15 middlewares instead.', E_USER_DEPRECATED); + } foreach ($this->activeUrlHandlers as $redirectHandler) { $response = $redirectHandler->handle(); if ($response instanceof ResponseInterface) { diff --git a/typo3/sysext/frontend/Classes/Http/RequestHandler.php b/typo3/sysext/frontend/Classes/Http/RequestHandler.php index 4954edb043df6c6efbbd4f39fc45737841776592..0ad5a80a8ab7fcdd302647c277eab27eff1ccf41 100644 --- a/typo3/sysext/frontend/Classes/Http/RequestHandler.php +++ b/typo3/sysext/frontend/Classes/Http/RequestHandler.php @@ -105,7 +105,8 @@ class RequestHandler implements RequestHandlerInterface, PsrRequestHandlerInterf // Store session data for fe_users $controller->storeSessionData(); - $redirectResponse = $controller->redirectToExternalUrl(); + // @deprecated since TYPO3 v9.3, will be removed in TYPO3 v10.0. + $redirectResponse = $controller->redirectToExternalUrl(true); if ($redirectResponse instanceof ResponseInterface) { return $redirectResponse; } diff --git a/typo3/sysext/frontend/Classes/Http/UrlHandlerInterface.php b/typo3/sysext/frontend/Classes/Http/UrlHandlerInterface.php index 248b2ec7f651a915948878b8a52e968ded6e48d8..123f1eb1c7f444c1cb528141554076387e22d94c 100644 --- a/typo3/sysext/frontend/Classes/Http/UrlHandlerInterface.php +++ b/typo3/sysext/frontend/Classes/Http/UrlHandlerInterface.php @@ -19,6 +19,7 @@ namespace TYPO3\CMS\Frontend\Http; * $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['urlProcessing']['urlHandlers'] * * It can be used to do custom URL processing during a Frontend request. + * @deprecated since TYPO3 v9.3, will be removed in TYPO3 v10.0 in favor of PSR-15 middlewares. */ interface UrlHandlerInterface { diff --git a/typo3/sysext/frontend/Classes/Middleware/PrepareTypoScriptFrontendRendering.php b/typo3/sysext/frontend/Classes/Middleware/PrepareTypoScriptFrontendRendering.php index d0e0ded10dfbf9f6b62be807bf7e7c1bdfe20d9d..ac875ea632dc21d3d1f04ef37d16c47ac2a921ac 100644 --- a/typo3/sysext/frontend/Classes/Middleware/PrepareTypoScriptFrontendRendering.php +++ b/typo3/sysext/frontend/Classes/Middleware/PrepareTypoScriptFrontendRendering.php @@ -84,7 +84,8 @@ class PrepareTypoScriptFrontendRendering implements MiddlewareInterface $GLOBALS['TYPO3_REQUEST'] = $request; } - $this->controller->initializeRedirectUrlHandlers(); + // @deprecated since TYPO3 v9.3, will be removed in TYPO3 v10.0 + $this->controller->initializeRedirectUrlHandlers(true); // Hook for processing data submission to extensions // This is done at this point, because we need the config values diff --git a/typo3/sysext/frontend/Classes/Middleware/ShortcutAndMountPointRedirect.php b/typo3/sysext/frontend/Classes/Middleware/ShortcutAndMountPointRedirect.php index fae88943e65d9726a94ad14f3406c869aa9e9666..f0f78a95a948196c4055c692dab6afba888e31d6 100644 --- a/typo3/sysext/frontend/Classes/Middleware/ShortcutAndMountPointRedirect.php +++ b/typo3/sysext/frontend/Classes/Middleware/ShortcutAndMountPointRedirect.php @@ -20,10 +20,12 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; use TYPO3\CMS\Core\Http\RedirectResponse; +use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; /** - * Checks mount points or shortcuts and redirects to the target + * Checks mount points, shortcuts and redirects to the target. + * Alternatively, checks if the current page is an redirect to an external page */ class ShortcutAndMountPointRedirect implements MiddlewareInterface { @@ -45,6 +47,18 @@ class ShortcutAndMountPointRedirect implements MiddlewareInterface return new RedirectResponse($redirectToUri, 307); } + // See if the current page is of doktype "External URL", if so, do a redirect as well. + if (empty($this->controller->config['config']['disablePageExternalUrl'] ?? null) + && $this->controller->sys_page::DOKTYPE_LINK === (int)$this->controller->page['doktype']) { + $externalUrl = $this->prefixExternalPageUrl( + $this->controller->page['url'], + $request->getAttribute('normalizedParams')->getSiteUrl() + ); + if (!empty($externalUrl)) { + return new RedirectResponse($externalUrl, 303); + } + } + return $handler->handle($request); } @@ -56,4 +70,26 @@ class ShortcutAndMountPointRedirect implements MiddlewareInterface } return $this->controller->getRedirectUriForMountPoint(); } + + /** + * Returns the redirect URL for the input page row IF the doktype is set to 3. + * + * @param string $redirectTo The page row to return URL type for + * @param string $sitePrefix if no protocol or relative path given, the site prefix is added + * @return string The URL from based on the external page URL given with a prefix. + */ + protected function prefixExternalPageUrl(string $redirectTo, string $sitePrefix): string + { + $uI = parse_url($redirectTo); + // If relative path, prefix Site URL + // If it's a valid email without protocol, add "mailto:" + if (!($uI['scheme'] ?? false)) { + if (GeneralUtility::validEmail($redirectTo)) { + $redirectTo = 'mailto:' . $redirectTo; + } elseif ($redirectTo[0] !== '/') { + $redirectTo = $sitePrefix . $redirectTo; + } + } + return $redirectTo; + } } diff --git a/typo3/sysext/frontend/Classes/Page/ExternalPageUrlHandler.php b/typo3/sysext/frontend/Classes/Page/ExternalPageUrlHandler.php index 9eb8136be0126109700633760d71f8df29c3651c..ed682fe74d4b0e66cfc3a3b213565c1334ed8843 100644 --- a/typo3/sysext/frontend/Classes/Page/ExternalPageUrlHandler.php +++ b/typo3/sysext/frontend/Classes/Page/ExternalPageUrlHandler.php @@ -21,6 +21,7 @@ use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; /** * Handles the redirection for external URL pages. + * @deprecated since TYPO3 v9.3, will be removed in TYPO3 v10.0. The functionality has been moved into a PSR-15 middleware. */ class ExternalPageUrlHandler implements \TYPO3\CMS\Frontend\Http\UrlHandlerInterface { @@ -29,6 +30,11 @@ class ExternalPageUrlHandler implements \TYPO3\CMS\Frontend\Http\UrlHandlerInter */ protected $externalUrl = ''; + public function __construct() + { + trigger_error('ExternalPageUrlHandler has been moved into a PSR-15 middleware and will be removed in TYPO3 v10.0. In order to modify the external page redirection, use a PSR-15 middleware as well', E_USER_DEPRECATED); + } + /** * Checks if external URLs are enabled and if the current page points to an external URL. * diff --git a/typo3/sysext/frontend/ext_localconf.php b/typo3/sysext/frontend/ext_localconf.php index c10552e8bd5b8e06d81238c4b163eea79e143d50..0d4f65743e17716c966daf9c62b583429b368f48 100644 --- a/typo3/sysext/frontend/ext_localconf.php +++ b/typo3/sysext/frontend/ext_localconf.php @@ -94,11 +94,6 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php'][ // Register search key shortcuts $GLOBALS['TYPO3_CONF_VARS']['SYS']['livesearch']['content'] = 'tt_content'; -// Register URL handler for external pages. -$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['urlProcessing']['urlHandlers']['frontendExternalUrl'] = [ - 'handler' => \TYPO3\CMS\Frontend\Page\ExternalPageUrlHandler::class, -]; - \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Imaging\IconRegistry::class) ->registerIcon( 'wizard-backendlayout', diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php index c236e70cf61d99948bbf2651b73b632ea430fb8b..29c4945389063d5196c5d6ca597577690faf7064 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php @@ -160,4 +160,9 @@ return [ 'Feature-84045-NewAdminPanelModuleAPI.rst', ], ], + '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'urlProcessing\'][\'urlHandlers\']' => [ + 'restFiles' => [ + 'Deprecation-85124-RedirectingUrlHandlerHookConcept.rst', + ], + ], ]; diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php index 68aa6265194a66f7930bcb12b6bc090008e60ddf..7f7d4d5790de20e4cd996d942bf72fabd46637e3 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php @@ -684,4 +684,14 @@ return [ 'Deprecation-85120-JavaScriptEncoder.rst', ], ], + 'TYPO3\CMS\Frontend\Page\ExternalPageUrlHandler' => [ + 'restFiles' => [ + 'Deprecation-85124-RedirectingUrlHandlerHookConcept.rst', + ], + ], + 'TYPO3\CMS\Frontend\Http\UrlHandlerInterface' => [ + 'restFiles' => [ + 'Deprecation-85124-RedirectingUrlHandlerHookConcept.rst', + ], + ], ];