|
2 | 2 |
|
3 | 3 | namespace DI\Bridge\Silex\Controller;
|
4 | 4 |
|
5 |
| -use DI\InvokerInterface; |
| 5 | +use Invoker\CallableResolver; |
| 6 | +use Invoker\Exception\NotCallableException; |
| 7 | +use Invoker\ParameterResolver\ParameterResolver; |
| 8 | +use Invoker\Reflection\CallableReflection; |
6 | 9 | use Symfony\Component\HttpFoundation\Request;
|
7 | 10 | use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
8 | 11 |
|
|
12 | 15 | class ControllerResolver implements ControllerResolverInterface
|
13 | 16 | {
|
14 | 17 | /**
|
15 |
| - * @var InvokerInterface |
| 18 | + * @var CallableResolver |
16 | 19 | */
|
17 |
| - private $invoker; |
| 20 | + private $callableResolver; |
18 | 21 |
|
19 |
| - public function __construct(InvokerInterface $invoker) |
| 22 | + /** |
| 23 | + * @var ParameterResolver |
| 24 | + */ |
| 25 | + private $parameterResolver; |
| 26 | + |
| 27 | + /** |
| 28 | + * Constructor. |
| 29 | + * |
| 30 | + * @param CallableResolver $callableResolver |
| 31 | + * @param ParameterResolver $parameterResolver |
| 32 | + */ |
| 33 | + public function __construct(CallableResolver $callableResolver, ParameterResolver $parameterResolver) |
20 | 34 | {
|
21 |
| - $this->invoker = $invoker; |
| 35 | + $this->callableResolver = $callableResolver; |
| 36 | + $this->parameterResolver = $parameterResolver; |
22 | 37 | }
|
23 | 38 |
|
24 | 39 | /**
|
25 | 40 | * {@inheritdoc}
|
26 | 41 | */
|
27 | 42 | public function getController(Request $request)
|
28 | 43 | {
|
29 |
| - $controller = $request->attributes->get('_controller'); |
30 |
| - |
31 |
| - if (! $controller) { |
32 |
| - throw new \LogicException('No controller can be found for this request'); |
| 44 | + if (! $controller = $request->attributes->get('_controller')) { |
| 45 | + throw new \LogicException(sprintf( |
| 46 | + 'Controller for URI "%s" could not be found because the "_controller" parameter is missing.', |
| 47 | + $request->getPathInfo() |
| 48 | + )); |
33 | 49 | }
|
34 | 50 |
|
35 |
| - return function () use ($request, $controller) { |
36 |
| - $parameters = [ |
37 |
| - 'request' => $request, |
38 |
| - ]; |
39 |
| - $parameters += $request->attributes->all(); |
40 |
| - |
41 |
| - return $this->invoker->call($controller, $parameters); |
42 |
| - }; |
| 51 | + try { |
| 52 | + return $this->callableResolver->resolve($controller); |
| 53 | + } catch (NotCallableException $e) { |
| 54 | + throw new \InvalidArgumentException(sprintf( |
| 55 | + 'Controller for URI "%s" is not callable: %s', |
| 56 | + $request->getPathInfo(), |
| 57 | + $e->getMessage() |
| 58 | + )); |
| 59 | + } |
43 | 60 | }
|
44 | 61 |
|
45 | 62 | /**
|
46 | 63 | * {@inheritdoc}
|
47 | 64 | */
|
48 | 65 | public function getArguments(Request $request, $controller)
|
49 | 66 | {
|
50 |
| - return array(); |
| 67 | + $controllerReflection = CallableReflection::create($controller); |
| 68 | + $controllerParameters = $controllerReflection->getParameters(); |
| 69 | + $resolvedArguments = []; |
| 70 | + |
| 71 | + foreach ($controllerParameters as $index => $parameter) { |
| 72 | + if ('request' === $parameter->getName() || ($parameter->getClass() && $parameter->getClass()->isInstance($request))) { |
| 73 | + $resolvedArguments[$index] = $request; |
| 74 | + |
| 75 | + break; |
| 76 | + } |
| 77 | + } |
| 78 | + |
| 79 | + $arguments = $this->parameterResolver->getParameters( |
| 80 | + $controllerReflection, |
| 81 | + $request->attributes->all(), |
| 82 | + $resolvedArguments |
| 83 | + ); |
| 84 | + |
| 85 | + ksort($arguments); |
| 86 | + |
| 87 | + // Check if all parameters are resolved |
| 88 | + $diff = array_diff_key($controllerParameters, $arguments); |
| 89 | + if (0 < count($diff)) { |
| 90 | + /** @var \ReflectionParameter $parameter */ |
| 91 | + $parameter = reset($diff); |
| 92 | + throw new \RuntimeException(sprintf( |
| 93 | + 'Controller "%s" requires that you provide a value for the "$%s" argument.', |
| 94 | + $controllerReflection->getName(), |
| 95 | + $parameter->getName() |
| 96 | + )); |
| 97 | + } |
| 98 | + |
| 99 | + return $arguments; |
51 | 100 | }
|
52 | 101 | }
|
0 commit comments