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

AutowireItemResolver   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Test Coverage

Coverage 93.88%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 47
c 1
b 0
f 0
dl 0
loc 89
ccs 46
cts 49
cp 0.9388
rs 10
wmc 24

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A resolveClassItem() 0 6 2
A resolveAliasItem() 0 8 2
B resolveArgs() 0 27 10
A resolveCallableItem() 0 5 1
A resolveVariadicItem() 0 10 4
A resolve() 0 10 4
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