Version 1
[yaffs-website] / vendor / symfony / dependency-injection / Compiler / ResolveInvalidReferencesPass.php
diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php
new file mode 100644 (file)
index 0000000..85dbceb
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Exception\RuntimeException;
+
+/**
+ * Emulates the invalid behavior if the reference is not found within the
+ * container.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ResolveInvalidReferencesPass implements CompilerPassInterface
+{
+    private $container;
+
+    /**
+     * Process the ContainerBuilder to resolve invalid references.
+     *
+     * @param ContainerBuilder $container
+     */
+    public function process(ContainerBuilder $container)
+    {
+        $this->container = $container;
+        foreach ($container->getDefinitions() as $definition) {
+            if ($definition->isSynthetic() || $definition->isAbstract()) {
+                continue;
+            }
+
+            $definition->setArguments(
+                $this->processArguments($definition->getArguments())
+            );
+
+            $calls = array();
+            foreach ($definition->getMethodCalls() as $call) {
+                try {
+                    $calls[] = array($call[0], $this->processArguments($call[1], true));
+                } catch (RuntimeException $e) {
+                    // this call is simply removed
+                }
+            }
+            $definition->setMethodCalls($calls);
+
+            $properties = array();
+            foreach ($definition->getProperties() as $name => $value) {
+                try {
+                    $value = $this->processArguments(array($value), true);
+                    $properties[$name] = reset($value);
+                } catch (RuntimeException $e) {
+                    // ignore property
+                }
+            }
+            $definition->setProperties($properties);
+        }
+    }
+
+    /**
+     * Processes arguments to determine invalid references.
+     *
+     * @param array $arguments    An array of Reference objects
+     * @param bool  $inMethodCall
+     *
+     * @return array
+     *
+     * @throws RuntimeException When the config is invalid
+     */
+    private function processArguments(array $arguments, $inMethodCall = false)
+    {
+        foreach ($arguments as $k => $argument) {
+            if (is_array($argument)) {
+                $arguments[$k] = $this->processArguments($argument, $inMethodCall);
+            } elseif ($argument instanceof Reference) {
+                $id = (string) $argument;
+
+                $invalidBehavior = $argument->getInvalidBehavior();
+                $exists = $this->container->has($id);
+
+                // resolve invalid behavior
+                if (!$exists && ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) {
+                    $arguments[$k] = null;
+                } elseif (!$exists && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) {
+                    if ($inMethodCall) {
+                        throw new RuntimeException('Method shouldn\'t be called.');
+                    }
+
+                    $arguments[$k] = null;
+                }
+            }
+        }
+
+        return $arguments;
+    }
+}