From 6cb3099901e162c56f717f312b39d993b5902883 Mon Sep 17 00:00:00 2001
From: Benni Mack <benni@typo3.org>
Date: Wed, 12 Sep 2018 08:53:02 +0200
Subject: [PATCH] [TASK] Streamline hooks and middlewares related to PSR-15

With PSR-15 it is not necessary to use any custom hooks during
the frontend request setup process anymore, as middlewares
are flexible enough to manipulate anything people want to do.

On top, various middlewares are also declared internal as
the usages are not really necessary to be publically exposed.
- typo3/cms-core/normalized-params-attribute
- typo3/cms-backend/legacy-document-template
- typo3/cms-backend/output-compression
- typo3/cms-backend/response-headers
- typo3/cms-frontend/timetracker
- typo3/cms-frontend/preprocessing
- typo3/cms-frontend/eid
- typo3/cms-frontend/content-length-headers
- typo3/cms-frontend/tsfe
- typo3/cms-frontend/output-compression
- typo3/cms-frontend/prepare-tsfe-rendering
- typo3/cms-frontend/shortcut-and-mountpoint-redirect

Resolves: #86279
Releases: master
Change-Id: I14fbd7b026acdc84fb23ca43cd395de5b7b9c4b6
Reviewed-on: https://review.typo3.org/58253
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Benjamin Franzke <bfr@qbus.de>
Tested-by: Benjamin Franzke <bfr@qbus.de>
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
---
 .../Configuration/RequestMiddlewares.php      |  4 ++
 .../Classes/Http/MiddlewareDispatcher.php     |  2 +
 .../Classes/Http/MiddlewareStackResolver.php  |  2 +
 ...86279-VariousHooksAndPSR-15Middlewares.rst | 61 +++++++++++++++++
 .../TypoScriptFrontendController.php          | 68 +++++++++++--------
 .../Middleware/BackendUserAuthenticator.php   | 22 +++---
 .../Classes/Middleware/EidHandler.php         |  5 +-
 .../Middleware/FrontendUserAuthenticator.php  |  9 ++-
 .../Classes/Middleware/PageResolver.php       |  5 +-
 .../PrepareTypoScriptFrontendRendering.php    |  9 ++-
 .../Middleware/PreprocessRequestHook.php      | 10 ++-
 .../ShortcutAndMountPointRedirect.php         |  2 +
 .../TypoScriptFrontendInitialization.php      | 11 +--
 .../Configuration/RequestMiddlewares.php      |  9 +++
 .../Php/ArrayDimensionMatcher.php             | 35 ++++++++++
 15 files changed, 204 insertions(+), 50 deletions(-)
 create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Deprecation-86279-VariousHooksAndPSR-15Middlewares.rst

