You are here

ResolveInvalidReferencesPass.php in Service Container 7.2

File

modules/providers/service_container_symfony/lib/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php
View source
<?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 $ignore) {

          // 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 $ignore) {

          // 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;
  }

}

Classes

Namesort descending Description
ResolveInvalidReferencesPass Emulates the invalid behavior if the reference is not found within the container.