[!!!][TASK] Remove $response preparation in route dispatching 09/59209/4
authorChristian Kuhn <lolli@schwarzbu.ch>
Wed, 19 Dec 2018 11:50:51 +0000 (12:50 +0100)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Wed, 19 Dec 2018 12:29:45 +0000 (13:29 +0100)
Calling controllers with a prepared $response object is
dropped, together with the b/w compat feature
'simplifiedControllerActionDispatching'.

Resolves: #87211
Releases: master
Change-Id: Ia1cba4cc78e1cf8527f9c2a8b8f20655bc6af611
Reviewed-on: https://review.typo3.org/59209
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
typo3/sysext/backend/Classes/Http/AjaxRequestHandler.php
typo3/sysext/backend/Classes/Http/RequestHandler.php
typo3/sysext/backend/Classes/Http/RouteDispatcher.php
typo3/sysext/core/Classes/Configuration/Features.php
typo3/sysext/core/Classes/Http/Dispatcher.php
typo3/sysext/core/Configuration/DefaultConfiguration.php
typo3/sysext/core/Configuration/DefaultConfigurationDescription.yaml
typo3/sysext/core/Documentation/Changelog/master/Breaking-87193-DeprecatedFunctionalityRemoved.rst
typo3/sysext/frontend/Classes/Http/EidRequestHandler.php
typo3/sysext/frontend/Classes/Middleware/EidHandler.php

index 83d5c0f..45ecdf0 100644 (file)
@@ -66,7 +66,6 @@ class AjaxRequestHandler implements RequestHandlerInterface, PsrRequestHandlerIn
             'X-JSON' => 'true'
         ]);
 
-        /** @var RouteDispatcher $dispatcher */
         $dispatcher = GeneralUtility::makeInstance(RouteDispatcher::class);
         return $dispatcher->dispatch($request, $response);
     }
index d497ef3..5377191 100644 (file)
@@ -57,20 +57,10 @@ class RequestHandler implements RequestHandlerInterface, PsrRequestHandlerInterf
      */
     public function handle(ServerRequestInterface $request): ResponseInterface
     {
-        // Use a custom pre-created response for AJAX calls
-        // @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0: No prepared $response to RouteDispatcher any longer
-        if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX) {
-            $response = new Response('php://temp', 200, [
-                'Content-Type' => 'application/json; charset=utf-8',
-                'X-JSON' => 'true'
-            ]);
-        } else {
-            $response = new Response();
-        }
         try {
             // Check if the router has the available route and dispatch.
             $dispatcher = GeneralUtility::makeInstance(RouteDispatcher::class);
-            return $dispatcher->dispatch($request, $response);
+            return $dispatcher->dispatch($request);
         } catch (InvalidRequestTokenException $e) {
             // When token was invalid redirect to login
             $url = GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir;
index 0d4e539..7f97c7b 100644 (file)
@@ -20,7 +20,6 @@ use TYPO3\CMS\Backend\Routing\Exception\InvalidRequestTokenException;
 use TYPO3\CMS\Backend\Routing\Route;
 use TYPO3\CMS\Backend\Routing\Router;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
-use TYPO3\CMS\Core\Configuration\Features;
 use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
 use TYPO3\CMS\Core\Http\Dispatcher;
 use TYPO3\CMS\Core\Type\Bitmask\Permission;
@@ -36,12 +35,11 @@ class RouteDispatcher extends Dispatcher
      * Main method to resolve the route and checks the target of the route, and tries to call it.
      *
      * @param ServerRequestInterface $request the current server request
-     * @param ResponseInterface $response the prepared response @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0
      * @return ResponseInterface the filled response by the callable / controller/action
      * @throws InvalidRequestTokenException if the route was not found
      * @throws \InvalidArgumentException if the defined target for the route is invalid
      */
-    public function dispatch(ServerRequestInterface $request, ResponseInterface $response = null): ResponseInterface
+    public function dispatch(ServerRequestInterface $request): ResponseInterface
     {
         $router = GeneralUtility::makeInstance(Router::class);
         $route = $router->matchRequest($request);
@@ -57,33 +55,6 @@ class RouteDispatcher extends Dispatcher
         $targetIdentifier = $route->getOption('target');
         $target = $this->getCallableFromTarget($targetIdentifier);
         $arguments = [$request];
-
-        // @deprecated Test if target accepts one (ok) or two (deprecated) arguments
-        $scanForResponse = !GeneralUtility::makeInstance(Features::class)
-            ->isFeatureEnabled('simplifiedControllerActionDispatching');
-        if ($scanForResponse) {
-            if (is_array($targetIdentifier)) {
-                $controllerActionName = implode('::', $targetIdentifier);
-                $targetReflection = new \ReflectionMethod($controllerActionName);
-            } elseif (is_string($targetIdentifier) && strpos($targetIdentifier, '::') !== false) {
-                $controllerActionName = $targetIdentifier;
-                $targetReflection = new \ReflectionMethod($controllerActionName);
-            } elseif (is_callable($targetIdentifier)) {
-                $controllerActionName = 'closure function';
-                $targetReflection = new \ReflectionFunction($targetIdentifier);
-            } else {
-                $controllerActionName = $targetIdentifier . '::__invoke';
-                $targetReflection = new \ReflectionMethod($controllerActionName);
-            }
-            if ($targetReflection->getNumberOfParameters() >= 2) {
-                trigger_error(
-                    'Handing over second argument $response to controller action ' . $controllerActionName . '() is deprecated and will be removed in TYPO3 v10.0.',
-                    E_USER_DEPRECATED
-                );
-                $arguments[] = $response;
-            }
-        }
-
         return call_user_func_array($target, $arguments);
     }
 
index 1da41f0..213602c 100644 (file)
@@ -53,6 +53,20 @@ namespace TYPO3\CMS\Core\Configuration;
 class Features
 {
     /**
+     * A list of features that are always activated (mainly happens if a previous feature switch is now always
+     * "turned on" to enforce a behaviour, but still valid for extension authors to ensure the feature switch
+     * returns "enabled" for future versions.
+     *
+     * Usually, this list is kept for 1-2 major versions.
+     *
+     * @var array
+     */
+    protected $alwaysActiveFeatures = [
+        // Enabled in v10.0 at any time, feature switch will be completely ignored in TYPO3 v11.
+        'simplifiedControllerActionDispatching',
+    ];
+
+    /**
      * Checks if a feature is active
      *
      * @param string $featureName the name of the feature
@@ -60,6 +74,9 @@ class Features
      */
     public function isFeatureEnabled(string $featureName): bool
     {
+        if (in_array($featureName, $this->alwaysActiveFeatures, true)) {
+            return true;
+        }
         return isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['features'][$featureName]) && $GLOBALS['TYPO3_CONF_VARS']['SYS']['features'][$featureName] === true;
     }
 }