diff --git a/typo3/sysext/backend/Configuration/RequestMiddlewares.php b/typo3/sysext/backend/Configuration/RequestMiddlewares.php
index bb8048e441a8..bc7fbc3f4f46 100644
--- a/typo3/sysext/backend/Configuration/RequestMiddlewares.php
+++ b/typo3/sysext/backend/Configuration/RequestMiddlewares.php
@@ -11,6 +11,7 @@
  */
 return [
     'backend' => [
+        /** internal: do not use or reference this middleware in your own code */
         'typo3/cms-core/normalized-params-attribute' => [
             'target' => \TYPO3\CMS\Core\Middleware\NormalizedParamsAttribute::class,
         ],
@@ -45,18 +46,21 @@ return [
                 'typo3/cms-backend/backend-routing'
             ]
         ],
+        /** internal: do not use or reference this middleware in your own code */
         'typo3/cms-backend/legacy-document-template' => [
             'target' => \TYPO3\CMS\Backend\Middleware\LegacyBackendTemplateInitialization::class,
             'after' => [
                 'typo3/cms-backend/authentication'
             ]
         ],
+        /** internal: do not use or reference this middleware in your own code */
         'typo3/cms-backend/output-compression' => [
             'target' => \TYPO3\CMS\Backend\Middleware\OutputCompression::class,
             'after' => [
                 'typo3/cms-backend/authentication'
             ]
         ],
+        /** internal: do not use or reference this middleware in your own code */
         'typo3/cms-backend/response-headers' => [
             'target' => \TYPO3\CMS\Backend\Middleware\AdditionalResponseHeaders::class,
             'after' => [
diff --git a/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php b/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php
index 773bef49d746..20849626ad77 100644
--- a/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php
+++ b/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php
@@ -25,6 +25,8 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  * MiddlewareDispatcher
  *
  * This class manages and dispatches a PSR-15 middleware stack.
+ *
+ * @internal
  */
 class MiddlewareDispatcher implements RequestHandlerInterface
 {
diff --git a/typo3/sysext/core/Classes/Http/MiddlewareStackResolver.php b/typo3/sysext/core/Classes/Http/MiddlewareStackResolver.php
index 0163d73d0670..b28229be7d5d 100644
--- a/typo3/sysext/core/Classes/Http/MiddlewareStackResolver.php
+++ b/typo3/sysext/core/Classes/Http/MiddlewareStackResolver.php
@@ -22,6 +22,8 @@ use TYPO3\CMS\Core\Service\DependencyOrderingService;
 
 /**
  * This class resolves middleware stacks from defined configuration in all active packages.
+ *
+ * @internal
  */
 class MiddlewareStackResolver
 {
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-86279-VariousHooksAndPSR-15Middlewares.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-86279-VariousHooksAndPSR-15Middlewares.rst
new file mode 100644
index 000000000000..e98c587058d9
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-86279-VariousHooksAndPSR-15Middlewares.rst
@@ -0,0 +1,61 @@
+.. include:: ../../Includes.txt
+
+==========================================================
+Deprecation: #86279 - Various Hooks and PSR-15 Middlewares
+==========================================================
+
+See :issue:`86279`
+
+Description
+===========
+
+The new PSR-15-based middleware concept allows for a more fine-grained "hooking" mechanism when enhancing the HTTP
+Request or Response object.
+
+The following hooks have therefore been marked as deprecated:
+* :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['tslib_fe-PostProc']`
+* :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['connectToDB']`
+* :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['initFEuser']`
+* :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preBeUser']`
+* :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['postBeUser']`
+* :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkAlternativeIdMethods-PostProc']`
+* :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest']`
+
+On top, some middlewares have only been introduced in order to execute these hooks, or due to, and are marked for
+internal use:
+
+* typo3/cms-core/normalized-params-attribute
+* typo3/cms-backend/legacy-document-template
+* typo3/cms-backend/output-compression
+* typo3/cms-backend/response-headers
+* typo3/cms-frontend/timetracker
+* typo3/cms-frontend/preprocessing
+* typo3/cms-frontend/eid
+* typo3/cms-frontend/content-length-headers
+* typo3/cms-frontend/tsfe
+* typo3/cms-frontend/output-compression
+* typo3/cms-frontend/prepare-tsfe-rendering
+* typo3/cms-frontend/shortcut-and-mountpoint-redirect
+
+As these middlewares are marked as internal, it is recommended not to reference them directly, as these might get removed
+in TYPO3 v10.0.
+
+
+Impact
+======
+
+Making use of one of the hooks in an extension will trigger a deprecation warning.
+
+
+Affected Installations
+======================
+
+TYPO3 instances with extensions using one of the hooks.
+
+
+Migration
+=========
+
+Use a custom PSR-15 middleware instead.
+
+.. index:: PHP-API, FullyScanned, ext:frontend
diff --git a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
index b384c69858f6..dbfa24b6a569 100644
--- a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
+++ b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
@@ -856,8 +856,11 @@ class TypoScriptFrontendController implements LoggerAwareInterface
         $this->uniqueString = md5(microtime());
         $this->initPageRenderer();
         // Call post processing function for constructor:
-        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['tslib_fe-PostProc'] ?? [] as $_funcRef) {
-            GeneralUtility::callUserFunction($_funcRef, $_params, $this);
+        if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['tslib_fe-PostProc'])) {
+            trigger_error('The "tslib_fe-PostProc" hook will be removed in TYPO3 v10.0 in favor of PSR-15. Use a middleware instead.', E_USER_DEPRECATED);
+            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['tslib_fe-PostProc'] as $_funcRef) {
+                GeneralUtility::callUserFunction($_funcRef, $_params, $this);
+            }
         }
         $this->cacheHash = GeneralUtility::makeInstance(CacheHashCalculator::class);
         $this->initCaches();
@@ -918,10 +921,13 @@ class TypoScriptFrontendController implements LoggerAwareInterface
                 throw new ServiceUnavailableException($message, 1301648782);
             }
         }
