Completed
Pull Request — master (#126)
by Phil
12:31
created

Container::has()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 11
cts 11
cp 1
rs 8.6737
c 0
b 0
f 0
cc 6
eloc 11
nc 6
nop 1
crap 6
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 57
     * Get a definition to extend.
68 57
     *
69
     * @param string $id [description]
70 57
     *
71 57
     * @return \League\Container\Definition\DefinitionInterface
72 57
     */
73
    public function extend(string $id): DefinitionInterface
74 57
    {
75 57
        if ($this->providers->provides($id)) {
76 57
            $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', $id)
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, bool $new = false)
106
    {
107
        if ($this->definitions->has($id)) {
108 9
            $resolved = $this->definitions->resolve($id, $new);
109 3
            return $this->inflectors->inflect($resolved);
110
        }
111
112 9
        if ($this->definitions->hasTag($id)) {
113
            $arrayOf = $this->definitions->resolveTagged($id);
114
115
            array_walk($arrayOf, function (&$resolved) {
116
                $resolved = $this->inflectors->inflect($resolved);
117
            });
118
119
            return $arrayOf;
120
        }
121
122 51
        if ($this->providers->provides($id)) {
123
            $this->providers->register($id);
124 51
            return $this->get($id, $new);
125
        }
126 51
127
        foreach ($this->delegates as $delegate) {
128
            if ($delegate->has($id)) {
129
                $resolved = $delegate->get($id);
130
                return $this->inflectors->inflect($resolved);
131
            }
132 45
        }
133
134 45
        throw new NotFoundException(sprintf('Alias (%s) is not being managed by the container or delegates', $id));
135 45
    }
136 45
137
    /**
138 45
     * {@inheritdoc}
139 3
     */
140 3
    public function has($id): bool
141
    {
142 45
        if ($this->definitions->has($id)) {
143
            return true;
144 45
        }
145 39
146 18
        if ($this->definitions->hasTag($id)) {
147 18
            return true;
148 33
        }
149
150
        if ($this->providers->provides($id)) {
151 39
            return true;
152
        }
153
154
        foreach ($this->delegates as $delegate) {
155 6
            if ($delegate->has($id)) {
156 6
                return true;
157
            }
158
        }
159
160
        return false;
161 33
    }
162
163 33
    /**
164
     * Allows for manipulation of specific types on resolution.
165
     *
166
     * @param string        $type
167
     * @param callable|null $callback
168
     *
169 12
     * @return \League\Container\Inflector\InflectorInterface
170
     */
171 12
    public function inflector(string $type, callable $callback = null): InflectorInterface
172
    {
173 12
        return $this->inflectors->add($type, $callback);
174
    }
175
176
    /**
177
     * Delegate a backup container to be checked for services if it
178
     * cannot be resolved via this container.
179 6
     *
180
     * @param \Psr\Container\ContainerInterface $container
181 6
     *
182 3
     * @return self
183 3
     */
184
    public function delegate(ContainerInterface $container): self
185 6
    {
186 3
        $this->delegates[] = $container;
187
188
        if ($container instanceof ContainerAwareInterface) {
189 6
            $container->setContainer($this);
190 3
        }
191
192
        return $this;
193 3
    }
194
}
195