ArgumentResolverTrait   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 97
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 18
eloc 48
c 4
b 0
f 0
dl 0
loc 97
ccs 47
cts 47
cp 1
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
C resolveArguments() 0 48 12
B reflectArguments() 0 42 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace League\Container\Argument;
6
7
use League\Container\DefinitionContainerInterface;
8
use League\Container\Exception\{ContainerException, NotFoundException};
9
use League\Container\ReflectionContainer;
10
use Psr\Container\ContainerInterface;
11
use ReflectionFunctionAbstract;
12
use ReflectionNamedType;
13
14
trait ArgumentResolverTrait
15
{
16 114
    public function resolveArguments(array $arguments): array
17
    {
18
        try {
19 114
            $container = $this->getContainer();
20 51
        } catch (ContainerException $e) {
21 51
            $container = ($this instanceof ReflectionContainer) ? $this : null;
22
        }
23
24 114
        foreach ($arguments as &$arg) {
25
            // if we have a literal, we don't want to do anything more with it
26 78
            if ($arg instanceof LiteralArgumentInterface) {
27 12
                $arg = $arg->getValue();
28 12
                continue;
29
            }
30
31 75
            if ($arg instanceof ArgumentInterface) {
32 39
                $argValue = $arg->getValue();
33
            } else {
34 36
                $argValue = $arg;
35
            }
36
37 75
            if (!is_string($argValue)) {
38 12
                 continue;
39
            }
40
41
            // resolve the argument from the container, if it happens to be another
42
            // argument wrapper, use that value
43 66
            if ($container instanceof ContainerInterface && $container->has($argValue)) {
44
                try {
45 57
                    $arg = $container->get($argValue);
46
47 54
                    if ($arg instanceof ArgumentInterface) {
48 3
                        $arg = $arg->getValue();
49
                    }
50
51 54
                    continue;
52 3
                } catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
53
                }
54
            }
55
56
            // if we have a default value, we use that, no more resolution as
57
            // we expect a default/optional argument value to be literal
58 18
            if ($arg instanceof DefaultValueInterface) {
59 6
                $arg = $arg->getDefaultValue();
60
            }
61
        }
62
63 114
        return $arguments;
64
    }
65
66 48
    public function reflectArguments(ReflectionFunctionAbstract $method, array $args = []): array
67
    {
68 48
        $params    = $method->getParameters();
69 48
        $arguments = [];
70
71 48
        foreach ($params as $param) {
72 48
            $name = $param->getName();
73
74
            // if we've been given a value for the argument, treat as literal
75 48
            if (array_key_exists($name, $args)) {
76 6
                $arguments[] = new LiteralArgument($args[$name]);
77 6
                continue;
78
            }
79
80 45
            $type = $param->getType();
81
82 45
            if ($type instanceof ReflectionNamedType) {
83
                // in PHP 8, nullable arguments have "?" prefix
84 39
                $typeHint = ltrim($type->getName(), '?');
85
86 39
                if ($param->isDefaultValueAvailable()) {
87 27
                    $arguments[] = new DefaultValueArgument($typeHint, $param->getDefaultValue());
88 27
                    continue;
89
                }
90
91 18
                $arguments[] = new ResolvableArgument($typeHint);
92 18
                continue;
93
            }
94
95 12
            if ($param->isDefaultValueAvailable()) {
96 6
                $arguments[] = new LiteralArgument($param->getDefaultValue());
97 6
                continue;
98
            }
99
100 6
            throw new NotFoundException(sprintf(
101 6
                'Unable to resolve a value for parameter (%s) in the function/method (%s)',
102 6
                $name,
103 6
                $method->getName()
104 6
            ));
105
        }
106
107 42
        return $this->resolveArguments($arguments);
108
    }
109
110
    abstract public function getContainer(): DefinitionContainerInterface;
111
}
112