85dbceb9a61ec526e290eb64f6dd4405485abb58
[yaffs-website] / vendor / symfony / dependency-injection / Compiler / ResolveInvalidReferencesPass.php
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      *
75      * @return array
76      *
77      * @throws RuntimeException When the config is invalid
78      */
79     private function processArguments(array $arguments, $inMethodCall = false)
80     {
81         foreach ($arguments as $k => $argument) {
82             if (is_array($argument)) {
83                 $arguments[$k] = $this->processArguments($argument, $inMethodCall);
84             } elseif ($argument instanceof Reference) {
85                 $id = (string) $argument;
86
87                 $invalidBehavior = $argument->getInvalidBehavior();
88                 $exists = $this->container->has($id);
89
90                 // resolve invalid behavior
91                 if (!$exists && ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) {
92                     $arguments[$k] = null;
93                 } elseif (!$exists && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) {
94                     if ($inMethodCall) {
95                         throw new RuntimeException('Method shouldn\'t be called.');
96                     }
97
98                     $arguments[$k] = null;
99                 }
100             }
101         }
102
103         return $arguments;
104     }
105 }