MethodArgumentInspector   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 30
dl 0
loc 81
rs 10
c 1
b 0
f 0
wmc 13

4 Methods

Rating   Name   Duplication   Size   Complexity  
A arguments() 0 3 1
B parseAttribute() 0 23 7
A __construct() 0 6 1
A definedArguments() 0 19 4
1
<?php
2
3
/**
4
 * This file is part of di
5
 *
6
 * For the full copyright and license information, please view the LICENSE.md
7
 * file that was distributed with this source code.
8
 */
9
10
declare(strict_types=1);
11
12
namespace Slick\Di\Inspector;
13
14
use Psr\Container\ContainerExceptionInterface;
15
use Psr\Container\NotFoundExceptionInterface;
16
use ReflectionMethod;
17
use ReflectionParameter;
18
use Slick\Di\ContainerInterface;
19
use Slick\Di\Exception\NotFoundException;
20
21
/**
22
 * MethodArgumentInspector
23
 *
24
 * @package Slick\Di\Inspector
25
 */
26
final class MethodArgumentInspector
27
{
28
    private array $arguments;
29
30
    /**
31
     * Creates a MethodArgumentInspector
32
     *
33
     * @param ReflectionMethod $method
34
     * @param ContainerInterface $container
35
     * @param array $override
36
     * @throws ContainerExceptionInterface
37
     * @throws NotFoundExceptionInterface
38
     */
39
    public function __construct(
40
        private readonly ReflectionMethod $method,
41
        private readonly ContainerInterface $container,
42
        private readonly array $override = []
43
    ) {
44
        $this->arguments = array_replace($this->definedArguments(), $this->override);
45
    }
46
47
    public function arguments(): array
48
    {
49
        return $this->arguments;
50
    }
51
52
    /**
53
     * Get the list of arguments from constructor defined parameters
54
     *
55
     * @return array
56
     * @throws ContainerExceptionInterface
57
     * @throws NotFoundExceptionInterface
58
     */
59
    private function definedArguments(): array
60
    {
61
        $arguments = [];
62
63
        if (null === $this->method) {
64
            return $arguments;
65
        }
66
67
        $parameters = $this->method->getParameters();
68
        $count = 1;
69
        foreach ($parameters as $parameter) {
70
            if ($count++ <= count($this->override)) {
71
                $arguments[] = null;
72
                continue;
73
            }
74
75
            $this->parseAttribute($arguments, $parameter);
76
        }
77
        return $arguments;
78
    }
79
80
    /**
81
     * @throws ContainerExceptionInterface
82
     * @throws NotFoundExceptionInterface
83
     */
84
    private function parseAttribute(array &$arguments, ReflectionParameter $parameter): void
85
    {
86
        $name = $parameter->getName();
87
        $parameterType = $parameter->getType();
88
89
        $isBuiltInType = is_null($parameterType) || $parameterType->isBuiltin();
90
        $isNullable = !$this->container->has($name) && $parameter->allowsNull();
91
92
        if ($isBuiltInType) {
93
            $arguments[] = $isNullable ? null : $this->container->get($name);
94
            return;
95
        }
96
97
        try {
98
            $value = $this->container->get($parameterType->getName());
0 ignored issues
show
Bug introduced by
The method getName() does not exist on ReflectionType. It seems like you code against a sub-type of ReflectionType such as ReflectionNamedType. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

98
            $value = $this->container->get($parameterType->/** @scrutinizer ignore-call */ getName());
Loading history...
99
            $arguments[] = $value;
100
        } catch (NotFoundException $foundException) {
101
            if ($parameter->allowsNull()) {
102
                $arguments[] = null;
103
                return;
104
            }
105
106
            throw $foundException;
107
        }
108
    }
109
}
110