Completed
Push — master ( 8eb05e...3661d0 )
by Miloš
01:25
created

Container::addEntry()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
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)) && $resolver = $this->resolverFactory->create($definition)) {
65 6
            return $this->addEntry($id, $resolver->resolve($definition));
66
        }
67
68 5
        if ($this->isAutowire()) {
69 5
            $resolver = new ClassResolver($this);
70
71 5
            return $this->addEntry($id, $resolver->resolve($id));
72
        }
73
74
        throw NotFoundException::create($id);
75
    }
76
77
    /**
78
     * @inheritDoc
79
     */
80
    public function has($id): bool
81
    {
82
        try {
83
            $this->get($id);
84
85
            return true;
86
        } catch (NotFoundExceptionInterface $ex) {
87
            return false;
88
        } catch (ContainerExceptionInterface $ex) {
89
            return true;
90
        }
91
    }
92
93
    /**
94
     * @param bool $autowire
95
     */
96 6
    public function setAutowire(bool $autowire): void
97
    {
98 6
        $this->autowire = $autowire;
99 6
    }
100
101 5
    public function isAutowire(): bool
102
    {
103 5
        return $this->autowire;
104
    }
105
106
    /**
107
     * @param array $definitions
108
     *
109
     * @throws ContainerException
110
     */
111 6
    public function addDefinitions(array $definitions): void
112
    {
113 6
        foreach ($definitions as $id => $definition) {
114 6
            $this->addDefinition($id, $definition);
115
        }
116 6
    }
117
118
    /**
119
     * @param string $id
120
     * @param $definition
121
     *
122
     * @throws ContainerException
123
     */
124 6
    public function addDefinition(string $id, $definition): void
125
    {
126 6
        if ($this->hasDefinition($id)) {
127
            throw new ContainerException("More than one definition is found for entry or class $id");
128
        }
129
130 6
        $this->definitions[$id] = $definition;
131 6
    }
132
133
    /**
134
     * @param string $id
135
     *
136
     * @return null|mixed
137
     */
138 6
    public function getDefinition(string $id)
139
    {
140 6
        return $this->definitions[$id] ?? null;
141
    }
142
143
    /**
144
     * @param string $id
145
     *
146
     * @return bool
147
     */
148 6
    public function hasDefinition(string $id): bool
149
    {
150 6
        return array_key_exists($id, $this->definitions);
151
    }
152
153
    /**
154
     * @param string $id
155
     * @param mixed $entry
156
     *
157
     * @return mixed
158
     */
159 6
    private function addEntry(string $id, $entry)
160
    {
161 6
        return $this->entries[$id] = $entry;
162
    }
163
164
    /**
165
     * @param string $id
166
     *
167
     * @return null|mixed
168
     */
169 6
    public function getEntry(string $id)
170
    {
171 6
        return $this->entries[$id] ?? null;
172
    }
173
}
174