Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / vendor / league / container / src / Container.php
1 <?php
2
3 namespace League\Container;
4
5 use Interop\Container\ContainerInterface as InteropContainerInterface;
6 use League\Container\Argument\RawArgumentInterface;
7 use League\Container\Definition\DefinitionFactory;
8 use League\Container\Definition\DefinitionFactoryInterface;
9 use League\Container\Definition\DefinitionInterface;
10 use League\Container\Exception\NotFoundException;
11 use League\Container\Inflector\InflectorAggregate;
12 use League\Container\Inflector\InflectorAggregateInterface;
13 use League\Container\ServiceProvider\ServiceProviderAggregate;
14 use League\Container\ServiceProvider\ServiceProviderAggregateInterface;
15
16 class Container implements ContainerInterface
17 {
18     /**
19      * @var \League\Container\Definition\DefinitionFactoryInterface
20      */
21     protected $definitionFactory;
22
23     /**
24      * @var \League\Container\Definition\DefinitionInterface[]
25      */
26     protected $definitions = [];
27
28     /**
29      * @var \League\Container\Definition\DefinitionInterface[]
30      */
31     protected $sharedDefinitions = [];
32
33     /**
34      * @var \League\Container\Inflector\InflectorAggregateInterface
35      */
36     protected $inflectors;
37
38     /**
39      * @var \League\Container\ServiceProvider\ServiceProviderAggregateInterface
40      */
41     protected $providers;
42
43     /**
44      * @var array
45      */
46     protected $shared = [];
47
48     /**
49      * @var \Interop\Container\ContainerInterface[]
50      */
51     protected $delegates = [];
52
53     /**
54      * Constructor.
55      *
56      * @param \League\Container\ServiceProvider\ServiceProviderAggregateInterface|null $providers
57      * @param \League\Container\Inflector\InflectorAggregateInterface|null             $inflectors
58      * @param \League\Container\Definition\DefinitionFactoryInterface|null             $definitionFactory
59      */
60     public function __construct(
61         ServiceProviderAggregateInterface $providers         = null,
62         InflectorAggregateInterface       $inflectors        = null,
63         DefinitionFactoryInterface        $definitionFactory = null
64     ) {
65         // set required dependencies
66         $this->providers         = (is_null($providers))
67                                  ? (new ServiceProviderAggregate)->setContainer($this)
68                                  : $providers->setContainer($this);
69
70         $this->inflectors        = (is_null($inflectors))
71                                  ? (new InflectorAggregate)->setContainer($this)
72                                  : $inflectors->setContainer($this);
73
74         $this->definitionFactory = (is_null($definitionFactory))
75                                  ? (new DefinitionFactory)->setContainer($this)
76                                  : $definitionFactory->setContainer($this);
77     }
78
79     /**
80      * {@inheritdoc}
81      */
82     public function get($alias, array $args = [])
83     {
84         try {
85             return $this->getFromThisContainer($alias, $args);
86         } catch (NotFoundException $exception) {
87             if ($this->providers->provides($alias)) {
88                 $this->providers->register($alias);
89
90                 return $this->getFromThisContainer($alias, $args);
91             }
92
93             $resolved = $this->getFromDelegate($alias, $args);
94
95             return $this->inflectors->inflect($resolved);
96         }
97     }
98
99     /**
100      * {@inheritdoc}
101      */
102     public function has($alias)
103     {
104         if (array_key_exists($alias, $this->definitions) || $this->hasShared($alias)) {
105             return true;
106         }
107
108         if ($this->providers->provides($alias)) {
109             return true;
110         }
111
112         return $this->hasInDelegate($alias);
113     }
114
115     /**
116      * Returns a boolean to determine if the container has a shared instance of an alias.
117      *
118      * @param  string  $alias
119      * @param  boolean $resolved
120      * @return boolean
121      */
122     public function hasShared($alias, $resolved = false)
123     {
124         $shared = ($resolved === false) ? array_merge($this->shared, $this->sharedDefinitions) : $this->shared;
125
126         return (array_key_exists($alias, $shared));
127     }
128
129     /**
130      * {@inheritdoc}
131      */
132     public function add($alias, $concrete = null, $share = false)
133     {
134         unset($this->shared[$alias]);
135         unset($this->definitions[$alias]);
136         unset($this->sharedDefinitions[$alias]);
137
138         if (is_null($concrete)) {
139             $concrete = $alias;
140         }
141
142         $definition = $this->definitionFactory->getDefinition($alias, $concrete);
143
144         if ($definition instanceof DefinitionInterface) {
145             if ($share === false) {
146                 $this->definitions[$alias] = $definition;
147             } else {
148                 $this->sharedDefinitions[$alias] = $definition;
149             }
150
151             return $definition;
152         }
153
154         // dealing with a value that cannot build a definition
155         $this->shared[$alias] = $concrete;
156     }
157
158     /**
159      * {@inheritdoc}
160      */
161     public function share($alias, $concrete = null)
162     {
163         return $this->add($alias, $concrete, true);
164     }
165
166     /**
167      * {@inheritdoc}
168      */
169     public function addServiceProvider($provider)
170     {
171         $this->providers->add($provider);
172
173         return $this;
174     }
175
176     /**
177      * {@inheritdoc}
178      */
179     public function extend($alias)
180     {
181         if ($this->providers->provides($alias)) {
182             $this->providers->register($alias);
183         }
184
185         if (array_key_exists($alias, $this->definitions)) {
186             return $this->definitions[$alias];
187         }
188
189         if (array_key_exists($alias, $this->sharedDefinitions)) {
190             return $this->sharedDefinitions[$alias];
191         }
192
193         throw new NotFoundException(
194             sprintf('Unable to extend alias (%s) as it is not being managed as a definition', $alias)
195         );
196     }
197
198     /**
199      * {@inheritdoc}
200      */
201     public function inflector($type, callable $callback = null)
202     {
203         return $this->inflectors->add($type, $callback);
204     }
205
206     /**
207      * {@inheritdoc}
208      */
209     public function call(callable $callable, array $args = [])
210     {
211         return (new ReflectionContainer)->setContainer($this)->call($callable, $args);
212     }
213
214     /**
215      * Delegate a backup container to be checked for services if it
216      * cannot be resolved via this container.
217      *
218      * @param  \Interop\Container\ContainerInterface $container
219      * @return $this
220      */
221     public function delegate(InteropContainerInterface $container)
222     {
223         $this->delegates[] = $container;
224
225         if ($container instanceof ImmutableContainerAwareInterface) {
226             $container->setContainer($this);
227         }
228
229         return $this;
230     }
231
232     /**
233      * Returns true if service is registered in one of the delegated backup containers.
234      *
235      * @param  string $alias
236      * @return boolean
237      */
238     public function hasInDelegate($alias)
239     {
240         foreach ($this->delegates as $container) {
241             if ($container->has($alias)) {
242                 return true;
243             }
244         }
245
246         return false;
247     }
248
249     /**
250      * Attempt to get a service from the stack of delegated backup containers.
251      *
252      * @param  string $alias
253      * @param  array  $args
254      * @return mixed
255      */
256     protected function getFromDelegate($alias, array $args = [])
257     {
258         foreach ($this->delegates as $container) {
259             if ($container->has($alias)) {
260                 return $container->get($alias, $args);
261             }
262
263             continue;
264         }
265
266         throw new NotFoundException(
267             sprintf('Alias (%s) is not being managed by the container', $alias)
268         );
269
270     }
271
272     /**
273      * Get a service that has been registered in this container.
274      *
275      * @param  string $alias
276      * @param  array $args
277      * @return mixed
278      */
279     protected function getFromThisContainer($alias, array $args = [])
280     {
281         if ($this->hasShared($alias, true)) {
282             $shared = $this->inflectors->inflect($this->shared[$alias]);
283             if ($shared instanceof RawArgumentInterface) {
284                 return $shared->getValue();
285             }
286             return $shared;
287         }
288
289         if (array_key_exists($alias, $this->sharedDefinitions)) {
290             $shared = $this->inflectors->inflect($this->sharedDefinitions[$alias]->build());
291             $this->shared[$alias] = $shared;
292             return $shared;
293         }
294
295         if (array_key_exists($alias, $this->definitions)) {
296             return $this->inflectors->inflect(
297                 $this->definitions[$alias]->build($args)
298             );
299         }
300
301         throw new NotFoundException(
302             sprintf('Alias (%s) is not being managed by the container', $alias)
303         );
304     }
305 }