-        // Call post processing function for DB connection:
-        $_params = ['pObj' => &$this];
-        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['connectToDB'] ?? [] as $_funcRef) {
-            GeneralUtility::callUserFunction($_funcRef, $_params, $this);
+        // Call post processing function for DB connection
+        if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['connectToDB'])) {
+            trigger_error('The "connectToDB" hook will be removed in TYPO3 v10.0 in favor of PSR-15. Use a middleware instead.', E_USER_DEPRECATED);
+            $_params = ['pObj' => &$this];
+            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['connectToDB'] as $_funcRef) {
+                GeneralUtility::callUserFunction($_funcRef, $_params, $this);
+            }
         }
     }
 
@@ -969,9 +975,12 @@ class TypoScriptFrontendController implements LoggerAwareInterface
         $this->fe_user->unpack_uc();
 
         // Call hook for possible manipulation of frontend user object
-        $_params = ['pObj' => &$this];
-        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['initFEuser'] ?? [] as $_funcRef) {
-            GeneralUtility::callUserFunction($_funcRef, $_params, $this);
+        if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['initFEuser'])) {
+            trigger_error('The "initFEuser" hook will be removed in TYPO3 v10.0 in favor of PSR-15. Use a middleware instead.', E_USER_DEPRECATED);
+            $_params = ['pObj' => &$this];
+            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['initFEuser'] as $_funcRef) {
+                GeneralUtility::callUserFunction($_funcRef, $_params, $this);
+            }
         }
     }
 
@@ -1094,9 +1103,12 @@ class TypoScriptFrontendController implements LoggerAwareInterface
     {
         trigger_error('The method "' . __METHOD__ . '" is deprecated, and will be removed in TYPO3 v10. Extensions should ensure that the BackendAuthenticator middleware is run to load a backend user.', E_USER_DEPRECATED);
         // PRE BE_USER HOOK
-        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preBeUser'] ?? [] as $_funcRef) {
-            $_params = [];
-            GeneralUtility::callUserFunction($_funcRef, $_params, $this);
+        if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preBeUser'])) {
+            trigger_error('The "preBeUser" hook will be removed in TYPO3 v10.0 in favor of PSR-15. Use a middleware instead.', E_USER_DEPRECATED);
+            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preBeUser'] as $_funcRef) {
+                $_params = [];
+                GeneralUtility::callUserFunction($_funcRef, $_params, $this);
+            }
         }
         $backendUserObject = null;
         // If the backend cookie is set,
@@ -1122,16 +1134,19 @@ class TypoScriptFrontendController implements LoggerAwareInterface
         $this->context->setAspect('backend.user', GeneralUtility::makeInstance(UserAspect::class, $backendUserObject));
         $this->context->setAspect('workspace', GeneralUtility::makeInstance(WorkspaceAspect::class, $backendUserObject ? $backendUserObject->workspace : 0));
         // POST BE_USER HOOK
