Completed
Pull Request — master (#126)
by Phil
13:49
created

Container   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 170
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 100%

Importance

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