Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /*
|
Chris@0
|
4 * This file is part of the Symfony package.
|
Chris@0
|
5 *
|
Chris@0
|
6 * (c) Fabien Potencier <fabien@symfony.com>
|
Chris@0
|
7 *
|
Chris@0
|
8 * For the full copyright and license information, please view the LICENSE
|
Chris@0
|
9 * file that was distributed with this source code.
|
Chris@0
|
10 */
|
Chris@0
|
11
|
Chris@0
|
12 namespace Symfony\Component\DependencyInjection\Loader;
|
Chris@0
|
13
|
Chris@0
|
14 use Symfony\Component\DependencyInjection\Alias;
|
Chris@14
|
15 use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
Chris@14
|
16 use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
Chris@14
|
17 use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
Chris@14
|
18 use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
Chris@14
|
19 use Symfony\Component\DependencyInjection\ChildDefinition;
|
Chris@14
|
20 use Symfony\Component\DependencyInjection\ContainerBuilder;
|
Chris@0
|
21 use Symfony\Component\DependencyInjection\ContainerInterface;
|
Chris@0
|
22 use Symfony\Component\DependencyInjection\Definition;
|
Chris@0
|
23 use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
Chris@0
|
24 use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
Chris@17
|
25 use Symfony\Component\DependencyInjection\Reference;
|
Chris@17
|
26 use Symfony\Component\ExpressionLanguage\Expression;
|
Chris@0
|
27 use Symfony\Component\Yaml\Exception\ParseException;
|
Chris@0
|
28 use Symfony\Component\Yaml\Parser as YamlParser;
|
Chris@14
|
29 use Symfony\Component\Yaml\Tag\TaggedValue;
|
Chris@0
|
30 use Symfony\Component\Yaml\Yaml;
|
Chris@0
|
31
|
Chris@0
|
32 /**
|
Chris@0
|
33 * YamlFileLoader loads YAML files service definitions.
|
Chris@0
|
34 *
|
Chris@0
|
35 * @author Fabien Potencier <fabien@symfony.com>
|
Chris@0
|
36 */
|
Chris@0
|
37 class YamlFileLoader extends FileLoader
|
Chris@0
|
38 {
|
Chris@17
|
39 private static $serviceKeywords = [
|
Chris@0
|
40 'alias' => 'alias',
|
Chris@0
|
41 'parent' => 'parent',
|
Chris@0
|
42 'class' => 'class',
|
Chris@0
|
43 'shared' => 'shared',
|
Chris@0
|
44 'synthetic' => 'synthetic',
|
Chris@0
|
45 'lazy' => 'lazy',
|
Chris@0
|
46 'public' => 'public',
|
Chris@0
|
47 'abstract' => 'abstract',
|
Chris@0
|
48 'deprecated' => 'deprecated',
|
Chris@0
|
49 'factory' => 'factory',
|
Chris@0
|
50 'file' => 'file',
|
Chris@0
|
51 'arguments' => 'arguments',
|
Chris@0
|
52 'properties' => 'properties',
|
Chris@0
|
53 'configurator' => 'configurator',
|
Chris@0
|
54 'calls' => 'calls',
|
Chris@0
|
55 'tags' => 'tags',
|
Chris@0
|
56 'decorates' => 'decorates',
|
Chris@0
|
57 'decoration_inner_name' => 'decoration_inner_name',
|
Chris@0
|
58 'decoration_priority' => 'decoration_priority',
|
Chris@0
|
59 'autowire' => 'autowire',
|
Chris@0
|
60 'autowiring_types' => 'autowiring_types',
|
Chris@14
|
61 'autoconfigure' => 'autoconfigure',
|
Chris@14
|
62 'bind' => 'bind',
|
Chris@17
|
63 ];
|
Chris@14
|
64
|
Chris@17
|
65 private static $prototypeKeywords = [
|
Chris@14
|
66 'resource' => 'resource',
|
Chris@14
|
67 'namespace' => 'namespace',
|
Chris@14
|
68 'exclude' => 'exclude',
|
Chris@14
|
69 'parent' => 'parent',
|
Chris@14
|
70 'shared' => 'shared',
|
Chris@14
|
71 'lazy' => 'lazy',
|
Chris@14
|
72 'public' => 'public',
|
Chris@14
|
73 'abstract' => 'abstract',
|
Chris@14
|
74 'deprecated' => 'deprecated',
|
Chris@14
|
75 'factory' => 'factory',
|
Chris@14
|
76 'arguments' => 'arguments',
|
Chris@14
|
77 'properties' => 'properties',
|
Chris@14
|
78 'configurator' => 'configurator',
|
Chris@14
|
79 'calls' => 'calls',
|
Chris@14
|
80 'tags' => 'tags',
|
Chris@14
|
81 'autowire' => 'autowire',
|
Chris@14
|
82 'autoconfigure' => 'autoconfigure',
|
Chris@14
|
83 'bind' => 'bind',
|
Chris@17
|
84 ];
|
Chris@14
|
85
|
Chris@17
|
86 private static $instanceofKeywords = [
|
Chris@14
|
87 'shared' => 'shared',
|
Chris@14
|
88 'lazy' => 'lazy',
|
Chris@14
|
89 'public' => 'public',
|
Chris@14
|
90 'properties' => 'properties',
|
Chris@14
|
91 'configurator' => 'configurator',
|
Chris@14
|
92 'calls' => 'calls',
|
Chris@14
|
93 'tags' => 'tags',
|
Chris@14
|
94 'autowire' => 'autowire',
|
Chris@17
|
95 ];
|
Chris@14
|
96
|
Chris@17
|
97 private static $defaultsKeywords = [
|
Chris@14
|
98 'public' => 'public',
|
Chris@14
|
99 'tags' => 'tags',
|
Chris@14
|
100 'autowire' => 'autowire',
|
Chris@14
|
101 'autoconfigure' => 'autoconfigure',
|
Chris@14
|
102 'bind' => 'bind',
|
Chris@17
|
103 ];
|
Chris@0
|
104
|
Chris@0
|
105 private $yamlParser;
|
Chris@0
|
106
|
Chris@14
|
107 private $anonymousServicesCount;
|
Chris@14
|
108 private $anonymousServicesSuffix;
|
Chris@14
|
109
|
Chris@0
|
110 /**
|
Chris@0
|
111 * {@inheritdoc}
|
Chris@0
|
112 */
|
Chris@0
|
113 public function load($resource, $type = null)
|
Chris@0
|
114 {
|
Chris@0
|
115 $path = $this->locator->locate($resource);
|
Chris@0
|
116
|
Chris@0
|
117 $content = $this->loadFile($path);
|
Chris@0
|
118
|
Chris@14
|
119 $this->container->fileExists($path);
|
Chris@0
|
120
|
Chris@0
|
121 // empty file
|
Chris@0
|
122 if (null === $content) {
|
Chris@0
|
123 return;
|
Chris@0
|
124 }
|
Chris@0
|
125
|
Chris@0
|
126 // imports
|
Chris@0
|
127 $this->parseImports($content, $path);
|
Chris@0
|
128
|
Chris@0
|
129 // parameters
|
Chris@0
|
130 if (isset($content['parameters'])) {
|
Chris@17
|
131 if (!\is_array($content['parameters'])) {
|
Chris@14
|
132 throw new InvalidArgumentException(sprintf('The "parameters" key should contain an array in %s. Check your YAML syntax.', $path));
|
Chris@0
|
133 }
|
Chris@0
|
134
|
Chris@0
|
135 foreach ($content['parameters'] as $key => $value) {
|
Chris@14
|
136 $this->container->setParameter($key, $this->resolveServices($value, $path, true));
|
Chris@0
|
137 }
|
Chris@0
|
138 }
|
Chris@0
|
139
|
Chris@0
|
140 // extensions
|
Chris@0
|
141 $this->loadFromExtensions($content);
|
Chris@0
|
142
|
Chris@0
|
143 // services
|
Chris@14
|
144 $this->anonymousServicesCount = 0;
|
Chris@17
|
145 $this->anonymousServicesSuffix = '~'.ContainerBuilder::hash($path);
|
Chris@17
|
146 $this->setCurrentDir(\dirname($path));
|
Chris@14
|
147 try {
|
Chris@14
|
148 $this->parseDefinitions($content, $path);
|
Chris@14
|
149 } finally {
|
Chris@17
|
150 $this->instanceof = [];
|
Chris@14
|
151 }
|
Chris@0
|
152 }
|
Chris@0
|
153
|
Chris@0
|
154 /**
|
Chris@0
|
155 * {@inheritdoc}
|
Chris@0
|
156 */
|
Chris@0
|
157 public function supports($resource, $type = null)
|
Chris@0
|
158 {
|
Chris@17
|
159 if (!\is_string($resource)) {
|
Chris@14
|
160 return false;
|
Chris@14
|
161 }
|
Chris@14
|
162
|
Chris@17
|
163 if (null === $type && \in_array(pathinfo($resource, PATHINFO_EXTENSION), ['yaml', 'yml'], true)) {
|
Chris@14
|
164 return true;
|
Chris@14
|
165 }
|
Chris@14
|
166
|
Chris@17
|
167 return \in_array($type, ['yaml', 'yml'], true);
|
Chris@0
|
168 }
|
Chris@0
|
169
|
Chris@0
|
170 /**
|
Chris@0
|
171 * Parses all imports.
|
Chris@0
|
172 *
|
Chris@0
|
173 * @param array $content
|
Chris@0
|
174 * @param string $file
|
Chris@0
|
175 */
|
Chris@0
|
176 private function parseImports(array $content, $file)
|
Chris@0
|
177 {
|
Chris@0
|
178 if (!isset($content['imports'])) {
|
Chris@0
|
179 return;
|
Chris@0
|
180 }
|
Chris@0
|
181
|
Chris@17
|
182 if (!\is_array($content['imports'])) {
|
Chris@0
|
183 throw new InvalidArgumentException(sprintf('The "imports" key should contain an array in %s. Check your YAML syntax.', $file));
|
Chris@0
|
184 }
|
Chris@0
|
185
|
Chris@17
|
186 $defaultDirectory = \dirname($file);
|
Chris@0
|
187 foreach ($content['imports'] as $import) {
|
Chris@17
|
188 if (!\is_array($import)) {
|
Chris@17
|
189 $import = ['resource' => $import];
|
Chris@14
|
190 }
|
Chris@14
|
191 if (!isset($import['resource'])) {
|
Chris@14
|
192 throw new InvalidArgumentException(sprintf('An import should provide a resource in %s. Check your YAML syntax.', $file));
|
Chris@0
|
193 }
|
Chris@0
|
194
|
Chris@0
|
195 $this->setCurrentDir($defaultDirectory);
|
Chris@14
|
196 $this->import($import['resource'], isset($import['type']) ? $import['type'] : null, isset($import['ignore_errors']) ? (bool) $import['ignore_errors'] : false, $file);
|
Chris@0
|
197 }
|
Chris@0
|
198 }
|
Chris@0
|
199
|
Chris@0
|
200 /**
|
Chris@0
|
201 * Parses definitions.
|
Chris@0
|
202 *
|
Chris@0
|
203 * @param array $content
|
Chris@0
|
204 * @param string $file
|
Chris@0
|
205 */
|
Chris@0
|
206 private function parseDefinitions(array $content, $file)
|
Chris@0
|
207 {
|
Chris@0
|
208 if (!isset($content['services'])) {
|
Chris@0
|
209 return;
|
Chris@0
|
210 }
|
Chris@0
|
211
|
Chris@17
|
212 if (!\is_array($content['services'])) {
|
Chris@0
|
213 throw new InvalidArgumentException(sprintf('The "services" key should contain an array in %s. Check your YAML syntax.', $file));
|
Chris@0
|
214 }
|
Chris@0
|
215
|
Chris@18
|
216 if (\array_key_exists('_instanceof', $content['services'])) {
|
Chris@14
|
217 $instanceof = $content['services']['_instanceof'];
|
Chris@14
|
218 unset($content['services']['_instanceof']);
|
Chris@14
|
219
|
Chris@17
|
220 if (!\is_array($instanceof)) {
|
Chris@17
|
221 throw new InvalidArgumentException(sprintf('Service "_instanceof" key must be an array, "%s" given in "%s".', \gettype($instanceof), $file));
|
Chris@14
|
222 }
|
Chris@17
|
223 $this->instanceof = [];
|
Chris@14
|
224 $this->isLoadingInstanceof = true;
|
Chris@14
|
225 foreach ($instanceof as $id => $service) {
|
Chris@17
|
226 if (!$service || !\is_array($service)) {
|
Chris@14
|
227 throw new InvalidArgumentException(sprintf('Type definition "%s" must be a non-empty array within "_instanceof" in %s. Check your YAML syntax.', $id, $file));
|
Chris@14
|
228 }
|
Chris@17
|
229 if (\is_string($service) && 0 === strpos($service, '@')) {
|
Chris@14
|
230 throw new InvalidArgumentException(sprintf('Type definition "%s" cannot be an alias within "_instanceof" in %s. Check your YAML syntax.', $id, $file));
|
Chris@14
|
231 }
|
Chris@17
|
232 $this->parseDefinition($id, $service, $file, []);
|
Chris@14
|
233 }
|
Chris@14
|
234 }
|
Chris@14
|
235
|
Chris@14
|
236 $this->isLoadingInstanceof = false;
|
Chris@14
|
237 $defaults = $this->parseDefaults($content, $file);
|
Chris@0
|
238 foreach ($content['services'] as $id => $service) {
|
Chris@14
|
239 $this->parseDefinition($id, $service, $file, $defaults);
|
Chris@0
|
240 }
|
Chris@0
|
241 }
|
Chris@0
|
242
|
Chris@0
|
243 /**
|
Chris@14
|
244 * @param array $content
|
Chris@14
|
245 * @param string $file
|
Chris@14
|
246 *
|
Chris@14
|
247 * @return array
|
Chris@14
|
248 *
|
Chris@14
|
249 * @throws InvalidArgumentException
|
Chris@14
|
250 */
|
Chris@14
|
251 private function parseDefaults(array &$content, $file)
|
Chris@14
|
252 {
|
Chris@18
|
253 if (!\array_key_exists('_defaults', $content['services'])) {
|
Chris@17
|
254 return [];
|
Chris@14
|
255 }
|
Chris@14
|
256 $defaults = $content['services']['_defaults'];
|
Chris@14
|
257 unset($content['services']['_defaults']);
|
Chris@14
|
258
|
Chris@17
|
259 if (!\is_array($defaults)) {
|
Chris@17
|
260 throw new InvalidArgumentException(sprintf('Service "_defaults" key must be an array, "%s" given in "%s".', \gettype($defaults), $file));
|
Chris@14
|
261 }
|
Chris@14
|
262
|
Chris@14
|
263 foreach ($defaults as $key => $default) {
|
Chris@14
|
264 if (!isset(self::$defaultsKeywords[$key])) {
|
Chris@14
|
265 throw new InvalidArgumentException(sprintf('The configuration key "%s" cannot be used to define a default value in "%s". Allowed keys are "%s".', $key, $file, implode('", "', self::$defaultsKeywords)));
|
Chris@14
|
266 }
|
Chris@14
|
267 }
|
Chris@14
|
268
|
Chris@14
|
269 if (isset($defaults['tags'])) {
|
Chris@17
|
270 if (!\is_array($tags = $defaults['tags'])) {
|
Chris@14
|
271 throw new InvalidArgumentException(sprintf('Parameter "tags" in "_defaults" must be an array in %s. Check your YAML syntax.', $file));
|
Chris@14
|
272 }
|
Chris@14
|
273
|
Chris@14
|
274 foreach ($tags as $tag) {
|
Chris@17
|
275 if (!\is_array($tag)) {
|
Chris@17
|
276 $tag = ['name' => $tag];
|
Chris@14
|
277 }
|
Chris@14
|
278
|
Chris@14
|
279 if (!isset($tag['name'])) {
|
Chris@14
|
280 throw new InvalidArgumentException(sprintf('A "tags" entry in "_defaults" is missing a "name" key in %s.', $file));
|
Chris@14
|
281 }
|
Chris@14
|
282 $name = $tag['name'];
|
Chris@14
|
283 unset($tag['name']);
|
Chris@14
|
284
|
Chris@17
|
285 if (!\is_string($name) || '' === $name) {
|
Chris@14
|
286 throw new InvalidArgumentException(sprintf('The tag name in "_defaults" must be a non-empty string in %s.', $file));
|
Chris@14
|
287 }
|
Chris@14
|
288
|
Chris@14
|
289 foreach ($tag as $attribute => $value) {
|
Chris@14
|
290 if (!is_scalar($value) && null !== $value) {
|
Chris@14
|
291 throw new InvalidArgumentException(sprintf('Tag "%s", attribute "%s" in "_defaults" must be of a scalar-type in %s. Check your YAML syntax.', $name, $attribute, $file));
|
Chris@14
|
292 }
|
Chris@14
|
293 }
|
Chris@14
|
294 }
|
Chris@14
|
295 }
|
Chris@14
|
296
|
Chris@14
|
297 if (isset($defaults['bind'])) {
|
Chris@17
|
298 if (!\is_array($defaults['bind'])) {
|
Chris@14
|
299 throw new InvalidArgumentException(sprintf('Parameter "bind" in "_defaults" must be an array in %s. Check your YAML syntax.', $file));
|
Chris@14
|
300 }
|
Chris@14
|
301
|
Chris@14
|
302 $defaults['bind'] = array_map(function ($v) { return new BoundArgument($v); }, $this->resolveServices($defaults['bind'], $file));
|
Chris@14
|
303 }
|
Chris@14
|
304
|
Chris@14
|
305 return $defaults;
|
Chris@14
|
306 }
|
Chris@14
|
307
|
Chris@14
|
308 /**
|
Chris@14
|
309 * @param array $service
|
Chris@14
|
310 *
|
Chris@14
|
311 * @return bool
|
Chris@14
|
312 */
|
Chris@14
|
313 private function isUsingShortSyntax(array $service)
|
Chris@14
|
314 {
|
Chris@14
|
315 foreach ($service as $key => $value) {
|
Chris@17
|
316 if (\is_string($key) && ('' === $key || '$' !== $key[0])) {
|
Chris@14
|
317 return false;
|
Chris@14
|
318 }
|
Chris@14
|
319 }
|
Chris@14
|
320
|
Chris@14
|
321 return true;
|
Chris@14
|
322 }
|
Chris@14
|
323
|
Chris@14
|
324 /**
|
Chris@0
|
325 * Parses a definition.
|
Chris@0
|
326 *
|
Chris@0
|
327 * @param string $id
|
Chris@0
|
328 * @param array|string $service
|
Chris@0
|
329 * @param string $file
|
Chris@14
|
330 * @param array $defaults
|
Chris@0
|
331 *
|
Chris@0
|
332 * @throws InvalidArgumentException When tags are invalid
|
Chris@0
|
333 */
|
Chris@14
|
334 private function parseDefinition($id, $service, $file, array $defaults)
|
Chris@0
|
335 {
|
Chris@14
|
336 if (preg_match('/^_[a-zA-Z0-9_]*$/', $id)) {
|
Chris@14
|
337 @trigger_error(sprintf('Service names that start with an underscore are deprecated since Symfony 3.3 and will be reserved in 4.0. Rename the "%s" service or define it in XML instead.', $id), E_USER_DEPRECATED);
|
Chris@14
|
338 }
|
Chris@17
|
339 if (\is_string($service) && 0 === strpos($service, '@')) {
|
Chris@14
|
340 $this->container->setAlias($id, $alias = new Alias(substr($service, 1)));
|
Chris@14
|
341 if (isset($defaults['public'])) {
|
Chris@14
|
342 $alias->setPublic($defaults['public']);
|
Chris@14
|
343 }
|
Chris@0
|
344
|
Chris@0
|
345 return;
|
Chris@0
|
346 }
|
Chris@0
|
347
|
Chris@17
|
348 if (\is_array($service) && $this->isUsingShortSyntax($service)) {
|
Chris@17
|
349 $service = ['arguments' => $service];
|
Chris@14
|
350 }
|
Chris@14
|
351
|
Chris@14
|
352 if (null === $service) {
|
Chris@17
|
353 $service = [];
|
Chris@14
|
354 }
|
Chris@14
|
355
|
Chris@17
|
356 if (!\is_array($service)) {
|
Chris@17
|
357 throw new InvalidArgumentException(sprintf('A service definition must be an array or a string starting with "@" but %s found for service "%s" in %s. Check your YAML syntax.', \gettype($service), $id, $file));
|
Chris@0
|
358 }
|
Chris@0
|
359
|
Chris@14
|
360 $this->checkDefinition($id, $service, $file);
|
Chris@0
|
361
|
Chris@0
|
362 if (isset($service['alias'])) {
|
Chris@14
|
363 $this->container->setAlias($id, $alias = new Alias($service['alias']));
|
Chris@18
|
364 if (\array_key_exists('public', $service)) {
|
Chris@14
|
365 $alias->setPublic($service['public']);
|
Chris@14
|
366 } elseif (isset($defaults['public'])) {
|
Chris@14
|
367 $alias->setPublic($defaults['public']);
|
Chris@14
|
368 }
|
Chris@0
|
369
|
Chris@0
|
370 foreach ($service as $key => $value) {
|
Chris@17
|
371 if (!\in_array($key, ['alias', 'public'])) {
|
Chris@0
|
372 @trigger_error(sprintf('The configuration key "%s" is unsupported for the service "%s" which is defined as an alias in "%s". Allowed configuration keys for service aliases are "alias" and "public". The YamlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported attributes.', $key, $id, $file), E_USER_DEPRECATED);
|
Chris@0
|
373 }
|
Chris@0
|
374 }
|
Chris@0
|
375
|
Chris@0
|
376 return;
|
Chris@0
|
377 }
|
Chris@0
|
378
|
Chris@14
|
379 if ($this->isLoadingInstanceof) {
|
Chris@14
|
380 $definition = new ChildDefinition('');
|
Chris@14
|
381 } elseif (isset($service['parent'])) {
|
Chris@14
|
382 if (!empty($this->instanceof)) {
|
Chris@14
|
383 throw new InvalidArgumentException(sprintf('The service "%s" cannot use the "parent" option in the same file where "_instanceof" configuration is defined as using both is not supported. Move your child definitions to a separate file.', $id));
|
Chris@14
|
384 }
|
Chris@14
|
385
|
Chris@14
|
386 foreach ($defaults as $k => $v) {
|
Chris@14
|
387 if ('tags' === $k) {
|
Chris@14
|
388 // since tags are never inherited from parents, there is no confusion
|
Chris@14
|
389 // thus we can safely add them as defaults to ChildDefinition
|
Chris@14
|
390 continue;
|
Chris@14
|
391 }
|
Chris@14
|
392 if ('bind' === $k) {
|
Chris@14
|
393 throw new InvalidArgumentException(sprintf('Attribute "bind" on service "%s" cannot be inherited from "_defaults" when a "parent" is set. Move your child definitions to a separate file.', $id));
|
Chris@14
|
394 }
|
Chris@14
|
395 if (!isset($service[$k])) {
|
Chris@14
|
396 throw new InvalidArgumentException(sprintf('Attribute "%s" on service "%s" cannot be inherited from "_defaults" when a "parent" is set. Move your child definitions to a separate file or define this attribute explicitly.', $k, $id));
|
Chris@14
|
397 }
|
Chris@14
|
398 }
|
Chris@14
|
399
|
Chris@14
|
400 $definition = new ChildDefinition($service['parent']);
|
Chris@0
|
401 } else {
|
Chris@0
|
402 $definition = new Definition();
|
Chris@14
|
403
|
Chris@14
|
404 if (isset($defaults['public'])) {
|
Chris@14
|
405 $definition->setPublic($defaults['public']);
|
Chris@14
|
406 }
|
Chris@14
|
407 if (isset($defaults['autowire'])) {
|
Chris@14
|
408 $definition->setAutowired($defaults['autowire']);
|
Chris@14
|
409 }
|
Chris@14
|
410 if (isset($defaults['autoconfigure'])) {
|
Chris@14
|
411 $definition->setAutoconfigured($defaults['autoconfigure']);
|
Chris@14
|
412 }
|
Chris@14
|
413
|
Chris@17
|
414 $definition->setChanges([]);
|
Chris@0
|
415 }
|
Chris@0
|
416
|
Chris@0
|
417 if (isset($service['class'])) {
|
Chris@0
|
418 $definition->setClass($service['class']);
|
Chris@0
|
419 }
|
Chris@0
|
420
|
Chris@0
|
421 if (isset($service['shared'])) {
|
Chris@0
|
422 $definition->setShared($service['shared']);
|
Chris@0
|
423 }
|
Chris@0
|
424
|
Chris@0
|
425 if (isset($service['synthetic'])) {
|
Chris@0
|
426 $definition->setSynthetic($service['synthetic']);
|
Chris@0
|
427 }
|
Chris@0
|
428
|
Chris@0
|
429 if (isset($service['lazy'])) {
|
Chris@0
|
430 $definition->setLazy($service['lazy']);
|
Chris@0
|
431 }
|
Chris@0
|
432
|
Chris@0
|
433 if (isset($service['public'])) {
|
Chris@0
|
434 $definition->setPublic($service['public']);
|
Chris@0
|
435 }
|
Chris@0
|
436
|
Chris@0
|
437 if (isset($service['abstract'])) {
|
Chris@0
|
438 $definition->setAbstract($service['abstract']);
|
Chris@0
|
439 }
|
Chris@0
|
440
|
Chris@18
|
441 if (\array_key_exists('deprecated', $service)) {
|
Chris@0
|
442 $definition->setDeprecated(true, $service['deprecated']);
|
Chris@0
|
443 }
|
Chris@0
|
444
|
Chris@0
|
445 if (isset($service['factory'])) {
|
Chris@0
|
446 $definition->setFactory($this->parseCallable($service['factory'], 'factory', $id, $file));
|
Chris@0
|
447 }
|
Chris@0
|
448
|
Chris@0
|
449 if (isset($service['file'])) {
|
Chris@0
|
450 $definition->setFile($service['file']);
|
Chris@0
|
451 }
|
Chris@0
|
452
|
Chris@0
|
453 if (isset($service['arguments'])) {
|
Chris@14
|
454 $definition->setArguments($this->resolveServices($service['arguments'], $file));
|
Chris@0
|
455 }
|
Chris@0
|
456
|
Chris@0
|
457 if (isset($service['properties'])) {
|
Chris@14
|
458 $definition->setProperties($this->resolveServices($service['properties'], $file));
|
Chris@0
|
459 }
|
Chris@0
|
460
|
Chris@0
|
461 if (isset($service['configurator'])) {
|
Chris@0
|
462 $definition->setConfigurator($this->parseCallable($service['configurator'], 'configurator', $id, $file));
|
Chris@0
|
463 }
|
Chris@0
|
464
|
Chris@0
|
465 if (isset($service['calls'])) {
|
Chris@17
|
466 if (!\is_array($service['calls'])) {
|
Chris@0
|
467 throw new InvalidArgumentException(sprintf('Parameter "calls" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
|
Chris@0
|
468 }
|
Chris@0
|
469
|
Chris@0
|
470 foreach ($service['calls'] as $call) {
|
Chris@0
|
471 if (isset($call['method'])) {
|
Chris@0
|
472 $method = $call['method'];
|
Chris@17
|
473 $args = isset($call['arguments']) ? $this->resolveServices($call['arguments'], $file) : [];
|
Chris@0
|
474 } else {
|
Chris@0
|
475 $method = $call[0];
|
Chris@17
|
476 $args = isset($call[1]) ? $this->resolveServices($call[1], $file) : [];
|
Chris@0
|
477 }
|
Chris@0
|
478
|
Chris@17
|
479 if (!\is_array($args)) {
|
Chris@14
|
480 throw new InvalidArgumentException(sprintf('The second parameter for function call "%s" must be an array of its arguments for service "%s" in %s. Check your YAML syntax.', $method, $id, $file));
|
Chris@14
|
481 }
|
Chris@0
|
482 $definition->addMethodCall($method, $args);
|
Chris@0
|
483 }
|
Chris@0
|
484 }
|
Chris@0
|
485
|
Chris@17
|
486 $tags = isset($service['tags']) ? $service['tags'] : [];
|
Chris@17
|
487 if (!\is_array($tags)) {
|
Chris@14
|
488 throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
|
Chris@14
|
489 }
|
Chris@14
|
490
|
Chris@14
|
491 if (isset($defaults['tags'])) {
|
Chris@14
|
492 $tags = array_merge($tags, $defaults['tags']);
|
Chris@14
|
493 }
|
Chris@14
|
494
|
Chris@14
|
495 foreach ($tags as $tag) {
|
Chris@17
|
496 if (!\is_array($tag)) {
|
Chris@17
|
497 $tag = ['name' => $tag];
|
Chris@0
|
498 }
|
Chris@0
|
499
|
Chris@14
|
500 if (!isset($tag['name'])) {
|
Chris@14
|
501 throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s" in %s.', $id, $file));
|
Chris@14
|
502 }
|
Chris@14
|
503 $name = $tag['name'];
|
Chris@14
|
504 unset($tag['name']);
|
Chris@14
|
505
|
Chris@17
|
506 if (!\is_string($name) || '' === $name) {
|
Chris@14
|
507 throw new InvalidArgumentException(sprintf('The tag name for service "%s" in %s must be a non-empty string.', $id, $file));
|
Chris@14
|
508 }
|
Chris@14
|
509
|
Chris@14
|
510 foreach ($tag as $attribute => $value) {
|
Chris@14
|
511 if (!is_scalar($value) && null !== $value) {
|
Chris@14
|
512 throw new InvalidArgumentException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s" in %s. Check your YAML syntax.', $id, $name, $attribute, $file));
|
Chris@0
|
513 }
|
Chris@14
|
514 }
|
Chris@0
|
515
|
Chris@14
|
516 $definition->addTag($name, $tag);
|
Chris@0
|
517 }
|
Chris@0
|
518
|
Chris@0
|
519 if (isset($service['decorates'])) {
|
Chris@0
|
520 if ('' !== $service['decorates'] && '@' === $service['decorates'][0]) {
|
Chris@0
|
521 throw new InvalidArgumentException(sprintf('The value of the "decorates" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s").', $id, $service['decorates'], substr($service['decorates'], 1)));
|
Chris@0
|
522 }
|
Chris@0
|
523
|
Chris@0
|
524 $renameId = isset($service['decoration_inner_name']) ? $service['decoration_inner_name'] : null;
|
Chris@0
|
525 $priority = isset($service['decoration_priority']) ? $service['decoration_priority'] : 0;
|
Chris@0
|
526 $definition->setDecoratedService($service['decorates'], $renameId, $priority);
|
Chris@0
|
527 }
|
Chris@0
|
528
|
Chris@0
|
529 if (isset($service['autowire'])) {
|
Chris@0
|
530 $definition->setAutowired($service['autowire']);
|
Chris@0
|
531 }
|
Chris@0
|
532
|
Chris@0
|
533 if (isset($service['autowiring_types'])) {
|
Chris@17
|
534 if (\is_string($service['autowiring_types'])) {
|
Chris@0
|
535 $definition->addAutowiringType($service['autowiring_types']);
|
Chris@0
|
536 } else {
|
Chris@17
|
537 if (!\is_array($service['autowiring_types'])) {
|
Chris@0
|
538 throw new InvalidArgumentException(sprintf('Parameter "autowiring_types" must be a string or an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
|
Chris@0
|
539 }
|
Chris@0
|
540
|
Chris@0
|
541 foreach ($service['autowiring_types'] as $autowiringType) {
|
Chris@17
|
542 if (!\is_string($autowiringType)) {
|
Chris@0
|
543 throw new InvalidArgumentException(sprintf('A "autowiring_types" attribute must be of type string for service "%s" in %s. Check your YAML syntax.', $id, $file));
|
Chris@0
|
544 }
|
Chris@0
|
545
|
Chris@0
|
546 $definition->addAutowiringType($autowiringType);
|
Chris@0
|
547 }
|
Chris@0
|
548 }
|
Chris@0
|
549 }
|
Chris@0
|
550
|
Chris@14
|
551 if (isset($defaults['bind']) || isset($service['bind'])) {
|
Chris@14
|
552 // deep clone, to avoid multiple process of the same instance in the passes
|
Chris@17
|
553 $bindings = isset($defaults['bind']) ? unserialize(serialize($defaults['bind'])) : [];
|
Chris@14
|
554
|
Chris@14
|
555 if (isset($service['bind'])) {
|
Chris@17
|
556 if (!\is_array($service['bind'])) {
|
Chris@14
|
557 throw new InvalidArgumentException(sprintf('Parameter "bind" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
|
Chris@14
|
558 }
|
Chris@14
|
559
|
Chris@14
|
560 $bindings = array_merge($bindings, $this->resolveServices($service['bind'], $file));
|
Chris@14
|
561 }
|
Chris@14
|
562
|
Chris@14
|
563 $definition->setBindings($bindings);
|
Chris@14
|
564 }
|
Chris@14
|
565
|
Chris@14
|
566 if (isset($service['autoconfigure'])) {
|
Chris@14
|
567 if (!$definition instanceof ChildDefinition) {
|
Chris@14
|
568 $definition->setAutoconfigured($service['autoconfigure']);
|
Chris@14
|
569 } elseif ($service['autoconfigure']) {
|
Chris@14
|
570 throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also have "autoconfigure". Try setting "autoconfigure: false" for the service.', $id));
|
Chris@14
|
571 }
|
Chris@14
|
572 }
|
Chris@14
|
573
|
Chris@18
|
574 if (\array_key_exists('namespace', $service) && !\array_key_exists('resource', $service)) {
|
Chris@14
|
575 throw new InvalidArgumentException(sprintf('A "resource" attribute must be set when the "namespace" attribute is set for service "%s" in %s. Check your YAML syntax.', $id, $file));
|
Chris@14
|
576 }
|
Chris@14
|
577
|
Chris@18
|
578 if (\array_key_exists('resource', $service)) {
|
Chris@17
|
579 if (!\is_string($service['resource'])) {
|
Chris@14
|
580 throw new InvalidArgumentException(sprintf('A "resource" attribute must be of type string for service "%s" in %s. Check your YAML syntax.', $id, $file));
|
Chris@14
|
581 }
|
Chris@14
|
582 $exclude = isset($service['exclude']) ? $service['exclude'] : null;
|
Chris@14
|
583 $namespace = isset($service['namespace']) ? $service['namespace'] : $id;
|
Chris@14
|
584 $this->registerClasses($definition, $namespace, $service['resource'], $exclude);
|
Chris@14
|
585 } else {
|
Chris@14
|
586 $this->setDefinition($id, $definition);
|
Chris@14
|
587 }
|
Chris@0
|
588 }
|
Chris@0
|
589
|
Chris@0
|
590 /**
|
Chris@0
|
591 * Parses a callable.
|
Chris@0
|
592 *
|
Chris@0
|
593 * @param string|array $callable A callable
|
Chris@0
|
594 * @param string $parameter A parameter (e.g. 'factory' or 'configurator')
|
Chris@0
|
595 * @param string $id A service identifier
|
Chris@0
|
596 * @param string $file A parsed file
|
Chris@0
|
597 *
|
Chris@17
|
598 * @throws InvalidArgumentException When errors occur
|
Chris@0
|
599 *
|
Chris@0
|
600 * @return string|array A parsed callable
|
Chris@0
|
601 */
|
Chris@0
|
602 private function parseCallable($callable, $parameter, $id, $file)
|
Chris@0
|
603 {
|
Chris@17
|
604 if (\is_string($callable)) {
|
Chris@0
|
605 if ('' !== $callable && '@' === $callable[0]) {
|
Chris@0
|
606 throw new InvalidArgumentException(sprintf('The value of the "%s" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s").', $parameter, $id, $callable, substr($callable, 1)));
|
Chris@0
|
607 }
|
Chris@0
|
608
|
Chris@0
|
609 if (false !== strpos($callable, ':') && false === strpos($callable, '::')) {
|
Chris@0
|
610 $parts = explode(':', $callable);
|
Chris@0
|
611
|
Chris@17
|
612 return [$this->resolveServices('@'.$parts[0], $file), $parts[1]];
|
Chris@0
|
613 }
|
Chris@0
|
614
|
Chris@0
|
615 return $callable;
|
Chris@0
|
616 }
|
Chris@0
|
617
|
Chris@17
|
618 if (\is_array($callable)) {
|
Chris@0
|
619 if (isset($callable[0]) && isset($callable[1])) {
|
Chris@17
|
620 return [$this->resolveServices($callable[0], $file), $callable[1]];
|
Chris@14
|
621 }
|
Chris@14
|
622
|
Chris@14
|
623 if ('factory' === $parameter && isset($callable[1]) && null === $callable[0]) {
|
Chris@14
|
624 return $callable;
|
Chris@0
|
625 }
|
Chris@0
|
626
|
Chris@0
|
627 throw new InvalidArgumentException(sprintf('Parameter "%s" must contain an array with two elements for service "%s" in %s. Check your YAML syntax.', $parameter, $id, $file));
|
Chris@0
|
628 }
|
Chris@0
|
629
|
Chris@0
|
630 throw new InvalidArgumentException(sprintf('Parameter "%s" must be a string or an array for service "%s" in %s. Check your YAML syntax.', $parameter, $id, $file));
|
Chris@0
|
631 }
|
Chris@0
|
632
|
Chris@0
|
633 /**
|
Chris@0
|
634 * Loads a YAML file.
|
Chris@0
|
635 *
|
Chris@0
|
636 * @param string $file
|
Chris@0
|
637 *
|
Chris@0
|
638 * @return array The file content
|
Chris@0
|
639 *
|
Chris@0
|
640 * @throws InvalidArgumentException when the given file is not a local file or when it does not exist
|
Chris@0
|
641 */
|
Chris@0
|
642 protected function loadFile($file)
|
Chris@0
|
643 {
|
Chris@0
|
644 if (!class_exists('Symfony\Component\Yaml\Parser')) {
|
Chris@0
|
645 throw new RuntimeException('Unable to load YAML config files as the Symfony Yaml Component is not installed.');
|
Chris@0
|
646 }
|
Chris@0
|
647
|
Chris@0
|
648 if (!stream_is_local($file)) {
|
Chris@0
|
649 throw new InvalidArgumentException(sprintf('This is not a local file "%s".', $file));
|
Chris@0
|
650 }
|
Chris@0
|
651
|
Chris@0
|
652 if (!file_exists($file)) {
|
Chris@0
|
653 throw new InvalidArgumentException(sprintf('The file "%s" does not exist.', $file));
|
Chris@0
|
654 }
|
Chris@0
|
655
|
Chris@0
|
656 if (null === $this->yamlParser) {
|
Chris@0
|
657 $this->yamlParser = new YamlParser();
|
Chris@0
|
658 }
|
Chris@0
|
659
|
Chris@14
|
660 $prevErrorHandler = set_error_handler(function ($level, $message, $script, $line) use ($file, &$prevErrorHandler) {
|
Chris@14
|
661 $message = E_USER_DEPRECATED === $level ? preg_replace('/ on line \d+/', ' in "'.$file.'"$0', $message) : $message;
|
Chris@14
|
662
|
Chris@14
|
663 return $prevErrorHandler ? $prevErrorHandler($level, $message, $script, $line) : false;
|
Chris@14
|
664 });
|
Chris@14
|
665
|
Chris@0
|
666 try {
|
Chris@14
|
667 $configuration = $this->yamlParser->parseFile($file, Yaml::PARSE_CONSTANT | Yaml::PARSE_CUSTOM_TAGS);
|
Chris@0
|
668 } catch (ParseException $e) {
|
Chris@17
|
669 throw new InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML: %s', $file, $e->getMessage()), 0, $e);
|
Chris@14
|
670 } finally {
|
Chris@14
|
671 restore_error_handler();
|
Chris@0
|
672 }
|
Chris@0
|
673
|
Chris@0
|
674 return $this->validate($configuration, $file);
|
Chris@0
|
675 }
|
Chris@0
|
676
|
Chris@0
|
677 /**
|
Chris@0
|
678 * Validates a YAML file.
|
Chris@0
|
679 *
|
Chris@0
|
680 * @param mixed $content
|
Chris@0
|
681 * @param string $file
|
Chris@0
|
682 *
|
Chris@0
|
683 * @return array
|
Chris@0
|
684 *
|
Chris@0
|
685 * @throws InvalidArgumentException When service file is not valid
|
Chris@0
|
686 */
|
Chris@0
|
687 private function validate($content, $file)
|
Chris@0
|
688 {
|
Chris@0
|
689 if (null === $content) {
|
Chris@0
|
690 return $content;
|
Chris@0
|
691 }
|
Chris@0
|
692
|
Chris@17
|
693 if (!\is_array($content)) {
|
Chris@0
|
694 throw new InvalidArgumentException(sprintf('The service file "%s" is not valid. It should contain an array. Check your YAML syntax.', $file));
|
Chris@0
|
695 }
|
Chris@0
|
696
|
Chris@0
|
697 foreach ($content as $namespace => $data) {
|
Chris@17
|
698 if (\in_array($namespace, ['imports', 'parameters', 'services'])) {
|
Chris@0
|
699 continue;
|
Chris@0
|
700 }
|
Chris@0
|
701
|
Chris@0
|
702 if (!$this->container->hasExtension($namespace)) {
|
Chris@0
|
703 $extensionNamespaces = array_filter(array_map(function ($ext) { return $ext->getAlias(); }, $this->container->getExtensions()));
|
Chris@17
|
704 throw new InvalidArgumentException(sprintf('There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s', $namespace, $file, $namespace, $extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none'));
|
Chris@0
|
705 }
|
Chris@0
|
706 }
|
Chris@0
|
707
|
Chris@0
|
708 return $content;
|
Chris@0
|
709 }
|
Chris@0
|
710
|
Chris@0
|
711 /**
|
Chris@0
|
712 * Resolves services.
|
Chris@0
|
713 *
|
Chris@14
|
714 * @param mixed $value
|
Chris@14
|
715 * @param string $file
|
Chris@14
|
716 * @param bool $isParameter
|
Chris@0
|
717 *
|
Chris@14
|
718 * @return array|string|Reference|ArgumentInterface
|
Chris@0
|
719 */
|
Chris@14
|
720 private function resolveServices($value, $file, $isParameter = false)
|
Chris@0
|
721 {
|
Chris@14
|
722 if ($value instanceof TaggedValue) {
|
Chris@14
|
723 $argument = $value->getValue();
|
Chris@14
|
724 if ('iterator' === $value->getTag()) {
|
Chris@17
|
725 if (!\is_array($argument)) {
|
Chris@14
|
726 throw new InvalidArgumentException(sprintf('"!iterator" tag only accepts sequences in "%s".', $file));
|
Chris@14
|
727 }
|
Chris@14
|
728 $argument = $this->resolveServices($argument, $file, $isParameter);
|
Chris@14
|
729 try {
|
Chris@14
|
730 return new IteratorArgument($argument);
|
Chris@14
|
731 } catch (InvalidArgumentException $e) {
|
Chris@14
|
732 throw new InvalidArgumentException(sprintf('"!iterator" tag only accepts arrays of "@service" references in "%s".', $file));
|
Chris@14
|
733 }
|
Chris@14
|
734 }
|
Chris@14
|
735 if ('tagged' === $value->getTag()) {
|
Chris@17
|
736 if (!\is_string($argument) || !$argument) {
|
Chris@14
|
737 throw new InvalidArgumentException(sprintf('"!tagged" tag only accepts non empty string in "%s".', $file));
|
Chris@14
|
738 }
|
Chris@14
|
739
|
Chris@14
|
740 return new TaggedIteratorArgument($argument);
|
Chris@14
|
741 }
|
Chris@14
|
742 if ('service' === $value->getTag()) {
|
Chris@14
|
743 if ($isParameter) {
|
Chris@14
|
744 throw new InvalidArgumentException(sprintf('Using an anonymous service in a parameter is not allowed in "%s".', $file));
|
Chris@14
|
745 }
|
Chris@14
|
746
|
Chris@14
|
747 $isLoadingInstanceof = $this->isLoadingInstanceof;
|
Chris@14
|
748 $this->isLoadingInstanceof = false;
|
Chris@14
|
749 $instanceof = $this->instanceof;
|
Chris@17
|
750 $this->instanceof = [];
|
Chris@14
|
751
|
Chris@14
|
752 $id = sprintf('%d_%s', ++$this->anonymousServicesCount, preg_replace('/^.*\\\\/', '', isset($argument['class']) ? $argument['class'] : '').$this->anonymousServicesSuffix);
|
Chris@17
|
753 $this->parseDefinition($id, $argument, $file, []);
|
Chris@14
|
754
|
Chris@14
|
755 if (!$this->container->hasDefinition($id)) {
|
Chris@14
|
756 throw new InvalidArgumentException(sprintf('Creating an alias using the tag "!service" is not allowed in "%s".', $file));
|
Chris@14
|
757 }
|
Chris@14
|
758
|
Chris@14
|
759 $this->container->getDefinition($id)->setPublic(false);
|
Chris@14
|
760
|
Chris@14
|
761 $this->isLoadingInstanceof = $isLoadingInstanceof;
|
Chris@14
|
762 $this->instanceof = $instanceof;
|
Chris@14
|
763
|
Chris@14
|
764 return new Reference($id);
|
Chris@14
|
765 }
|
Chris@14
|
766
|
Chris@14
|
767 throw new InvalidArgumentException(sprintf('Unsupported tag "!%s".', $value->getTag()));
|
Chris@14
|
768 }
|
Chris@14
|
769
|
Chris@17
|
770 if (\is_array($value)) {
|
Chris@14
|
771 foreach ($value as $k => $v) {
|
Chris@14
|
772 $value[$k] = $this->resolveServices($v, $file, $isParameter);
|
Chris@14
|
773 }
|
Chris@17
|
774 } elseif (\is_string($value) && 0 === strpos($value, '@=')) {
|
Chris@14
|
775 if (!class_exists(Expression::class)) {
|
Chris@14
|
776 throw new \LogicException(sprintf('The "@=" expression syntax cannot be used without the ExpressionLanguage component. Try running "composer require symfony/expression-language".'));
|
Chris@14
|
777 }
|
Chris@14
|
778
|
Chris@0
|
779 return new Expression(substr($value, 2));
|
Chris@17
|
780 } elseif (\is_string($value) && 0 === strpos($value, '@')) {
|
Chris@0
|
781 if (0 === strpos($value, '@@')) {
|
Chris@0
|
782 $value = substr($value, 1);
|
Chris@0
|
783 $invalidBehavior = null;
|
Chris@14
|
784 } elseif (0 === strpos($value, '@!')) {
|
Chris@14
|
785 $value = substr($value, 2);
|
Chris@14
|
786 $invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE;
|
Chris@0
|
787 } elseif (0 === strpos($value, '@?')) {
|
Chris@0
|
788 $value = substr($value, 2);
|
Chris@0
|
789 $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
|
Chris@0
|
790 } else {
|
Chris@0
|
791 $value = substr($value, 1);
|
Chris@0
|
792 $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
|
Chris@0
|
793 }
|
Chris@0
|
794
|
Chris@0
|
795 if ('=' === substr($value, -1)) {
|
Chris@14
|
796 @trigger_error(sprintf('The "=" suffix that used to disable strict references in Symfony 2.x is deprecated since Symfony 3.3 and will be unsupported in 4.0. Remove it in "%s".', $value), E_USER_DEPRECATED);
|
Chris@0
|
797 $value = substr($value, 0, -1);
|
Chris@0
|
798 }
|
Chris@0
|
799
|
Chris@0
|
800 if (null !== $invalidBehavior) {
|
Chris@0
|
801 $value = new Reference($value, $invalidBehavior);
|
Chris@0
|
802 }
|
Chris@0
|
803 }
|
Chris@0
|
804
|
Chris@0
|
805 return $value;
|
Chris@0
|
806 }
|
Chris@0
|
807
|
Chris@0
|
808 /**
|
Chris@0
|
809 * Loads from Extensions.
|
Chris@0
|
810 */
|
Chris@0
|
811 private function loadFromExtensions(array $content)
|
Chris@0
|
812 {
|
Chris@0
|
813 foreach ($content as $namespace => $values) {
|
Chris@17
|
814 if (\in_array($namespace, ['imports', 'parameters', 'services'])) {
|
Chris@0
|
815 continue;
|
Chris@0
|
816 }
|
Chris@0
|
817
|
Chris@17
|
818 if (!\is_array($values) && null !== $values) {
|
Chris@17
|
819 $values = [];
|
Chris@0
|
820 }
|
Chris@0
|
821
|
Chris@0
|
822 $this->container->loadFromExtension($namespace, $values);
|
Chris@0
|
823 }
|
Chris@0
|
824 }
|
Chris@0
|
825
|
Chris@0
|
826 /**
|
Chris@0
|
827 * Checks the keywords used to define a service.
|
Chris@0
|
828 *
|
Chris@0
|
829 * @param string $id The service name
|
Chris@0
|
830 * @param array $definition The service definition to check
|
Chris@0
|
831 * @param string $file The loaded YAML file
|
Chris@0
|
832 */
|
Chris@14
|
833 private function checkDefinition($id, array $definition, $file)
|
Chris@0
|
834 {
|
Chris@14
|
835 if ($throw = $this->isLoadingInstanceof) {
|
Chris@14
|
836 $keywords = self::$instanceofKeywords;
|
Chris@14
|
837 } elseif ($throw = (isset($definition['resource']) || isset($definition['namespace']))) {
|
Chris@14
|
838 $keywords = self::$prototypeKeywords;
|
Chris@14
|
839 } else {
|
Chris@14
|
840 $keywords = self::$serviceKeywords;
|
Chris@14
|
841 }
|
Chris@14
|
842
|
Chris@0
|
843 foreach ($definition as $key => $value) {
|
Chris@14
|
844 if (!isset($keywords[$key])) {
|
Chris@14
|
845 if ($throw) {
|
Chris@14
|
846 throw new InvalidArgumentException(sprintf('The configuration key "%s" is unsupported for definition "%s" in "%s". Allowed configuration keys are "%s".', $key, $id, $file, implode('", "', $keywords)));
|
Chris@14
|
847 }
|
Chris@14
|
848
|
Chris@14
|
849 @trigger_error(sprintf('The configuration key "%s" is unsupported for service definition "%s" in "%s". Allowed configuration keys are "%s". The YamlFileLoader object will raise an exception instead in Symfony 4.0 when detecting an unsupported service configuration key.', $key, $id, $file, implode('", "', $keywords)), E_USER_DEPRECATED);
|
Chris@0
|
850 }
|
Chris@0
|
851 }
|
Chris@0
|
852 }
|
Chris@0
|
853 }
|