-        if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['postBeUser'])) {
-            $_params = [
-                'BE_USER' => &$backendUserObject
-            ];
-            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['postBeUser'] as $_funcRef) {
-                GeneralUtility::callUserFunction($_funcRef, $_params, $this);
+        if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['postBeUser'])) {
+            trigger_error('The "postBeUser" hook will be removed in TYPO3 v10.0 in favor of PSR-15. Use a middleware instead.', E_USER_DEPRECATED);
+            if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['postBeUser'])) {
+                $_params = [
+                    'BE_USER' => &$backendUserObject
+                ];
+                foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['postBeUser'] as $_funcRef) {
+                    GeneralUtility::callUserFunction($_funcRef, $_params, $this);
+                }
+                // Set the aspect again, in case it got changed
+                $this->context->setAspect('backend.user', GeneralUtility::makeInstance(UserAspect::class, $backendUserObject));
+                $this->context->setAspect('workspace', GeneralUtility::makeInstance(WorkspaceAspect::class, $backendUserObject ? $backendUserObject->workspace : 0));
             }
-            // Set the aspect again, in case it got changed
-            $this->context->setAspect('backend.user', GeneralUtility::makeInstance(UserAspect::class, $backendUserObject));
-            $this->context->setAspect('workspace', GeneralUtility::makeInstance(WorkspaceAspect::class, $backendUserObject ? $backendUserObject->workspace : 0));
         }
         return $backendUserObject;
     }
@@ -2879,7 +2894,7 @@ class TypoScriptFrontendController implements LoggerAwareInterface
      */
     public function handleDataSubmission()
     {
-        trigger_error('The method "' . __METHOD__ . '" is deprecated since TYPO3 v9, and will be removed in TYPO3 v10. Implement the hooks directly, as they are still executed within TYPO3 via a PSR-15 middleware.', E_USER_DEPRECATED);
+        trigger_error('The method "' . __METHOD__ . '" is deprecated since TYPO3 v9, and will be removed in TYPO3 v10. Use a PSR-15 middleware. The hooks are still executed as PSR-15 middleware but will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
         // Hook for processing data submission to extensions
         foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkDataSubmission'] ?? [] as $className) {
             $_procObj = GeneralUtility::makeInstance($className);
@@ -3293,8 +3308,7 @@ class TypoScriptFrontendController implements LoggerAwareInterface
         // NOTE: as hooks are called in a loop, the last hook will have the final word (however each
         // hook receives the current status of the $usePageCache flag)
         foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['usePageCache'] ?? [] as $className) {
-            $_procObj = GeneralUtility::makeInstance($className);
-            $usePageCache = $_procObj->usePageCache($this, $usePageCache);
+            $usePageCache = GeneralUtility::makeInstance($className)->usePageCache($this, $usePageCache);
         }
         // Write the page to cache, if necessary
         if ($usePageCache) {
@@ -3302,8 +3316,7 @@ class TypoScriptFrontendController implements LoggerAwareInterface
         }
         // Hook for cache post processing (eg. writing static files!)
         foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['insertPageIncache'] ?? [] as $className) {
-            $_procObj = GeneralUtility::makeInstance($className);
-            $_procObj->insertPageIncache($this, $timeOutTime);
+            GeneralUtility::makeInstance($className)->insertPageIncache($this, $timeOutTime);
         }
     }
 
@@ -3595,8 +3608,7 @@ class TypoScriptFrontendController implements LoggerAwareInterface
         $this->content = $this->convOutputCharset($this->content);
         // Hook for indexing pages
         foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['pageIndexing'] ?? [] as $className) {
-            $_procObj = GeneralUtility::makeInstance($className);
-            $_procObj->hook_indexContent($this);
+            GeneralUtility::makeInstance($className)->hook_indexContent($this);
         }
         // Storing for cache:
         if (!$this->no_cache) {
diff --git a/typo3/sysext/frontend/Classes/Middleware/BackendUserAuthenticator.php b/typo3/sysext/frontend/Classes/Middleware/BackendUserAuthenticator.php
index a29054558299..90b9a05f6fab 100644
--- a/typo3/sysext/frontend/Classes/Middleware/BackendUserAuthenticator.php
+++ b/typo3/sysext/frontend/Classes/Middleware/BackendUserAuthenticator.php
@@ -52,9 +52,12 @@ class BackendUserAuthenticator implements MiddlewareInterface
     public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
     {
         // PRE BE_USER HOOK
-        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preBeUser'] ?? [] as $_funcRef) {
-            $_params = [];
-            GeneralUtility::callUserFunction($_funcRef, $_params, $GLOBALS['TSFE']);
+        if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preBeUser'])) {
+            trigger_error('The "preBeUser" hook will be removed in TYPO3 v10.0 in favor of PSR-15. Use a middleware instead.', E_USER_DEPRECATED);
+            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preBeUser'] as $_funcRef) {
+                $_params = [];
+                GeneralUtility::callUserFunction($_funcRef, $_params, $GLOBALS['TSFE']);
+            }
         }
 
         // Initializing a possible logged-in Backend User
