Completed
Pull Request — master (#126)
by Phil
11:08
created

Container   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 170
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 6
dl 0
loc 170
ccs 50
cts 50
cp 1
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A add() 0 6 1
A extend() 0 14 3
A addServiceProvider() 0 6 1
B get() 0 21 5
B has() 0 18 5
A inflector() 0 4 1
A delegate() 0 10 2
1
<?php declare(strict_types=1);
2
3
namespace League\Container;
4
5
use League\Container\Definition\{DefinitionAggregate, DefinitionInterface, DefinitionAggregateInterface};
6
use League\Container\Inflector\{InflectorAggregate, InflectorInterface, InflectorAggregateInterface};
7
use League\Container\ServiceProvider\{ServiceProviderAggregate, ServiceProviderAggregateInterface};
8
use Psr\Container\ContainerInterface;
9
10
class Container implements ContainerInterface
11
{
12
    /**
13
     * @var \League\Container\Definition\DefinitionAggregateInterface
14
     */
15
    protected $definitions;
16
17
    /**
18
     * @var \League\Container\ServiceProvider\ServiceProviderAggregateInterface
19
     */
20
    protected $providers;
21
22
    /**
23
     * @var \League\Container\Inflector\InflectorAggregateInterface
24
     */
25
    protected $inflectors;
26
27
    /**
28
     * @var \Psr\Container\ContainerInterface
29
     */
30
    protected $delegates = [];
31
32
    /**
33
     * Construct.
34
     *
35
     * @param \League\Container\Definition\DefinitionAggregateInterface|null           $definitions
36
     * @param \League\Container\ServiceProvider\ServiceProviderAggregateInterface|null $providers
37
     * @param \League\Container\Inflector\InflectorAggregateInterface|null             $inflectors
38
     */
39
    public function __construct(
40
        DefinitionAggregateInterface      $definitions = null,
41
        ServiceProviderAggregateInterface $providers   = null,
42
        InflectorAggregateInterface       $inflectors  = null
43
    ) {
44
        $this->definitions = $definitions ?? (new DefinitionAggregate)->setContainer($this);
45
        $this->providers   = $providers   ?? (new ServiceProviderAggregate)->setContainer($this);
46
        $this->inflectors  = $inflectors  ?? (new InflectorAggregate)->setContainer($this);
47
    }
48
49
    /**
50
     * Add an item to the container.
51
     *
52
     * @param string  $id
53
     * @param mixed   $concrete
54
     * @param boolean $shared
55
     *
56
     * @return \League\Container\Definition\DefinitionInterface
57
     */
58
    public function add(string $id, $concrete = null, bool $shared = false): DefinitionInterface
59
    {
60 57
        $concrete = $concrete ?? $id;
61
62
        return $this->definitions->add($id, $concrete, $shared);
63
    }
64
65
    /**
66 57
     * Get a definition to extend.
67 56
     *
68 39
     * @param string $id [description]
69
     *
70 57
     * @return \League\Container\Definition\DefinitionInterface
71 57
     */
72 38
    public function extend(string $id): DefinitionInterface
73
    {
74 57
        if ($this->providers->provides($id)) {
75 57
            $this->providers->register($id);
76 38
        }
77 57
78
        if ($this->definitions->has($id)) {
79
            return $this->definitions->getDefinition($id);
80
        }
81
82 45
        throw new NotFoundException(
83
            sprintf('Unable to extend alias (%s) as it is not being managed as a definition', $alias)
84
        );
85 45
    }
86 21
87 21
    /**
88 12
     * Add a service provider.
89
     *
90 12
     * @param \League\Container\ServiceProvider\ServiceProviderInterface|string $provider
91
     *
92
     * @return self
93 9
     */
94
    public function addServiceProvider($provider): self
95 6
    {
96
        $this->providers->add($provider);
97
98
        return $this;
99
    }
100
101
    /**
102 21
     * {@inheritdoc}
103
     */
104 21
    public function get($id, array $args = [], bool $new = false)
105 15
    {
106
        if ($this->definitions->has($id)) {
107
            $resolved = $this->definitions->resolve($id, $args, $new);
108 9
            return $this->inflectors->inflect($resolved);
109 3
        }
110
111
        if ($this->providers->provides($id)) {
112 9
            $this->providers->register($id);
113
            return $this->get($id, $args, $new);
114
        }
115
116
        foreach ($this->delegates as $delegate) {
0 ignored issues
show
Bug introduced by
The expression $this->delegates of type object<Psr\Container\ContainerInterface> is not traversable.
Loading history...
117
            if ($delegate->has($id)) {
118
                $resolved = $delegate->get($id, $args);
119
                return $this->inflectors->inflect($resolved);
120
            }
121
        }
122 51
123
        throw new NotFoundException(sprintf('Alias (%s) is not being managed by the container or delegates', $id));
124 51
    }
125
126 51
    /**
127
     * {@inheritdoc}
128
     */
129
    public function has($id): bool
130
    {
131
        if ($this->definitions->has($id)) {
132 45
            return true;
133
        }
134 45
135 45
        if ($this->providers->provides($id)) {
136 45
            return true;
137
        }
138 45
139 3
        foreach ($this->delegates as $delegate) {
0 ignored issues
show
Bug introduced by
The expression $this->delegates of type object<Psr\Container\ContainerInterface> is not traversable.
Loading history...
140 2
            if ($delegate->has($id)) {
141
                return true;
142 45
            }
143
        }
144 45
145 39
        return false;
146 18
    }
147 12
148 33
    /**
149
     * Allows for manipulation of specific types on resolution.
150
     *
151 39
     * @param string        $type
152
     * @param callable|null $callback
153
     *
154
     * @return \League\Container\Inflector\InflectorInterface
155 6
     */
156 6
    public function inflector(string $type, callable $callback = null): InflectorInterface
157
    {
158
        return $this->inflectors->add($type, $callback);
159
    }
160
161 33
    /**
162
     * Delegate a backup container to be checked for services if it
163 33
     * cannot be resolved via this container.
164
     *
165
     * @param \Psr\Container\ContainerInterface $container
166
     *
167
     * @return self
168
     */
169 12
    public function delegate(ContainerInterface $container): self
170
    {
171 12
        $this->delegates[] = $container;
172
173 12
        if ($container instanceof ContainerAwareInterface) {
174
            $container->setContainer($this);
175
        }
176
177
        return $this;
178
    }
179
}
180