Completed
Pull Request — master (#126)
by Phil
02:35
created

Container::has()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 0
cts 9
cp 0
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 9
nc 5
nop 1
crap 30
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 $delagates = [];
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 12
    public function __construct(
40
        DefinitionAggregateInterface      $definitions = null,
41
        ServiceProviderAggregateInterface $providers   = null,
42
        InflectorAggregateInterface       $inflectors  = null
43
    ) {
44 12
        $this->definitions = $definitions ?? (new DefinitionAggregate)->setContainer($this);
45 12
        $this->providers   = $providers   ?? (new ServiceProviderAggregate)->setContainer($this);
46 12
        $this->inflectors  = $inflectors  ?? (new InflectorAggregate)->setContainer($this);
47 12
    }
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
        $concrete = $concrete ?? $id;
61
62
        return $this->definitions->add($id, $concrete, $shared);
63
    }
64
65
    /**
66
     * Get a definition to extend.
67
     *
68
     * @param string $id [description]
69
     *
70
     * @return \League\Container\Definition\DefinitionInterface
71
     */
72
    public function extend(string $id): DefinitionInterface
73
    {
74
        if ($this->providers->provides($id)) {
75
            $this->providers->register($id);
76
        }
77
78
        if ($this->definitions->has($id)) {
79
            return $this->definitions->getDefinition($id);
80
        }
81
82
        throw new NotFoundException(
83
            sprintf('Unable to extend alias (%s) as it is not being managed as a definition', $alias)
84
        );
85
    }
86
87
    /**
88
     * Add a service provider.
89
     *
90
     * @param \League\Container\ServiceProvider\ServiceProviderInterface|string $provider
91
     *
92
     * @return self
93
     */
94
    public function addServiceProvider($provider): self
95
    {
96
        $this->providers->add($provider);
97
98
        return $this;
99
    }
100
101
    /**
102
     * {@inheritdoc}
103
     */
104
    public function get($id, array $args = [], bool $new = false)
105
    {
106
        if ($this->definitions->has($id)) {
107
            $resolved = $this->definitions->resolve($id, $args, $new);
108
            return $this->inflectors->inflect($resolved);
109
        }
110
111
        if ($this->providers->provides($id)) {
112
            $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 property delegates does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
117
            if ($delegate->has($id)) {
118
                $resolved = $delegate->get($id, $args);
119
                return $this->inflectors->inflect($resolved);
120
            }
121
        }
122
123
        throw new NotFoundException(sprintf('Alias (%s) is not being managed by the container or delegates', $id));
124
    }
125
126
    /**
127
     * {@inheritdoc}
128
     */
129
    public function has($id): bool
130
    {
131
        if ($this->definitions->has($id)) {
132
            return true;
133
        }
134
135
        if ($this->providers->provides($id)) {
136
            return true;
137
        }
138
139
        foreach ($this->delegates as $delegate) {
140
            if ($delegate->has($id)) {
141
                return true;
142
            }
143
        }
144
145
        return false;
146
    }
147
148
    /**
149
     * Allows for manipulation of specific types on resolution.
150
     *
151
     * @param string        $type
152
     * @param callable|null $callback
153
     *
154
     * @return \League\Container\Inflector\InflectorInterface
155
     */
156
    public function inflector(string $type, callable $callback = null): InflectorInterface
157
    {
158
        return $this->inflectors->add($type, $callback);
159
    }
160
161
    /**
162
     * Delegate a backup container to be checked for services if it
163
     * cannot be resolved via this container.
164
     *
165
     * @param \Psr\Container\ContainerInterface $container
166
     *
167
     * @return self
168
     */
169
    public function delegate(ContainerInterface $container): self
170
    {
171
        $this->delegates[] = $container;
172
173
        if ($container instanceof ContainerAwareInterface) {
174
            $container->setContainer($this);
175
        }
176
177
        return $this;
178
    }
179
}
180