@@ -68,11 +71,14 @@ class BackendUserAuthenticator implements MiddlewareInterface
         $GLOBALS['BE_USER'] = $backendUserObject;
 
         // POST BE_USER HOOK
-        $_params = [
-            'BE_USER' => &$GLOBALS['BE_USER']
-        ];
-        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['postBeUser'] ?? [] as $_funcRef) {
-            GeneralUtility::callUserFunction($_funcRef, $_params, $GLOBALS['TSFE']);
+        if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['postBeUser'])) {
+            $_params = [
+                'BE_USER' => &$GLOBALS['BE_USER']
+            ];
+            trigger_error('The "postBeUser" hook will be removed in TYPO3 v10.0 in favor of PSR-15. Use a middleware instead.', E_USER_DEPRECATED);
+            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['postBeUser'] as $_funcRef) {
+                GeneralUtility::callUserFunction($_funcRef, $_params, $GLOBALS['TSFE']);
+            }
         }
 
         // Load specific dependencies which are necessary for a valid Backend User
diff --git a/typo3/sysext/frontend/Classes/Middleware/EidHandler.php b/typo3/sysext/frontend/Classes/Middleware/EidHandler.php
index 6532db1ca140..914cf8f046d8 100644
--- a/typo3/sysext/frontend/Classes/Middleware/EidHandler.php
+++ b/typo3/sysext/frontend/Classes/Middleware/EidHandler.php
@@ -27,7 +27,10 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * Lightweight alternative to regular frontend requests; used when $_GET[eID] is set.
- * In the future, logic from the EidUtility will be moved to this class.
+ * In the future, logic from the EidUtility will be moved to this class, however in most cases
+ * a custom PSR-15 middleware will be better suited for whatever job the eID functionality does currently.
+ *
+ * @internal
  */
 class EidHandler implements MiddlewareInterface
 {
diff --git a/typo3/sysext/frontend/Classes/Middleware/FrontendUserAuthenticator.php b/typo3/sysext/frontend/Classes/Middleware/FrontendUserAuthenticator.php
index f66aadf5cf4b..0260374b4d0a 100644
--- a/typo3/sysext/frontend/Classes/Middleware/FrontendUserAuthenticator.php
+++ b/typo3/sysext/frontend/Classes/Middleware/FrontendUserAuthenticator.php
@@ -65,9 +65,12 @@ class FrontendUserAuthenticator implements MiddlewareInterface
         // Call hook for possible manipulation of frontend user object
         // This hook is kept for compatibility reasons, however, it should be fairly simple to add a custom middleware
         // for this purpose
-        $_params = ['pObj' => &$GLOBALS['TSFE']];
-        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['initFEuser'] ?? [] as $_funcRef) {
-            GeneralUtility::callUserFunction($_funcRef, $_params, $GLOBALS['TSFE']);
+        if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['initFEuser'])) {
+            trigger_error('The "initFEuser" hook will be removed in TYPO3 v10.0 in favor of PSR-15. Use a middleware instead.', E_USER_DEPRECATED);
+            $_params = ['pObj' => &$GLOBALS['TSFE']];
+            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['initFEuser'] as $_funcRef) {
+                GeneralUtility::callUserFunction($_funcRef, $_params, $GLOBALS['TSFE']);
+            }
         }
 
         // Register the frontend user as aspect
