Passed
Push — main ( 57e5ef...e75ff3 )
by Breno
02:48
created

ReflectionClassResolver   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 55
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 20
dl 0
loc 55
rs 10
c 0
b 0
f 0
wmc 9

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A resolveClass() 0 20 4
A canResolve() 0 3 1
A resolveArguments() 0 10 3
1
<?php
2
declare(strict_types=1);
3
4
namespace Habemus\Autowiring;
5
6
use Habemus\Autowiring\Parameter\ParameterResolver;
7
use Habemus\Exception\NotFoundException;
8
use Habemus\Exception\NotInstantiableException;
9
use Habemus\Exception\UnresolvableParameterException;
10
use ReflectionClass;
11
use ReflectionFunctionAbstract;
12
use ReflectionMethod;
13
14
class ReflectionClassResolver implements ClassResolver
15
{
16
    /**
17
     * @var ParameterResolver
18
     */
19
    protected $parameterResolver;
20
21
    public function __construct(ParameterResolver $parameterResolver)
22
    {
23
        $this->parameterResolver = $parameterResolver;
24
    }
25
26
    /**
27
     * @inheritDoc
28
     */
29
    public function resolveClass(string $className, array $constructorArguments = [])
30
    {
31
        if (!$this->canResolve($className)) {
32
            throw NotFoundException::classNotFound($className);
33
        }
34
35
        $class = new ReflectionClass($className);
36
        if (!$class->isInstantiable()) {
37
            throw new NotInstantiableException($className);
38
        }
39
40
        $constructor = $class->getConstructor();
41
        if ($constructor instanceof ReflectionMethod) {
42
            return
43
                $class->newInstanceArgs(
44
                    $this->resolveArguments($constructor, $constructorArguments)
45
                );
46
        }
47
48
        return new $className();
49
    }
50
51
    public function resolveArguments(ReflectionFunctionAbstract $function, array $arguments = []): array
52
    {
53
        $params = [];
54
        foreach ($function->getParameters() as $parameter) {
55
            if (!$this->parameterResolver->resolve($parameter, $arguments, $params)) {
56
                throw UnresolvableParameterException::createForFunction($function, $parameter->getName());
57
            }
58
        }
59
60
        return $params;
61
    }
62
63
    /**
64
     * @inheritDoc
65
     */
66
    public function canResolve(string $className): bool
67
    {
68
        return class_exists($className);
69
    }
70
}
71