Completed
Push — master ( 696114...b35b16 )
by Phil
05:53 queued 02:05
created

Container::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 1
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 39
    public function __construct(
41
        DefinitionAggregateInterface      $definitions = null,
42
        ServiceProviderAggregateInterface $providers = null,
43
        InflectorAggregateInterface       $inflectors = null
44
    ) {
45 39
        $this->definitions = $definitions ?? (new DefinitionAggregate)->setContainer($this);
46 39
        $this->providers   = $providers   ?? (new ServiceProviderAggregate)->setContainer($this);
47 39
        $this->inflectors  = $inflectors  ?? (new InflectorAggregate)->setContainer($this);
48 39
    }
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 18
    public function add(string $id, $concrete = null, bool $shared = false): DefinitionInterface
60
    {
61 18
        $concrete = $concrete ?? $id;
62
63 18
        return $this->definitions->add($id, $concrete, $shared);
64
    }
65
66
    /**
67
     * Get a definition to extend.
68
     *
69
     * @param string $id [description]
70
     *
71
     * @return \League\Container\Definition\DefinitionInterface
72
     */
73 9
    public function extend(string $id): DefinitionInterface
74
    {
75 9
        if ($this->providers->provides($id)) {
76 3
            $this->providers->register($id);
77
        }
78
79 9
        if ($this->definitions->has($id)) {
80 6
            return $this->definitions->getDefinition($id);
81
        }
82
83 3
        throw new NotFoundException(
84 3
            sprintf('Unable to extend alias (%s) as it is not being managed as a definition', $id)
85
        );
86
    }
87
88
    /**
89
     * Add a service provider.
90
     *
91
     * @param \League\Container\ServiceProvider\ServiceProviderInterface|string $provider
92
     *
93
     * @return self
94
     */
95 6
    public function addServiceProvider($provider): self
96
    {
97 6
        $this->providers->add($provider);
98
99 6
        return $this;
100
    }
101
102
    /**
103
     * {@inheritdoc}
104
     */
105 18
    public function get($id, bool $new = false)
106
    {
107 18
        if ($this->definitions->has($id)) {
108 9
            $resolved = $this->definitions->resolve($id, $new);
109 9
            return $this->inflectors->inflect($resolved);
110
        }
111
112 12
        if ($this->definitions->hasTag($id)) {
113 3
            $arrayOf = $this->definitions->resolveTagged($id);
114
115 3
            array_walk($arrayOf, function (&$resolved) {
116 3
                $resolved = $this->inflectors->inflect($resolved);
117 3
            });
118
119 3
            return $arrayOf;
120
        }
121
122 9
        if ($this->providers->provides($id)) {
123 3
            $this->providers->register($id);
124 3
            return $this->get($id, $new);
125
        }
126
127 6
        foreach ($this->delegates as $delegate) {
128 3
            if ($delegate->has($id)) {
129 3
                $resolved = $delegate->get($id);
130 3
                return $this->inflectors->inflect($resolved);
131
            }
132
        }
133
134 3
        throw new NotFoundException(sprintf('Alias (%s) is not being managed by the container or delegates', $id));
135
    }
136
137
    /**
138
     * {@inheritdoc}
139
     */
140 21
    public function has($id): bool
141
    {
142 21
        if ($this->definitions->has($id)) {
143 9
            return true;
144
        }
145
146 15
        if ($this->definitions->hasTag($id)) {
147 3
            return true;
148
        }
149
150 12
        if ($this->providers->provides($id)) {
151 3
            return true;
152
        }
153
154 9
        foreach ($this->delegates as $delegate) {
155 3
            if ($delegate->has($id)) {
156 3
                return true;
157
            }
158
        }
159
160 6
        return false;
161
    }
162
163
    /**
164
     * Allows for manipulation of specific types on resolution.
165
     *
166
     * @param string        $type
167
     * @param callable|null $callback
168
     *
169
     * @return \League\Container\Inflector\InflectorInterface
170
     */
171 3
    public function inflector(string $type, callable $callback = null): InflectorInterface
172
    {
173 3
        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
     *
180
     * @param \Psr\Container\ContainerInterface $container
181
     *
182
     * @return self
183
     */
184 3
    public function delegate(ContainerInterface $container): self
185
    {
186 3
        $this->delegates[] = $container;
187
188 3
        if ($container instanceof ContainerAwareInterface) {
189 3
            $container->setContainer($this);
190
        }
191
192 3
        return $this;
193
    }
194
}
195