index 29e3342..56a556e 100644 (file)
@@ -16,7 +16,6 @@ namespace TYPO3\CMS\Core\Http;
 
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
-use TYPO3\CMS\Core\Configuration\Features;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -31,42 +30,14 @@ class Dispatcher implements DispatcherInterface
      * Main method that fetches the target from the request and calls the target directly
      *
      * @param ServerRequestInterface $request the current server request
-     * @param ResponseInterface $response the prepared response @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0
      * @return ResponseInterface the filled response by the callable/controller/action
      * @throws \InvalidArgumentException if the defined target is invalid
      */
-    public function dispatch(ServerRequestInterface $request, ResponseInterface $response = null): ResponseInterface
+    public function dispatch(ServerRequestInterface $request): ResponseInterface
     {
         $targetIdentifier = $request->getAttribute('target');
         $target = $this->getCallableFromTarget($targetIdentifier);
         $arguments = [$request];
-
-        // @deprecated Test if target accepts one (ok) or two (deprecated) arguments
-        $scanForResponse = !GeneralUtility::makeInstance(Features::class)
-            ->isFeatureEnabled('simplifiedControllerActionDispatching');
-        if ($scanForResponse) {
-            if (is_array($targetIdentifier)) {
-                $controllerActionName = implode('::', $targetIdentifier);
-                $targetReflection = new \ReflectionMethod($controllerActionName);
-            } elseif (is_string($targetIdentifier) && strpos($targetIdentifier, '::') !== false) {
-                $controllerActionName = $targetIdentifier;
-                $targetReflection = new \ReflectionMethod($controllerActionName);
-            } elseif (is_callable($targetIdentifier)) {
-                $controllerActionName = 'closure function';
-                $targetReflection = new \ReflectionFunction($targetIdentifier);
-            } else {
-                $controllerActionName = $targetIdentifier . '::__invoke';
-                $targetReflection = new \ReflectionMethod($controllerActionName);
-            }
-            if ($targetReflection->getNumberOfParameters() >= 2) {
-                trigger_error(
-                    'Handing over second argument $response to controller action ' . $controllerActionName . '() is deprecated and will be removed in TYPO3 v10.0.',
-                    E_USER_DEPRECATED
-                );
-                $arguments[] = $response;
-            }
-        }
-
         return call_user_func_array($target, $arguments);
     }
 
index 54ec536..1e90dd5 100644 (file)
@@ -75,7 +75,6 @@ return [
             'redirects.hitCount' => false,
             'unifiedPageTranslationHandling' => false,
             'TypoScript.strictSyntax' => true,
-            'simplifiedControllerActionDispatching' => false,
         ],
         'createGroup' => '',
         'sitename' => 'TYPO3',
index 121e8e8..e343626 100644 (file)
@@ -224,9 +224,6 @@ SYS:
               TypoScript.strictSyntax:
                 type: bool
                 description: 'If on, TypoScript is parsed in strict syntax modes. Enabling this feature means old condition syntax (which is deprecated) will trigger deprecation messages.'
-              simplifiedControllerActionDispatching:
-                type: bool
-                description: 'If on, controller actions of backend modules and eID scripts do not receive a deprecated prepared response object as second argument. Enabling this feature slightly improves performance.'
         availablePasswordHashAlgorithms:
             type: array
             description: 'A list of available password hash mechanisms. Extensions may register additional mechanisms here. This is usually not extended in LocalConfiguration.php.'
