container = $container; } /** * Main method that fetches the target from the request and calls the target directly * * @param ServerRequestInterface $request the current server request * @return ResponseInterface the filled response by the callable/controller/action * @throws \InvalidArgumentException if the defined target is invalid */ public function dispatch(ServerRequestInterface $request): ResponseInterface { $targetIdentifier = $request->getAttribute('target'); $target = $this->getCallableFromTarget($targetIdentifier); $arguments = [$request]; return $target(...$arguments); } /** * Creates a callable out of the given parameter, which can be a string, a callable / closure or an array * which can be invoked as a function. * * @param array|string|callable $target the target which is being resolved. * @return callable * @throws \InvalidArgumentException */ protected function getCallableFromTarget($target) { if (is_array($target)) { return $target; } if ($target instanceof \Closure) { return $target; } // Only a class name is given if (is_string($target) && !str_contains($target, ':')) { $targetObject = $this->container->has($target) ? $this->container->get($target) : GeneralUtility::makeInstance($target); if (!method_exists($targetObject, '__invoke')) { throw new \InvalidArgumentException('Object "' . $target . '" doesn\'t implement an __invoke() method and cannot be used as target.', 1442431631); } return $targetObject; } // Check if the target is a concatenated string of "className::actionMethod" if (is_string($target) && str_contains($target, '::')) { [$className, $methodName] = explode('::', $target, 2); $targetObject = $this->container->has($className) ? $this->container->get($className) : GeneralUtility::makeInstance($className); return [$targetObject, $methodName]; } // Closures needs to be checked at last as a string with object::method is recognized as callable if (is_callable($target)) { return $target; } throw new \InvalidArgumentException('Invalid target for "' . $target . '", as it is not callable.', 1425381442); } }