diff --git a/typo3/sysext/frontend/Classes/Middleware/PageResolver.php b/typo3/sysext/frontend/Classes/Middleware/PageResolver.php
index 5befaa1789ef..d0f4dfac9c25 100644
--- a/typo3/sysext/frontend/Classes/Middleware/PageResolver.php
+++ b/typo3/sysext/frontend/Classes/Middleware/PageResolver.php
@@ -115,7 +115,10 @@ class PageResolver implements MiddlewareInterface
         } else {
             // old-school page resolving for realurl, cooluri etc.
             $this->controller->siteScript = $request->getAttribute('normalizedParams')->getSiteScript();
-            $this->checkAlternativeIdMethods($this->controller);
+            if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkAlternativeIdMethods-PostProc'])) {
+                trigger_error('The "checkAlternativeIdMethods-PostProc" hook will be removed in TYPO3 v10.0 in favor of PSR-15. Use a middleware instead.', E_USER_DEPRECATED);
+                $this->checkAlternativeIdMethods($this->controller);
+            }
         }
 
         $this->controller->determineId();
diff --git a/typo3/sysext/frontend/Classes/Middleware/PrepareTypoScriptFrontendRendering.php b/typo3/sysext/frontend/Classes/Middleware/PrepareTypoScriptFrontendRendering.php
index ff6388a93a1c..794f1443722d 100644
--- a/typo3/sysext/frontend/Classes/Middleware/PrepareTypoScriptFrontendRendering.php
+++ b/typo3/sysext/frontend/Classes/Middleware/PrepareTypoScriptFrontendRendering.php
@@ -29,6 +29,8 @@ use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
  * Initialization of TypoScriptFrontendController
  *
  * Do all necessary preparation steps for rendering
+ *
+ * @internal this middleware might get removed in TYPO3 v10.0.
  */
 class PrepareTypoScriptFrontendRendering implements MiddlewareInterface
 {
@@ -99,8 +101,11 @@ class PrepareTypoScriptFrontendRendering implements MiddlewareInterface
 
         // Hook for processing data submission to extensions
         // This is done at this point, because we need the config values
-        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkDataSubmission'] ?? [] as $className) {
-            GeneralUtility::makeInstance($className)->checkDataSubmission($this->controller);
+        if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkDataSubmission'])) {
+            trigger_error('The "checkDataSubmission" hook will be removed in TYPO3 v10.0 in favor of PSR-15. Use a middleware instead.', E_USER_DEPRECATED);
+            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkDataSubmission'] as $className) {
+                GeneralUtility::makeInstance($className)->checkDataSubmission($this->controller);
+            }
         }
 
         return $handler->handle($request);
diff --git a/typo3/sysext/frontend/Classes/Middleware/PreprocessRequestHook.php b/typo3/sysext/frontend/Classes/Middleware/PreprocessRequestHook.php
index 0fafd197dc2b..f84cc4d51890 100644
--- a/typo3/sysext/frontend/Classes/Middleware/PreprocessRequestHook.php
+++ b/typo3/sysext/frontend/Classes/Middleware/PreprocessRequestHook.php
@@ -25,6 +25,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  * Calls a hook before processing a request for the TYPO3 Frontend.
  *
  * @internal
+ * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
  */
 class PreprocessRequestHook implements MiddlewareInterface
 {
@@ -38,9 +39,12 @@ class PreprocessRequestHook implements MiddlewareInterface
      */
     public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
     {
-        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'] ?? [] as $hookFunction) {
-            $hookParameters = [];
-            GeneralUtility::callUserFunction($hookFunction, $hookParameters, $hookParameters);
+        if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'])) {
+            trigger_error('The "preprocessRequest" hook will be removed in TYPO3 v10.0 in favor of PSR-15. Use a middleware instead.', E_USER_DEPRECATED);
+            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'] as $hookFunction) {
+                $hookParameters = [];
+                GeneralUtility::callUserFunction($hookFunction, $hookParameters, $hookParameters);
+            }
         }
         return $handler->handle($request);
     }
