Container   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 194
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 22
Bugs 1 Features 0
Metric Value
wmc 33
eloc 69
dl 0
loc 194
ccs 77
cts 77
cp 1
rs 9.76
c 22
b 1
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 19 4
A inflector() 0 3 1
A add() 0 9 2
A addShared() 0 4 1
A defaultToShared() 0 4 1
A getNew() 0 3 1
A addServiceProvider() 0 4 1
A extend() 0 13 3
A delegate() 0 9 2
A has() 0 21 6
A get() 0 3 1
B resolve() 0 37 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace League\Container;
6
7
use League\Container\Definition\{DefinitionAggregate, DefinitionInterface, DefinitionAggregateInterface};
8
use League\Container\Exception\{NotFoundException, ContainerException};
9
use League\Container\Inflector\{InflectorAggregate, InflectorInterface, InflectorAggregateInterface};
10
use League\Container\ServiceProvider\{ServiceProviderAggregate,
11
    ServiceProviderAggregateInterface,
12
    ServiceProviderInterface};
13
use Psr\Container\ContainerInterface;
14
15
class Container implements DefinitionContainerInterface
16
{
17
    /**
18
     * @var boolean
19
     */
20
    protected $defaultToShared = false;
21
22
    /**
23
     * @var DefinitionAggregateInterface
24
     */
25
    protected $definitions;
26
27
    /**
28
     * @var ServiceProviderAggregateInterface
29
     */
30
    protected $providers;
31
32
    /**
33
     * @var InflectorAggregateInterface
34
     */
35
    protected $inflectors;
36
37
    /**
38
     * @var ContainerInterface[]
39
     */
40
    protected $delegates = [];
41
42 138
    public function __construct(
43
        ?DefinitionAggregateInterface $definitions = null,
44
        ?ServiceProviderAggregateInterface $providers = null,
45
        ?InflectorAggregateInterface $inflectors = null
46
    ) {
47 138
        $this->definitions = $definitions ?? new DefinitionAggregate();
48 138
        $this->providers   = $providers   ?? new ServiceProviderAggregate();
49 138
        $this->inflectors  = $inflectors  ?? new InflectorAggregate();
50
51 138
        if ($this->definitions instanceof ContainerAwareInterface) {
0 ignored issues
show
introduced by
$this->definitions is always a sub-type of League\Container\ContainerAwareInterface.
Loading history...
52 138
            $this->definitions->setContainer($this);
53
        }
54
55 138
        if ($this->providers instanceof ContainerAwareInterface) {
0 ignored issues
show
introduced by
$this->providers is always a sub-type of League\Container\ContainerAwareInterface.
Loading history...
56 138
            $this->providers->setContainer($this);
57
        }
58
59 138
        if ($this->inflectors instanceof ContainerAwareInterface) {
0 ignored issues
show
introduced by
$this->inflectors is always a sub-type of League\Container\ContainerAwareInterface.
Loading history...
60 138
            $this->inflectors->setContainer($this);
61
        }
62
    }
63
64 36
    public function add(string $id, $concrete = null): DefinitionInterface
65
    {
66 36
        $concrete = $concrete ?? $id;
67
68 36
        if (true === $this->defaultToShared) {
69 3
            return $this->addShared($id, $concrete);
70
        }
71
72 33
        return $this->definitions->add($id, $concrete);
73
    }
74
75 6
    public function addShared(string $id, $concrete = null): DefinitionInterface
76
    {
77 6
        $concrete = $concrete ?? $id;
78 6
        return $this->definitions->addShared($id, $concrete);
79
    }
80
81 3
    public function defaultToShared(bool $shared = true): ContainerInterface
82
    {
83 3
        $this->defaultToShared = $shared;
84 3
        return $this;
85
    }
86
87 9
    public function extend(string $id): DefinitionInterface
88
    {
89 9
        if ($this->providers->provides($id)) {
90 3
            $this->providers->register($id);
91
        }
92
93 9
        if ($this->definitions->has($id)) {
94 6
            return $this->definitions->getDefinition($id);
95
        }
96
97 3
        throw new NotFoundException(sprintf(
98 3
            'Unable to extend alias (%s) as it is not being managed as a definition',
99 3
            $id
100 3
        ));
101
    }
102
103 9
    public function addServiceProvider(ServiceProviderInterface $provider): DefinitionContainerInterface
104
    {
105 9
        $this->providers->add($provider);
106 9
        return $this;
107
    }
108
109
    /**
110
     * @template RequestedType
111
     *
112
     * @param class-string<RequestedType>|string $id
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<RequestedType>|string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<RequestedType>|string.
Loading history...
113
     *
114
     * @return RequestedType|mixed
115
     */
116 45
    public function get($id)
117
    {
118 45
        return $this->resolve($id);
119
    }
120
121
    /**
122
     * @template RequestedType
123
     *
124
     * @param class-string<RequestedType>|string $id
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<RequestedType>|string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<RequestedType>|string.
Loading history...
125
     *
126
     * @return RequestedType|mixed
127
     */
128 3
    public function getNew($id)
129
    {
130 3
        return $this->resolve($id, true);
131
    }
132
133 48
    public function has($id): bool
134
    {
135 48
        if ($this->definitions->has($id)) {
136 27
            return true;
137
        }
138
139 27
        if ($this->definitions->hasTag($id)) {
140 6
            return true;
141
        }
142
143 21
        if ($this->providers->provides($id)) {
144 6
            return true;
145
        }
146
147 15
        foreach ($this->delegates as $delegate) {
148 6
            if ($delegate->has($id)) {
149 6
                return true;
150
            }
151
        }
152
153 9
        return false;
154
    }
155
156 3
    public function inflector(string $type, ?callable $callback = null): InflectorInterface
157
    {
158 3
        return $this->inflectors->add($type, $callback);
159
    }
160
161 9
    public function delegate(ContainerInterface $container): self
162
    {
163 9
        $this->delegates[] = $container;
164
165 9
        if ($container instanceof ContainerAwareInterface) {
166 9
            $container->setContainer($this);
167
        }
168
169 9
        return $this;
170
    }
171
172 45
    protected function resolve($id, bool $new = false)
173
    {
174 45
        if ($this->definitions->has($id)) {
175 27
            $resolved = (true === $new) ? $this->definitions->resolveNew($id) : $this->definitions->resolve($id);
176 27
            return $this->inflectors->inflect($resolved);
177
        }
178
179 24
        if ($this->definitions->hasTag($id)) {
180 6
            $arrayOf = (true === $new)
181 3
                ? $this->definitions->resolveTaggedNew($id)
182 6
                : $this->definitions->resolveTagged($id);
183
184 6
            array_walk($arrayOf, function (&$resolved) {
185 6
                $resolved = $this->inflectors->inflect($resolved);
186 6
            });
187
188 6
            return $arrayOf;
189
        }
190
191 18
        if ($this->providers->provides($id)) {
192 6
            $this->providers->register($id);
193
194 6
            if (!$this->definitions->has($id) && !$this->definitions->hasTag($id)) {
195 3
                throw new ContainerException(sprintf('Service provider lied about providing (%s) service', $id));
196
            }
197
198 3
            return $this->resolve($id, $new);
199
        }
200
201 12
        foreach ($this->delegates as $delegate) {
202 9
            if ($delegate->has($id)) {
203 9
                $resolved = $delegate->get($id);
204 9
                return $this->inflectors->inflect($resolved);
205
            }
206
        }
207
208 3
        throw new NotFoundException(sprintf('Alias (%s) is not being managed by the container or delegates', $id));
209
    }
210
}
211