Completed
Push — master ( a9358c...b17107 )
by Phil
01:46
created

Container::share()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
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 boolean
15
     */
16
    protected $defaultToShared = false;
17
18
    /**
19
     * @var \League\Container\Definition\DefinitionAggregateInterface
20
     */
21
    protected $definitions;
22
23
    /**
24
     * @var \League\Container\ServiceProvider\ServiceProviderAggregateInterface
25
     */
26
    protected $providers;
27
28
    /**
29
     * @var \League\Container\Inflector\InflectorAggregateInterface
30
     */
31
    protected $inflectors;
32
33
    /**
34
     * @var \Psr\Container\ContainerInterface[]
35
     */
36
    protected $delegates = [];
37
38
    /**
39
     * Construct.
40
     *
41
     * @param \League\Container\Definition\DefinitionAggregateInterface|null           $definitions
42
     * @param \League\Container\ServiceProvider\ServiceProviderAggregateInterface|null $providers
43
     * @param \League\Container\Inflector\InflectorAggregateInterface|null             $inflectors
44
     */
45 45
    public function __construct(
46
        DefinitionAggregateInterface      $definitions = null,
47
        ServiceProviderAggregateInterface $providers = null,
48
        InflectorAggregateInterface       $inflectors = null
49
    ) {
50 45
        $this->definitions = $definitions ?? (new DefinitionAggregate);
51 45
        $this->providers   = $providers   ?? (new ServiceProviderAggregate);
52 45
        $this->inflectors  = $inflectors  ?? (new InflectorAggregate);
53
54 45
        if ($this->definitions instanceof ContainerAwareInterface) {
55 45
            $this->definitions->setContainer($this);
56
        }
57
58 45
        if ($this->providers instanceof ContainerAwareInterface) {
59 45
            $this->providers->setContainer($this);
60
        }
61
62 45
        if ($this->inflectors instanceof ContainerAwareInterface) {
63 45
            $this->inflectors->setContainer($this);
64
        }
65 45
    }
66
67
    /**
68
     * Add an item to the container.
69
     *
70
     * @param string  $id
71
     * @param mixed   $concrete
72
     * @param boolean $shared
73
     *
74
     * @return \League\Container\Definition\DefinitionInterface
75
     */
76 24
    public function add(string $id, $concrete = null, bool $shared = false) : DefinitionInterface
77
    {
78 24
        $concrete = $concrete ?? $id;
79 24
        $shared   = ($this->defaultToShared === true || $shared === true);
80
81 24
        return $this->definitions->add($id, $concrete, $shared);
82
    }
83
84
    /**
85
     * Proxy to add with shared as true.
86
     *
87
     * @param string $id
88
     * @param mixed  $concrete
89
     *
90
     * @return \League\Container\Definition\DefinitionInterface
91
     */
92 6
    public function share(string $id, $concrete = null) : DefinitionInterface
93
    {
94 6
        return $this->add($id, $concrete, true);
95
    }
96
97
    /**
98
     * Whether the container should default to defining shared definitions.
99
     *
100
     * @param boolean $shared
101
     *
102
     * @return self
103
     */
104 3
    public function defaultToShared(bool $shared = true) : ContainerInterface
105
    {
106 3
        $this->defaultToShared = $shared;
107
108 3
        return $this;
109
    }
110
111
    /**
112
     * Get a definition to extend.
113
     *
114
     * @param string $id [description]
115
     *
116
     * @return \League\Container\Definition\DefinitionInterface
117
     */
118 9
    public function extend(string $id) : DefinitionInterface
119
    {
120 9
        if ($this->providers->provides($id)) {
121 3
            $this->providers->register($id);
122
        }
123
124 9
        if ($this->definitions->has($id)) {
125 6
            return $this->definitions->getDefinition($id);
126
        }
127
128 3
        throw new NotFoundException(
129 3
            sprintf('Unable to extend alias (%s) as it is not being managed as a definition', $id)
130
        );
131
    }
132
133
    /**
134
     * Add a service provider.
135
     *
136
     * @param \League\Container\ServiceProvider\ServiceProviderInterface|string $provider
137
     *
138
     * @return self
139
     */
140 6
    public function addServiceProvider($provider) : self
141
    {
142 6
        $this->providers->add($provider);
143
144 6
        return $this;
145
    }
146
147
    /**
148
     * {@inheritdoc}
149
     */
150 24
    public function get($id, bool $new = false)
151
    {
152 24
        if ($this->definitions->has($id)) {
153 15
            $resolved = $this->definitions->resolve($id, $new);
154 15
            return $this->inflectors->inflect($resolved);
155
        }
156
157 12
        if ($this->definitions->hasTag($id)) {
158 3
            $arrayOf = $this->definitions->resolveTagged($id);
159
160 3
            array_walk($arrayOf, function (&$resolved) {
161 3
                $resolved = $this->inflectors->inflect($resolved);
162 3
            });
163
164 3
            return $arrayOf;
165
        }
166
167 9
        if ($this->providers->provides($id)) {
168 3
            $this->providers->register($id);
169 3
            return $this->get($id, $new);
170
        }
171
172 6
        foreach ($this->delegates as $delegate) {
173 3
            if ($delegate->has($id)) {
174 3
                $resolved = $delegate->get($id);
175 3
                return $this->inflectors->inflect($resolved);
176
            }
177
        }
178
179 3
        throw new NotFoundException(sprintf('Alias (%s) is not being managed by the container or delegates', $id));
180
    }
181
182
    /**
183
     * {@inheritdoc}
184
     */
185 27
    public function has($id) : bool
186
    {
187 27
        if ($this->definitions->has($id)) {
188 15
            return true;
189
        }
190
191 15
        if ($this->definitions->hasTag($id)) {
192 3
            return true;
193
        }
194
195 12
        if ($this->providers->provides($id)) {
196 3
            return true;
197
        }
198
199 9
        foreach ($this->delegates as $delegate) {
200 3
            if ($delegate->has($id)) {
201 3
                return true;
202
            }
203
        }
204
205 6
        return false;
206
    }
207
208
    /**
209
     * Allows for manipulation of specific types on resolution.
210
     *
211
     * @param string        $type
212
     * @param callable|null $callback
213
     *
214
     * @return \League\Container\Inflector\InflectorInterface
215
     */
216 3
    public function inflector(string $type, callable $callback = null) : InflectorInterface
217
    {
218 3
        return $this->inflectors->add($type, $callback);
219
    }
220
221
    /**
222
     * Delegate a backup container to be checked for services if it
223
     * cannot be resolved via this container.
224
     *
225
     * @param \Psr\Container\ContainerInterface $container
226
     *
227
     * @return self
228
     */
229 3
    public function delegate(ContainerInterface $container) : self
230
    {
231 3
        $this->delegates[] = $container;
232
233 3
        if ($container instanceof ContainerAwareInterface) {
234 3
            $container->setContainer($this);
235
        }
236
237 3
        return $this;
238
    }
239
}
240