index 490ccef..d95aac0 100644 (file)
@@ -137,6 +137,7 @@ The following PHP static class methods that have been previously deprecated for
 
 The following methods changed signature according to previous deprecations in v9 at the end of the argument list:
 
+* :php:`TYPO3\CMS\Backend\Http\RouteDispatcher->dispatch() - Second argument dropped
 * :php:`TYPO3\CMS\Backend\Utility\BackendUtility::getPagesTSconfig()` - Second and third argument dropped
 * :php:`TYPO3\CMS\Core\Charset\CharsetConverter->conv()` - Fourth argument dropped
 * :php:`TYPO3\CMS\Core\Core\Bootstrap->checkIfEssentialConfigurationExists()` - First argument mandatory
@@ -145,6 +146,7 @@ The following methods changed signature according to previous deprecations in v9
 * :php:`TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash->getHashedPassword()` - Second argument dropped
 * :php:`TYPO3\CMS\Core\Crypto\PasswordHashing\Pbkdf2PasswordHash->getHashedPassword()` - Second argument dropped
 * :php:`TYPO3\CMS\Core\Crypto\PasswordHashing\PhpassPasswordHash->getHashedPassword()` - Second argument dropped
+* :php:`TYPO3\CMS\Core\Http\Dispatcher->dispatch() - Second argument dropped
 * :php:`TYPO3\CMS\Frontend\Page\PageRepository->getRawRecord()` - Fourth argument dropped
 
 
@@ -179,15 +181,18 @@ The following class properties have changed visibility:
 * :php:`TYPO3\CMS\Frontend\Page\PageRepository->sys_language_uid` changed from public to protected
 * :php:`TYPO3\CMS\Frontend\Page\PageRepository->versioningWorkspaceId` changed from public to protected
 
+
 The following scheduler tasks have been removed:
 
 * EXT:workspaces CleanupPreviewLinkTask
 * EXT:workspaces AutoPublishTask
 
+
 The following user TSconfig options have been dropped:
 
 * Prefix `mod.` to override page TSconfig is ignored
 
+
 The following constants have been dropped:
 
 * :php:`TYPO3\CMS\Core\Crypto\PasswordHashing\BlowfishPasswordHash::ITOA64`
@@ -220,6 +225,12 @@ The following global variables have been removed:
 
 * :php:`$GLOBALS['TYPO3_LOADED_EXT']`
 
+
+The following feature is now always enabled:
+
+* :php:`simplifiedControllerActionDispatching` - Backend controller actions do not receive a prepared response object anymore
+
+
 Impact
 ======
 
index f54467d..b383c34 100644 (file)
@@ -91,23 +91,19 @@ class EidRequestHandler implements RequestHandlerInterface, PsrRequestHandlerInt
         // Remove any output produced until now
         ob_clean();
 
-        /** @var Response $response */
-        $response = GeneralUtility::makeInstance(Response::class);
-
         $eID = $request->getParsedBody()['eID'] ?? $request->getQueryParams()['eID'] ?? '';
 
         if (empty($eID) || !isset($GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include'][$eID])) {
-            return $response->withStatus(404, 'eID not registered');
+            return (new Response())->withStatus(404, 'eID not registered');
         }
 
         $configuration = $GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include'][$eID];
 
         // Simple check to make sure that it's not an absolute file (to use the fallback)
         if (strpos($configuration, '::') !== false || is_callable($configuration)) {
-            /** @var Dispatcher $dispatcher */
             $dispatcher = GeneralUtility::makeInstance(Dispatcher::class);
             $request = $request->withAttribute('target', $configuration);
-            return $dispatcher->dispatch($request, $response);
+            return $dispatcher->dispatch($request);
         }
 
         $scriptPath = GeneralUtility::getFileAbsFileName($configuration);
index df9d2a1..dd4c1a3 100644 (file)
@@ -53,21 +53,17 @@ class EidHandler implements MiddlewareInterface
         // Remove any output produced until now
         ob_clean();
 
-        /** @var Response $response */
-        $response = GeneralUtility::makeInstance(Response::class);
-
         if (empty($eID) || !isset($GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include'][$eID])) {
-            return $response->withStatus(404, 'eID not registered');
+            return (new Response())->withStatus(404, 'eID not registered');
         }
 
         $configuration = $GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include'][$eID];
 
         // Simple check to make sure that it's not an absolute file (to use the fallback)
         if (strpos($configuration, '::') !== false || is_callable($configuration)) {
-            /** @var Dispatcher $dispatcher */
             $dispatcher = GeneralUtility::makeInstance(Dispatcher::class);
             $request = $request->withAttribute('target', $configuration);
-            return $dispatcher->dispatch($request, $response) ?? new NullResponse();
+            return $dispatcher->dispatch($request) ?? new NullResponse();
         }
         trigger_error(
             'eID "' . $eID . '" is registered with a script to a file. This behaviour will be removed in TYPO3 v10.0.'