diff --git a/typo3/sysext/frontend/Classes/Middleware/ShortcutAndMountPointRedirect.php b/typo3/sysext/frontend/Classes/Middleware/ShortcutAndMountPointRedirect.php
index 91dd092ee84d..184acf5f4480 100644
--- a/typo3/sysext/frontend/Classes/Middleware/ShortcutAndMountPointRedirect.php
+++ b/typo3/sysext/frontend/Classes/Middleware/ShortcutAndMountPointRedirect.php
@@ -27,6 +27,8 @@ use TYPO3\CMS\Frontend\Page\PageRepository;
 /**
  * Checks mount points, shortcuts and redirects to the target.
  * Alternatively, checks if the current page is an redirect to an external page
+ *
+ * @internal this middleware might get removed in TYPO3 v10.0.
  */
 class ShortcutAndMountPointRedirect implements MiddlewareInterface
 {
diff --git a/typo3/sysext/frontend/Classes/Middleware/TypoScriptFrontendInitialization.php b/typo3/sysext/frontend/Classes/Middleware/TypoScriptFrontendInitialization.php
index 503d4ee80ab1..11b1f7a61b2c 100644
--- a/typo3/sysext/frontend/Classes/Middleware/TypoScriptFrontendInitialization.php
+++ b/typo3/sysext/frontend/Classes/Middleware/TypoScriptFrontendInitialization.php
@@ -35,7 +35,7 @@ use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
  * For now, GeneralUtility::_GP() is used in favor of $request->getQueryParams() due to
  * hooks who could have $_GET/$_POST modified before.
  *
- * @internal
+ * @internal this middleware might get removed in TYPO3 v10.0.
  */
 class TypoScriptFrontendInitialization implements MiddlewareInterface, LoggerAwareInterface
 {
@@ -80,9 +80,12 @@ class TypoScriptFrontendInitialization implements MiddlewareInterface, LoggerAwa
             }
         }
         // Call post processing function for DB connection:
-        $_params = ['pObj' => &$GLOBALS['TSFE']];
-        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['connectToDB'] ?? [] as $_funcRef) {
-            GeneralUtility::callUserFunction($_funcRef, $_params, $GLOBALS['TSFE']);
+        if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['connectToDB'])) {
+            trigger_error('The "connectToDB" hook will be removed in TYPO3 v10.0 in favor of PSR-15. Use a middleware instead.', E_USER_DEPRECATED);
+            $_params = ['pObj' => &$GLOBALS['TSFE']];
+            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['connectToDB'] as $_funcRef) {
+                GeneralUtility::callUserFunction($_funcRef, $_params, $GLOBALS['TSFE']);
+            }
         }
 
         return $handler->handle($request);
