Test Failed
Pull Request — master (#1128)
by Aleksei
11:45
created

AutowireHandler   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 50
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 5
eloc 16
dl 0
loc 50
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A handle() 0 26 3
A resolveArguments() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Interceptors\Handler;
6
7
use Psr\Container\ContainerExceptionInterface;
8
use Psr\Container\ContainerInterface;
9
use Spiral\Core\ResolverInterface;
10
use Spiral\Interceptors\Context\CallContextInterface;
11
use Spiral\Interceptors\Exception\TargetCallException;
12
use Spiral\Interceptors\HandlerInterface;
13
use Spiral\Interceptors\Internal\ActionResolver;
14
15
/**
16
 * Handler resolves missing arguments from the container.
17
 * It requires the Target to explicitly point to a method or function.
18
 */
19
final class AutowireHandler implements HandlerInterface
20
{
21
    public function __construct(
22
        /** @internal */
23
        protected ContainerInterface $container,
24
    ) {
25
    }
26
27
    /**
28
     * @psalm-assert class-string $controller
29
     * @psalm-assert non-empty-string $action
30
     * @throws \Throwable
31
     */
32
    public function handle(CallContextInterface $context): mixed
33
    {
34
        // Resolve controller method
35
        $method = $context->getTarget()->getReflection() ?? throw new TargetCallException(
36
            "Reflection not provided for target `{$context->getTarget()}`.",
37
            TargetCallException::NOT_FOUND,
38
        );
39
        $path = $context->getTarget()->getPath();
40
41
        if ($method instanceof \ReflectionFunction) {
42
            return $method->invokeArgs(
43
                $this->resolveArguments($method, $context)
44
            );
45
        }
46
47
        if (!$method instanceof \ReflectionMethod) {
48
            throw new TargetCallException("Action not found for target `{$context->getTarget()}`.");
49
        }
50
51
        $controller = $context->getTarget()->getObject() ?? $this->container->get(\reset($path));
52
53
        // Validate method and controller
54
        ActionResolver::validateControllerMethod($method, $controller);
55
56
        // Run action
57
        return $method->invokeArgs($controller, $this->resolveArguments($method, $context));
58
    }
59
60
    /**
61
     * @throws ContainerExceptionInterface
62
     */
63
    protected function resolveArguments(\ReflectionFunctionAbstract $method, CallContextInterface $context): array
64
    {
65
        $resolver = $this->container->get(ResolverInterface::class);
66
        \assert($resolver instanceof ResolverInterface);
67
68
        return $resolver->resolveArguments($method, $context->getArguments());
69
    }
70
}
71