ContainerBuilder   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 103
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 30
dl 0
loc 103
ccs 38
cts 38
cp 1
rs 10
c 0
b 0
f 0
wmc 14

6 Methods

Rating   Name   Duplication   Size   Complexity  
A registerProvider() 0 8 2
A __construct() 0 3 1
A registerConfiguration() 0 4 2
A getWiredParameters() 0 30 6
A registerAutowiredClasses() 0 8 2
A getContainer() 0 3 1
1
<?php
2
3
namespace Simply\Container;
4
5
use Simply\Container\Entry\CallableEntry;
6
use Simply\Container\Entry\MixedEntry;
7
use Simply\Container\Entry\ProviderEntry;
8
use Simply\Container\Entry\WiredEntry;
9
use Simply\Container\Exception\ContainerException;
10
11
/**
12
 * Class that provides convenience functionality for setting up containers.
13
 *
14
 * @author Riikka Kalliomäki <[email protected]>
15
 * @copyright Copyright (c) 2018 Riikka Kalliomäki
16
 * @license http://opensource.org/licenses/mit-license.php MIT License
17
 */
18
class ContainerBuilder
19
{
20
    /** @var Container The container that is being built */
21
    private $container;
22
23
    /**
24
     * ContainerBuilder constructor.
25
     */
26 4
    public function __construct()
27
    {
28 4
        $this->container = new Container();
29 4
    }
30
31
    /**
32
     * Returns the container that is being built.
33
     * @return Container The container that is being built
34
     */
35 3
    public function getContainer(): Container
36
    {
37 3
        return $this->container;
38
    }
39
40
    /**
41
     * Registers an array with identifier value pairs to the container as mixed entries.
42
     * @param array $configuration The configuration array to register
43
     * @throws ContainerException If trying to register values that already exist
44
     */
45 2
    public function registerConfiguration(array $configuration): void
46
    {
47 2
        foreach ($configuration as $identifier => $value) {
48 2
            $this->container->addEntry($identifier, new MixedEntry($value));
49
        }
50 2
    }
51
52
    /**
53
     * Registers the given provider as a callable and applicable methods as provider methods.
54
     * @param EntryProvider $provider The entry provider to register
55
     * @throws ContainerException If the provider tries to provide something that has already been registered
56
     */
57 1
    public function registerProvider(EntryProvider $provider): void
58
    {
59 1
        $class = \get_class($provider);
60
61 1
        $this->container->addEntry($class, new CallableEntry([\get_class($provider), 'initialize']));
62
63 1
        foreach ($provider->getMethods() as $identifier => $method) {
64 1
            $this->container->addEntry($identifier, new ProviderEntry([$provider, $method]));
65
        }
66 1
    }
67
68
    /**
69
     * Registers classes that can be wired automatically based on constructor arguments.
70
     * @param string[] $classes List of classes to register for autowiring
71
     * @param string[] $overrides Override identifiers for constructor parameters
72
     * @throws ContainerException If trying to register classes that have already been registered
73
     */
74 2
    public function registerAutowiredClasses(array $classes, array $overrides = []): void
75
    {
76 2
        foreach ($classes as $class) {
77 2
            $reflection = new \ReflectionClass($class);
78 2
            $name = $reflection->getName();
79 2
            $parameters = $this->getWiredParameters($reflection, $overrides);
80
81 1
            $this->container->addEntry($name, new WiredEntry($name, $parameters));
82
        }
83 1
    }
84
85
    /**
86
     * Loads the parameter identifiers based on the constructor arguments and provided overrides.
87
     * @param \ReflectionClass $reflection The class reflection to inspect
88
     * @param string[] $overrides Override identifiers for constructor parameters
89
     * @return string[] Identifiers for constructor parameters
90
     */
91 2
    private function getWiredParameters(\ReflectionClass $reflection, array $overrides): array
92
    {
93 2
        $constructor = $reflection->getConstructor();
94
95 2
        if (!$constructor instanceof \ReflectionMethod) {
0 ignored issues
show
introduced by
$constructor is always a sub-type of ReflectionMethod.
Loading history...
96 1
            return [];
97
        }
98
99 2
        $parameters = [];
100
101 2
        foreach ($constructor->getParameters() as $parameter) {
102 2
            $name = '$' . $parameter->getName();
103
104 2
            if (isset($overrides[$name])) {
105 1
                $parameters[] = $overrides[$name];
106 1
                continue;
107
            }
108
109 2
            $type = $parameter->getType();
110
111 2
            if (!$type instanceof \ReflectionType || $type->isBuiltin()) {
112 1
                throw new \InvalidArgumentException(
113 1
                    sprintf("Missing autowired parameter '%s' for '%s'", $name, $reflection->getName())
114
                );
115
            }
116
117 1
            $parameters[] = $type->getName();
118
        }
119
120 1
        return $parameters;
121
    }
122
}
123