4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\DependencyInjection\Compiler;
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;
20 * Emulates the invalid behavior if the reference is not found within the
23 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
25 class ResolveInvalidReferencesPass implements CompilerPassInterface
30 * Process the ContainerBuilder to resolve invalid references.
32 * @param ContainerBuilder $container
34 public function process(ContainerBuilder $container)
36 $this->container = $container;
37 foreach ($container->getDefinitions() as $definition) {
38 if ($definition->isSynthetic() || $definition->isAbstract()) {
42 $definition->setArguments(
43 $this->processArguments($definition->getArguments())
47 foreach ($definition->getMethodCalls() as $call) {
49 $calls[] = array($call[0], $this->processArguments($call[1], true));
50 } catch (RuntimeException $e) {
51 // this call is simply removed
54 $definition->setMethodCalls($calls);
56 $properties = array();
57 foreach ($definition->getProperties() as $name => $value) {
59 $value = $this->processArguments(array($value), true);
60 $properties[$name] = reset($value);
61 } catch (RuntimeException $e) {
65 $definition->setProperties($properties);
70 * Processes arguments to determine invalid references.
72 * @param array $arguments An array of Reference objects
73 * @param bool $inMethodCall
77 * @throws RuntimeException When the config is invalid
79 private function processArguments(array $arguments, $inMethodCall = false)
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;
87 $invalidBehavior = $argument->getInvalidBehavior();
88 $exists = $this->container->has($id);
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) {
95 throw new RuntimeException('Method shouldn\'t be called.');
98 $arguments[$k] = null;