diff --git a/core/modules/rest/src/RequestHandler.php b/core/modules/rest/src/RequestHandler.php index 8e0cd74..652b5f6 100644 --- a/core/modules/rest/src/RequestHandler.php +++ b/core/modules/rest/src/RequestHandler.php @@ -2,12 +2,15 @@ namespace Drupal\rest; +use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Render\RenderContext; use Drupal\Core\Routing\RouteMatchInterface; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerAwareTrait; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException; use Symfony\Component\Serializer\Exception\UnexpectedValueException; @@ -16,11 +19,37 @@ /** * Acts as intermediate request forwarder for resource plugins. */ -class RequestHandler implements ContainerAwareInterface { +class RequestHandler implements ContainerAwareInterface, ContainerInjectionInterface { use ContainerAwareTrait; /** + * The controller resolver. + * + * @var \Symfony\Component\HttpKernel\Controller\ControllerResolverInterface + */ + protected $controllerResolver; + + /** + * Creates a new RequestHandler instance. + * + * @param \Symfony\Component\HttpKernel\Controller\ControllerResolverInterface $controller_resolver + * The controller resolver. + */ + public function __construct(ControllerResolverInterface $controller_resolver) { + $this->controllerResolver = $controller_resolver; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('controller_resolver') + ); + } + + /** * Handles a web API request. * * @param \Drupal\Core\Routing\RouteMatchInterface $route_match @@ -70,24 +99,17 @@ public function handle(RouteMatchInterface $route_match, Request $request) { } } - // Determine the request parameters that should be passed to the resource - // plugin. - $route_parameters = $route_match->getParameters(); - $parameters = array(); - // Filter out all internal parameters starting with "_". - foreach ($route_parameters as $key => $parameter) { - if ($key{0} !== '_') { - $parameters[] = $parameter; - } - } - // Invoke the operation on the resource plugin. // All REST routes are restricted to exactly one format, so instead of // parsing it out of the Accept headers again, we can simply retrieve the // format requirement. If there is no format associated, just pick JSON. $format = $route_match->getRouteObject()->getRequirement('_format') ?: 'json'; try { - $response = call_user_func_array(array($resource, $method), array_merge($parameters, array($unserialized, $request))); + $controller = [$resource, $method]; + $request = clone $request; + $request->attributes['data'] = $unserialized; + $arguments = $this->controllerResolver->getArguments($request, $controller); + $response = call_user_func_array($controller, $arguments); } catch (HttpException $e) { $error['error'] = $e->getMessage();