comparison vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 1fec387a4317
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Symfony\Component\DependencyInjection\Compiler;
13
14 use Symfony\Component\DependencyInjection\ContainerInterface;
15 use Symfony\Component\DependencyInjection\Reference;
16 use Symfony\Component\DependencyInjection\ContainerBuilder;
17 use Symfony\Component\DependencyInjection\Exception\RuntimeException;
18
19 /**
20 * Emulates the invalid behavior if the reference is not found within the
21 * container.
22 *
23 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
24 */
25 class ResolveInvalidReferencesPass implements CompilerPassInterface
26 {
27 private $container;
28
29 /**
30 * Process the ContainerBuilder to resolve invalid references.
31 *
32 * @param ContainerBuilder $container
33 */
34 public function process(ContainerBuilder $container)
35 {
36 $this->container = $container;
37 foreach ($container->getDefinitions() as $definition) {
38 if ($definition->isSynthetic() || $definition->isAbstract()) {
39 continue;
40 }
41
42 $definition->setArguments(
43 $this->processArguments($definition->getArguments())
44 );
45
46 $calls = array();
47 foreach ($definition->getMethodCalls() as $call) {
48 try {
49 $calls[] = array($call[0], $this->processArguments($call[1], true));
50 } catch (RuntimeException $e) {
51 // this call is simply removed
52 }
53 }
54 $definition->setMethodCalls($calls);
55
56 $properties = array();
57 foreach ($definition->getProperties() as $name => $value) {
58 try {
59 $value = $this->processArguments(array($value), true);
60 $properties[$name] = reset($value);
61 } catch (RuntimeException $e) {
62 // ignore property
63 }
64 }
65 $definition->setProperties($properties);
66 }
67 }
68
69 /**
70 * Processes arguments to determine invalid references.
71 *
72 * @param array $arguments An array of Reference objects
73 * @param bool $inMethodCall
74 * @param bool $inCollection
75 *
76 * @return array
77 *
78 * @throws RuntimeException When the config is invalid
79 */
80 private function processArguments(array $arguments, $inMethodCall = false, $inCollection = false)
81 {
82 $isNumeric = array_keys($arguments) === range(0, count($arguments) - 1);
83
84 foreach ($arguments as $k => $argument) {
85 if (is_array($argument)) {
86 $arguments[$k] = $this->processArguments($argument, $inMethodCall, true);
87 } elseif ($argument instanceof Reference) {
88 $id = (string) $argument;
89
90 $invalidBehavior = $argument->getInvalidBehavior();
91 $exists = $this->container->has($id);
92
93 // resolve invalid behavior
94 if (!$exists && ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) {
95 $arguments[$k] = null;
96 } elseif (!$exists && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) {
97 if ($inCollection) {
98 unset($arguments[$k]);
99 continue;
100 }
101 if ($inMethodCall) {
102 throw new RuntimeException('Method shouldn\'t be called.');
103 }
104
105 $arguments[$k] = null;
106 }
107 }
108 }
109
110 // Ensure numerically indexed arguments have sequential numeric keys.
111 if ($isNumeric) {
112 $arguments = array_values($arguments);
113 }
114
115 return $arguments;
116 }
117 }