[TASK] Deprecate second controller action argument
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Http / Dispatcher.php
index 133bfe1..9b3a620 100644 (file)
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Core\Http;
 
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
+use TYPO3\CMS\Core\Configuration\Features;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -30,15 +31,43 @@ 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
      * 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
-     * @return ResponseInterface the filled response by the callable / controller/action
+     * @param ResponseInterface $response the prepared response @deprecated since v9, will be removed in v10
+     * @return ResponseInterface the filled response by the callable/controller/action
      * @throws \InvalidArgumentException if the defined target is invalid
      */
      * @throws \InvalidArgumentException if the defined target is invalid
      */
-    public function dispatch(ServerRequestInterface $request, ResponseInterface $response)
+    public function dispatch(ServerRequestInterface $request, ResponseInterface $response = null): ResponseInterface
     {
         $targetIdentifier = $request->getAttribute('target');
         $target = $this->getCallableFromTarget($targetIdentifier);
     {
         $targetIdentifier = $request->getAttribute('target');
         $target = $this->getCallableFromTarget($targetIdentifier);
-        return call_user_func_array($target, [$request, $response]);
+        $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 v10.',
+                    E_USER_DEPRECATED
+                );
+                $arguments[] = $response;
+            }
+        }
+
+        return call_user_func_array($target, $arguments);
     }
 
     /**
     }
 
     /**
@@ -75,7 +104,7 @@ class Dispatcher implements DispatcherInterface
             return [$targetObject, $methodName];
         }
 
             return [$targetObject, $methodName];
         }
 
-        // This needs to be checked at last as a string with object::method is recognize as callable
+        // Closures needs to be checked at last as a string with object::method is recognized as callable
         if (is_callable($target)) {
             return $target;
         }
         if (is_callable($target)) {
             return $target;
         }