Completed
Push — master ( 1a6c14...1a0ee4 )
by Andrey
02:15
created

AutowireItemResolver::resolveArgs()   B

Complexity

Conditions 10
Paths 9

Size

Total Lines 27
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 10.0125

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 21
c 1
b 0
f 0
nc 9
nop 1
dl 0
loc 27
ccs 19
cts 20
cp 0.95
crap 10.0125
rs 7.6666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Borodulin\Container\Autowire;
6
7
use Borodulin\Container\Autowire\Item\AliasItem;
8
use Borodulin\Container\Autowire\Item\BuiltInTypeItem;
9
use Borodulin\Container\Autowire\Item\CallableItem;
10
use Borodulin\Container\Autowire\Item\ClassItem;
11
use Borodulin\Container\Autowire\Item\DefaultValueItem;
12
use Borodulin\Container\Autowire\Item\VariadicItem;
13
use Borodulin\Container\Container;
14
use Borodulin\Container\ContainerException;
15
16
class AutowireItemResolver
17
{
18
    /**
19
     * @var Container
20
     */
21
    private $container;
22
23 11
    public function __construct(Container $container)
24
    {
25 11
        $this->container = $container;
26 11
    }
27
28 8
    public function resolve(AutowireItemInterface $item): object
29
    {
30 8
        if ($item instanceof AliasItem) {
31 1
            return $this->resolveAliasItem($item);
32 8
        } elseif ($item instanceof CallableItem) {
33 2
            return $this->resolveCallableItem($item);
34 6
        } elseif ($item instanceof ClassItem) {
35 6
            return $this->resolveClassItem($item);
36
        } else {
37
            throw new ContainerException('Unsupported autowire item type.');
38
        }
39
    }
40
41 1
    private function resolveAliasItem(AliasItem $aliasItem): object
42
    {
43 1
        $classItem = $aliasItem->getClassItem();
44 1
        if ($classItem instanceof ClassItem) {
45 1
            return $this->resolveClassItem($classItem);
46
        }
47
48 1
        return $this->container->get($aliasItem->getAlias());
49
    }
50
51 2
    private function resolveCallableItem(CallableItem $item)
52
    {
53 2
        $args = $this->resolveArgs($item->getArgs());
54
55 2
        return \call_user_func_array($item->getCallable(), $args);
56
    }
57
58 7
    private function resolveClassItem(ClassItem $item): object
59
    {
60 7
        $reflection = new \ReflectionClass($item->getClassName());
61 7
        $args = $this->resolveArgs($item->getArgs());
62
63 5
        return $args ? $reflection->newInstanceArgs($args) : $reflection->newInstance();
64
    }
65
66 8
    private function resolveArgs(array $args): array
67
    {
68 8
        $result = [];
69 8
        $parameterBug = $this->container->getParameterBag();
70 8
        foreach ($args as $arg) {
71 8
            if ($arg instanceof BuiltInTypeItem) {
72 5
                if (null !== $parameterBug && $parameterBug->has($arg->getParamName())) {
73 2
                    $result[] = $parameterBug->get($arg->getParamName());
74 3
                } elseif ($arg->isDefaultValueAvailable()) {
75 1
                    $result[] = $arg->getDefaultValue();
76
                } else {
77 5
                    throw new ContainerException(sprintf('Unable to autowire parameter %s', \get_class($arg)));
78
                }
79 4
            } elseif ($arg instanceof DefaultValueItem) {
80 1
                $result[] = $arg->getValue();
81 3
            } elseif ($arg instanceof ClassItem) {
82 2
                $result[] = $this->resolveClassItem($arg);
83 2
            } elseif ($arg instanceof AliasItem) {
84 1
                $result[] = $this->resolveAliasItem($arg);
85 1
            } elseif ($arg instanceof VariadicItem) {
86 1
                $this->resolveVariadicItem($result, $arg);
87
            } else {
88
                throw new ContainerException(sprintf('Unable to autowire parameter %s', \get_class($arg)));
89
            }
90
        }
91
92 6
        return $result;
93
    }
94
95 1
    private function resolveVariadicItem(array &$result, VariadicItem $item): void
96
    {
97 1
        if ($item->getArgs()) {
98 1
            foreach ($item->getArgs() as $arg) {
99 1
                if ($arg instanceof ClassItem) {
100 1
                    $result[] = $this->resolveClassItem($arg);
101
                }
102
            }
103
        } else {
104
            $result[] = null;
105
        }
106 1
    }
107
}
108