diff --git a/typo3/sysext/frontend/Configuration/RequestMiddlewares.php b/typo3/sysext/frontend/Configuration/RequestMiddlewares.php
index dfab93272331..d286fee4ffbd 100644
--- a/typo3/sysext/frontend/Configuration/RequestMiddlewares.php
+++ b/typo3/sysext/frontend/Configuration/RequestMiddlewares.php
@@ -11,21 +11,25 @@
  */
 return [
     'frontend' => [
+        /** internal: do not use or reference this middleware in your own code */
         'typo3/cms-frontend/timetracker' => [
             'target' => \TYPO3\CMS\Frontend\Middleware\TimeTrackerInitialization::class,
         ],
+        /** internal: do not use or reference this middleware in your own code */
         'typo3/cms-core/normalized-params-attribute' => [
             'target' => \TYPO3\CMS\Core\Middleware\NormalizedParamsAttribute::class,
             'after' => [
                 'typo3/cms-frontend/timetracker',
             ]
         ],
+        /** internal: do not use or reference this middleware in your own code, as this will be possibly be removed */
         'typo3/cms-frontend/preprocessing' => [
             'target' => \TYPO3\CMS\Frontend\Middleware\PreprocessRequestHook::class,
             'after' => [
                 'typo3/cms-core/normalized-params-attribute',
             ]
         ],
+        /** internal: do not use or reference this middleware in your own code, as this will be possibly be removed */
         'typo3/cms-frontend/eid' => [
             'target' => \TYPO3\CMS\Frontend\Middleware\EidHandler::class,
             'after' => [
@@ -39,18 +43,21 @@ return [
                 'typo3/cms-frontend/eid'
             ]
         ],
+        /** internal: do not use or reference this middleware in your own code, as this will be possibly be removed */
         'typo3/cms-frontend/content-length-headers' => [
             'target' => \TYPO3\CMS\Frontend\Middleware\ContentLengthResponseHeader::class,
             'after' => [
                 'typo3/cms-frontend/maintenance-mode'
             ]
         ],
+        /** internal: do not use or reference this middleware in your own code, as this will be possibly be removed */
         'typo3/cms-frontend/tsfe' => [
             'target' => \TYPO3\CMS\Frontend\Middleware\TypoScriptFrontendInitialization::class,
             'after' => [
                 'typo3/cms-frontend/eid',
             ]
         ],
+        /** internal: do not use or reference this middleware in your own code, as this will be possibly be removed */
         'typo3/cms-frontend/output-compression' => [
             'target' => \TYPO3\CMS\Frontend\Middleware\OutputCompression::class,
             'after' => [
@@ -90,12 +97,14 @@ return [
                 'typo3/cms-frontend/site',
             ]
         ],
+        /** internal: do not use or reference this middleware in your own code, as this will be possibly be removed */
         'typo3/cms-frontend/prepare-tsfe-rendering' => [
             'target' => \TYPO3\CMS\Frontend\Middleware\PrepareTypoScriptFrontendRendering::class,
             'after' => [
                 'typo3/cms-frontend/page-resolver',
             ]
         ],
+        /** internal: do not use or reference this middleware in your own code, as this will be possibly be removed */
         'typo3/cms-frontend/shortcut-and-mountpoint-redirect' => [
             'target' => \TYPO3\CMS\Frontend\Middleware\ShortcutAndMountPointRedirect::class,
             'after' => [
diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php
index 3005819170f9..6aba2a6e7314 100644
--- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php
+++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php
@@ -180,4 +180,39 @@ return [
             'Deprecation-85977-ExtbaseCommandControllersAndCliAnnotation.rst',
         ],
     ],
+    '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'tslib/class.tslib_fe.php\'][\'tslib_fe-PostProc\']' => [
+        'restFiles' => [
+            'Deprecation-86279-VariousHooksAndPSR-15Middlewares.rst',
+        ],
+    ],
+    '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'tslib/class.tslib_fe.php\'][\'connectToDB\']' => [
+        'restFiles' => [
+            'Deprecation-86279-VariousHooksAndPSR-15Middlewares.rst',
+        ],
+    ],
+    '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'tslib/class.tslib_fe.php\'][\'initFEuser\']' => [
+        'restFiles' => [
+            'Deprecation-86279-VariousHooksAndPSR-15Middlewares.rst',
+        ],
+    ],
+    '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'tslib/index_ts.php\'][\'preBeUser\']' => [
+        'restFiles' => [
+            'Deprecation-86279-VariousHooksAndPSR-15Middlewares.rst',
+        ],
+    ],
+    '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'tslib/index_ts.php\'][\'postBeUser\']' => [
+        'restFiles' => [
+            'Deprecation-86279-VariousHooksAndPSR-15Middlewares.rst',
+        ],
+    ],
+    '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'tslib/class.tslib_fe.php\'][\'checkAlternativeIdMethods-PostProc\']' => [
+        'restFiles' => [
+            'Deprecation-86279-VariousHooksAndPSR-15Middlewares.rst',
+        ],
+    ],
+    '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'tslib/index_ts.php\'][\'preprocessRequest\']' => [
+        'restFiles' => [
+            'Deprecation-86279-VariousHooksAndPSR-15Middlewares.rst',
+        ],
+    ],
 ];
-- 
GitLab