Completed
Push — master ( 1a0ee4...8fb63d )
by Andrey
02:06
created

ClassItemBuilder::buildClassItem()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 10
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 15
ccs 10
cts 10
cp 1
crap 3
rs 9.9332
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Borodulin\Container\Autowire;
6
7
use Borodulin\Container\Autowire\Item\ClassItem;
8
use Borodulin\Container\ContainerException;
9
use Borodulin\Container\NotFoundException;
10
11
class ClassItemBuilder
12
{
13
    /**
14
     * @var ItemProvider
15
     */
16
    private $itemProvider;
17
    /**
18
     * @var array
19
     */
20
    private $buildClasses;
21
22 14
    public function __construct(ItemProvider $itemProvider)
23
    {
24 14
        $this->itemProvider = $itemProvider;
25 14
    }
26
27 14
    public function build(string $className): AutowireItemInterface
28
    {
29 14
        if ($this->itemProvider->hasItem($className)) {
30 6
            return $this->itemProvider->getItem($className);
31
        }
32 14
        if (class_exists($className)) {
33 13
            if (isset($this->buildClasses[$className])) {
34 1
                throw new ContainerException("$className has circular reference dependency.");
35
            }
36 13
            $this->buildClasses[$className] = true;
37 13
            $classItem = $this->buildClassItem($className);
38 11
            $this->itemProvider->addItem($className, $classItem);
39
40 11
            return $classItem;
41
        } else {
42 1
            throw new NotFoundException($className);
43
        }
44
    }
45
46 13
    private function buildClassItem($className): ClassItem
47
    {
48 13
        $reflection = new \ReflectionClass($className);
49 13
        if (!$reflection->isInstantiable()) {
50 1
            throw new ContainerException("$className is not instantiable.");
51
        }
52 12
        $constructor = $reflection->getConstructor();
53 12
        if (null !== $constructor) {
54 12
            $args = (new DependencyBuilder($this->itemProvider, $this))
55 12
                ->buildParameters($constructor->getParameters());
56
        } else {
57 2
            $args = [];
58
        }
59
60 11
        return new ClassItem($className, $args);
61
    }
62
}
63