Completed
Push — master ( c628d7...8aa25c )
by Miloš
01:17
created

Container::addDefinition()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 2
dl 0
loc 8
ccs 4
cts 5
cp 0.8
crap 2.032
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Laganica\Di;
4
5
use InvalidArgumentException;
6
use Laganica\Di\Exception\ContainerException;
7
use Laganica\Di\Exception\NotFoundException;
8
use Laganica\Di\Resolver\ClassResolver;
9
use Laganica\Di\Resolver\ResolverFactoryInterface;
10
use Psr\Container\ContainerExceptionInterface;
11
use Psr\Container\ContainerInterface;
12
use Psr\Container\NotFoundExceptionInterface;
13
14
/**
15
 * Class Container
16
 *
17
 * @package Laganica\Di
18
 */
19
class Container implements ContainerInterface
20
{
21
    /**
22
     * @var array
23
     */
24
    private $definitions = [];
25
26
    /**
27
     * @var array
28
     */
29
    private $entries = [];
30
31
    /**
32
     * @var bool
33
     */
34
    private $autowire = true;
35
36
    /**
37
     * @var ResolverFactoryInterface
38
     */
39
    private $resolverFactory;
40
41
    /**
42
     * @param ResolverFactoryInterface $resolverFactory
43
     */
44 6
    public function __construct(ResolverFactoryInterface $resolverFactory)
45
    {
46 6
        $this->resolverFactory = $resolverFactory;
47 6
        $this->resolverFactory->setContainer($this);
48 6
    }
49
50
    /**
51
     * @inheritDoc
52
     */
53 6
    public function get($id)
54
    {
55 6
        if (!is_string($id)) {
56
            $type = gettype($id);
57
            throw new InvalidArgumentException("Argument \$id must be string, $type given");
58
        }
59
60 6
        if ($entry = $this->getEntry($id)) {
61
            return $entry;
62
        }
63
64 6
        if ($definition = $this->getDefinition($id)) {
65
            try {
66 6
                $resolver = $this->resolverFactory->create($definition);
67
68 6
                return $this->addEntry($id, $resolver->resolve($definition));
69
            } catch (InvalidArgumentException $ex) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
70
            }
71
        }
72
73 5
        if ($this->isAutowire()) {
74 5
            $resolver = new ClassResolver($this);
75
76 5
            return $this->addEntry($id, $resolver->resolve($id));
77
        }
78
79
        throw NotFoundException::create($id);
80
    }
81
82
    /**
83
     * @inheritDoc
84
     */
85
    public function has($id): bool
86
    {
87
        try {
88
            $this->get($id);
89
90
            return true;
91
        } catch (NotFoundExceptionInterface $ex) {
92
            return false;
93
        } catch (ContainerExceptionInterface $ex) {
94
            return true;
95
        }
96
    }
97
98
    /**
99
     * @param bool $autowire
100
     */
101 6
    public function setAutowire(bool $autowire): void
102
    {
103 6
        $this->autowire = $autowire;
104 6
    }
105
106 5
    public function isAutowire(): bool
107
    {
108 5
        return $this->autowire;
109
    }
110
111
    /**
112
     * @param array $definitions
113
     *
114
     * @throws ContainerException
115
     */
116 6
    public function addDefinitions(array $definitions): void
117
    {
118 6
        foreach ($definitions as $id => $definition) {
119 6
            $this->addDefinition($id, $definition);
120
        }
121 6
    }
122
123
    /**
124
     * @param string $id
125
     * @param $definition
126
     *
127
     * @throws ContainerException
128
     */
129 6
    public function addDefinition(string $id, $definition): void
130
    {
131 6
        if ($this->hasDefinition($id)) {
132
            throw new ContainerException("More than one definition is found for entry or class $id");
133
        }
134
135 6
        $this->definitions[$id] = $definition;
136 6
    }
137
138
    /**
139
     * @param string $id
140
     *
141
     * @return null|mixed
142
     */
143 6
    public function getDefinition(string $id)
144
    {
145 6
        return $this->definitions[$id] ?? null;
146
    }
147
148
    /**
149
     * @param string $id
150
     *
151
     * @return bool
152
     */
153 6
    public function hasDefinition(string $id): bool
154
    {
155 6
        return array_key_exists($id, $this->definitions);
156
    }
157
158
    /**
159
     * @param string $id
160
     * @param mixed $entry
161
     *
162
     * @return mixed
163
     */
164 6
    private function addEntry(string $id, $entry)
165
    {
166 6
        return $this->entries[$id] = $entry;
167
    }
168
169
    /**
170
     * @param string $id
171
     *
172
     * @return null|mixed
173
     */
174 6
    public function getEntry(string $id)
175
    {
176 6
        return $this->entries[$id] ?? null;
177
    }
178
}
179