Container   B
last analyzed

Coupling/Cohesion

Components 1
Dependencies 11

Complexity

Total Complexity 38

Size/Duplication

Total Lines 290
Duplicated Lines 0 %

Test Coverage

Coverage 96.08%

Importance

Changes 0
Metric Value
wmc 38
lcom 1
cbo 11
dl 0
loc 290
ccs 98
cts 102
cp 0.9608
rs 8.3999
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A share() 0 4 1
A addServiceProvider() 0 6 1
A extend() 0 18 4
A inflector() 0 4 1
A call() 0 4 1
A delegate() 0 10 2
A hasInDelegate() 0 10 3
A __construct() 0 18 4
A get() 0 16 3
A has() 0 12 4
A hasShared() 0 6 2
B add() 0 25 4
A getFromDelegate() 0 15 3
B getFromThisContainer() 0 26 5
1
<?php
2
3
namespace League\Container;
4
5
use Interop\Container\ContainerInterface as InteropContainerInterface;
6
use League\Container\Argument\RawArgumentInterface;
7
use League\Container\Definition\DefinitionFactory;
8
use League\Container\Definition\DefinitionFactoryInterface;
9
use League\Container\Definition\DefinitionInterface;
10
use League\Container\Exception\NotFoundException;
11
use League\Container\Inflector\InflectorAggregate;
12
use League\Container\Inflector\InflectorAggregateInterface;
13
use League\Container\ServiceProvider\ServiceProviderAggregate;
14
use League\Container\ServiceProvider\ServiceProviderAggregateInterface;
15
16
class Container implements ContainerInterface
17
{
18
    /**
19
     * @var \League\Container\Definition\DefinitionFactoryInterface
20
     */
21
    protected $definitionFactory;
22
23
    /**
24
     * @var \League\Container\Definition\DefinitionInterface[]
25
     */
26
    protected $definitions = [];
27
28
    /**
29
     * @var \League\Container\Definition\DefinitionInterface[]
30
     */
31
    protected $sharedDefinitions = [];
32
33
    /**
34
     * @var \League\Container\Inflector\InflectorAggregateInterface
35
     */
36
    protected $inflectors;
37
38
    /**
39
     * @var \League\Container\ServiceProvider\ServiceProviderAggregateInterface
40
     */
41
    protected $providers;
42
43
    /**
44
     * @var array
45
     */
46
    protected $shared = [];
47
48
    /**
49
     * @var \Interop\Container\ContainerInterface[]
50
     */
51
    protected $delegates = [];
52
53
    /**
54
     * Constructor.
55
     *
56
     * @param \League\Container\ServiceProvider\ServiceProviderAggregateInterface|null $providers
57
     * @param \League\Container\Inflector\InflectorAggregateInterface|null             $inflectors
58
     * @param \League\Container\Definition\DefinitionFactoryInterface|null             $definitionFactory
59
     */
60 57
    public function __construct(
61
        ServiceProviderAggregateInterface $providers         = null,
62
        InflectorAggregateInterface       $inflectors        = null,
63
        DefinitionFactoryInterface        $definitionFactory = null
64
    ) {
65
        // set required dependencies
66 57
        $this->providers         = (is_null($providers))
67 57
                                 ? (new ServiceProviderAggregate)->setContainer($this)
68 57
                                 : $providers->setContainer($this);
69
70 57
        $this->inflectors        = (is_null($inflectors))
71 57
                                 ? (new InflectorAggregate)->setContainer($this)
72 57
                                 : $inflectors->setContainer($this);
73
74 57
        $this->definitionFactory = (is_null($definitionFactory))
75 57
                                 ? (new DefinitionFactory)->setContainer($this)
76 57
                                 : $definitionFactory->setContainer($this);
77 57
    }
78
79
    /**
80
     * [email protected]}
81
     */
82 45
    public function get($alias, array $args = [])
83
    {
84
        try {
85 45
            return $this->getFromThisContainer($alias, $args);
86 21
        } catch (NotFoundException $exception) {
87 21
            if ($this->providers->provides($alias)) {
88 12
                $this->providers->register($alias);
89
90 12
                return $this->getFromThisContainer($alias, $args);
91
            }
92
93 9
            $resolved = $this->getFromDelegate($alias, $args);
94
95 6
            return $this->inflectors->inflect($resolved);
96
        }
97
    }
98
99
    /**
100
     * [email protected]}
101
     */
102 21
    public function has($alias)
103
    {
104 21
        if (array_key_exists($alias, $this->definitions) || $this->hasShared($alias)) {
105 15
            return true;
106
        }
107
108 9
        if ($this->providers->provides($alias)) {
109 3
            return true;
110
        }
111
112 9
        return $this->hasInDelegate($alias);
113
    }
114
115
    /**
116
     * Returns a boolean to determine if the container has a shared instance of an alias.
117
     *
118
     * @param  string  $alias
119
     * @param  boolean $resolved
120
     * @return boolean
121
     */
122 51
    public function hasShared($alias, $resolved = false)
123
    {
124 51
        $shared = ($resolved === false) ? array_merge($this->shared, $this->sharedDefinitions) : $this->shared;
125
126 51
        return (array_key_exists($alias, $shared));
127
    }
128
129
    /**
130
     * [email protected]}
131
     */
132 45
    public function add($alias, $concrete = null, $share = false)
133
    {
134 45
        unset($this->shared[$alias]);
135 45
        unset($this->definitions[$alias]);
136 45
        unset($this->sharedDefinitions[$alias]);
137
138 45
        if (is_null($concrete)) {
139 3
            $concrete = $alias;
140 3
        }
141
142 45
        $definition = $this->definitionFactory->getDefinition($alias, $concrete);
143
144 45
        if ($definition instanceof DefinitionInterface) {
145 39
            if ($share === false) {
146 18
                $this->definitions[$alias] = $definition;
147 18
            } else {
148 33
                $this->sharedDefinitions[$alias] = $definition;
149
            }
150
151 39
            return $definition;
152
        }
153
154
        // dealing with a value that cannot build a definition
155 6
        $this->shared[$alias] = $concrete;
156 6
    }
157
158
    /**
159
     * [email protected]}
160
     */
161 33
    public function share($alias, $concrete = null)
162
    {
163 33
        return $this->add($alias, $concrete, true);
164
    }
165
166
    /**
167
     * [email protected]}
168
     */
169 12
    public function addServiceProvider($provider)
170
    {
171 12
        $this->providers->add($provider);
172
173 12
        return $this;
174
    }
175
176
    /**
177
     * [email protected]}
178
     */
179 6
    public function extend($alias)
180
    {
181 6
        if ($this->providers->provides($alias)) {
182 3
            $this->providers->register($alias);
183 3
        }
184
185 6
        if (array_key_exists($alias, $this->definitions)) {
186 3
            return $this->definitions[$alias];
187
        }
188
189 6
        if (array_key_exists($alias, $this->sharedDefinitions)) {
190 3
            return $this->sharedDefinitions[$alias];
191
        }
192
193 3
        throw new NotFoundException(
194 3
            sprintf('Unable to extend alias (%s) as it is not being managed as a definition', $alias)
195 3
        );
196
    }
197
198
    /**
199
     * [email protected]}
200
     */
201
    public function inflector($type, callable $callback = null)
202
    {
203
        return $this->inflectors->add($type, $callback);
204
    }
205
206
    /**
207
     * [email protected]}
208
     */
209
    public function call(callable $callable, array $args = [])
210
    {
211
        return (new ReflectionContainer)->setContainer($this)->call($callable, $args);
212
    }
213
214
    /**
215
     * Delegate a backup container to be checked for services if it
216
     * cannot be resolved via this container.
217
     *
218
     * @param  \Interop\Container\ContainerInterface $container
219
     * @return $this
220
     */
221 9
    public function delegate(InteropContainerInterface $container)
222
    {
223 9
        $this->delegates[] = $container;
224
225 9
        if ($container instanceof ImmutableContainerAwareInterface) {
0 ignored issues
show
Bug introduced by Andreas Möller
The class League\Container\ImmutableContainerAwareInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
226 3
            $container->setContainer($this);
227 3
        }
228
229 9
        return $this;
230
    }
231
232
    /**
233
     * Returns true if service is registered in one of the delegated backup containers.
234
     *
235
     * @param  string $alias
236
     * @return boolean
237
     */
238 9
    public function hasInDelegate($alias)
239
    {
240 9
        foreach ($this->delegates as $container) {
241 3
            if ($container->has($alias)) {
242 3
                return true;
243
            }
244 9
        }
245
246 6
        return false;
247
    }
248
249
    /**
250
     * Attempt to get a service from the stack of delegated backup containers.
251
     *
252
     * @param  string $alias
253
     * @param  array  $args
254
     * @return mixed
255
     */
256 9
    protected function getFromDelegate($alias, array $args = [])
257
    {
258 9
        foreach ($this->delegates as $container) {
259 6
            if ($container->has($alias)) {
260 6
                return $container->get($alias, $args);
261
            }
262
263 3
            continue;
264 3
        }
265
266 3
        throw new NotFoundException(
267 3
            sprintf('Alias (%s) is not being managed by the container', $alias)
268 3
        );
269
270
    }
271
272
    /**
273
     * Get a service that has been registered in this container.
274
     *
275
     * @param  string $alias
276
     * @param  array $args
277
     * @return mixed
278
     */
279 45
    protected function getFromThisContainer($alias, array $args = [])
280
    {
281 45
        if ($this->hasShared($alias, true)) {
282 18
            $shared = $this->inflectors->inflect($this->shared[$alias]);
283 18
            if ($shared instanceof RawArgumentInterface) {
284 3
                return $shared->getValue();
285
            }
286 15
            return $shared;
287
        }
288
289 39
        if (array_key_exists($alias, $this->sharedDefinitions)) {
290 27
            $shared = $this->inflectors->inflect($this->sharedDefinitions[$alias]->build());
291 27
            $this->shared[$alias] = $shared;
292 27
            return $shared;
293
        }
294
295 30
        if (array_key_exists($alias, $this->definitions)) {
296 12
            return $this->inflectors->inflect(
297 12
                $this->definitions[$alias]->build($args)
298 12
            );
299
        }
300
301 21
        throw new NotFoundException(
302 21
            sprintf('Alias (%s) is not being managed by the container', $alias)
303 21
        );
304
    }
305
}
306