[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/vendor/symfony/dependency-injection/Compiler/ -> CheckReferenceValidityPass.php (source)

   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\ContainerBuilder;
  15  use Symfony\Component\DependencyInjection\ContainerInterface;
  16  use Symfony\Component\DependencyInjection\Definition;
  17  use Symfony\Component\DependencyInjection\Exception\RuntimeException;
  18  use Symfony\Component\DependencyInjection\Exception\ScopeCrossingInjectionException;
  19  use Symfony\Component\DependencyInjection\Exception\ScopeWideningInjectionException;
  20  use Symfony\Component\DependencyInjection\Reference;
  21  
  22  /**
  23   * Checks the validity of references.
  24   *
  25   * The following checks are performed by this pass:
  26   * - target definitions are not abstract
  27   * - target definitions are of equal or wider scope
  28   * - target definitions are in the same scope hierarchy
  29   *
  30   * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  31   */
  32  class CheckReferenceValidityPass implements CompilerPassInterface
  33  {
  34      private $container;
  35      private $currentId;
  36      private $currentScope;
  37      private $currentScopeAncestors;
  38      private $currentScopeChildren;
  39  
  40      /**
  41       * Processes the ContainerBuilder to validate References.
  42       */
  43      public function process(ContainerBuilder $container)
  44      {
  45          $this->container = $container;
  46  
  47          $children = $this->container->getScopeChildren(false);
  48          $ancestors = array();
  49  
  50          $scopes = $this->container->getScopes(false);
  51          foreach ($scopes as $name => $parent) {
  52              $ancestors[$name] = array($parent);
  53  
  54              while (isset($scopes[$parent])) {
  55                  $ancestors[$name][] = $parent = $scopes[$parent];
  56              }
  57          }
  58  
  59          foreach ($container->getDefinitions() as $id => $definition) {
  60              if ($definition->isSynthetic() || $definition->isAbstract()) {
  61                  continue;
  62              }
  63  
  64              $this->currentId = $id;
  65              $this->currentScope = $scope = $definition->getScope(false);
  66  
  67              if (ContainerInterface::SCOPE_CONTAINER === $scope) {
  68                  $this->currentScopeChildren = array_keys($scopes);
  69                  $this->currentScopeAncestors = array();
  70              } elseif (ContainerInterface::SCOPE_PROTOTYPE !== $scope) {
  71                  $this->currentScopeChildren = isset($children[$scope]) ? $children[$scope] : array();
  72                  $this->currentScopeAncestors = isset($ancestors[$scope]) ? $ancestors[$scope] : array();
  73              }
  74  
  75              $this->validateReferences($definition->getArguments());
  76              $this->validateReferences($definition->getMethodCalls());
  77              $this->validateReferences($definition->getProperties());
  78          }
  79      }
  80  
  81      /**
  82       * Validates an array of References.
  83       *
  84       * @param array $arguments An array of Reference objects
  85       *
  86       * @throws RuntimeException when there is a reference to an abstract definition
  87       */
  88      private function validateReferences(array $arguments)
  89      {
  90          foreach ($arguments as $argument) {
  91              if (\is_array($argument)) {
  92                  $this->validateReferences($argument);
  93              } elseif ($argument instanceof Reference) {
  94                  $targetDefinition = $this->getDefinition((string) $argument);
  95  
  96                  if (null !== $targetDefinition && $targetDefinition->isAbstract()) {
  97                      throw new RuntimeException(sprintf('The definition "%s" has a reference to an abstract definition "%s". Abstract definitions cannot be the target of references.', $this->currentId, $argument));
  98                  }
  99  
 100                  $this->validateScope($argument, $targetDefinition);
 101              }
 102          }
 103      }
 104  
 105      /**
 106       * Validates the scope of a single Reference.
 107       *
 108       * @throws ScopeWideningInjectionException when the definition references a service of a narrower scope
 109       * @throws ScopeCrossingInjectionException when the definition references a service of another scope hierarchy
 110       */
 111      private function validateScope(Reference $reference, Definition $definition = null)
 112      {
 113          if (ContainerInterface::SCOPE_PROTOTYPE === $this->currentScope) {
 114              return;
 115          }
 116  
 117          if (!$reference->isStrict(false)) {
 118              return;
 119          }
 120  
 121          if (null === $definition) {
 122              return;
 123          }
 124  
 125          if ($this->currentScope === $scope = $definition->getScope(false)) {
 126              return;
 127          }
 128  
 129          $id = (string) $reference;
 130  
 131          if (\in_array($scope, $this->currentScopeChildren, true)) {
 132              throw new ScopeWideningInjectionException($this->currentId, $this->currentScope, $id, $scope);
 133          }
 134  
 135          if (!\in_array($scope, $this->currentScopeAncestors, true)) {
 136              throw new ScopeCrossingInjectionException($this->currentId, $this->currentScope, $id, $scope);
 137          }
 138      }
 139  
 140      /**
 141       * Returns the Definition given an id.
 142       *
 143       * @param string $id Definition identifier
 144       *
 145       * @return Definition
 146       */
 147      private function getDefinition($id)
 148      {
 149          if (!$this->container->hasDefinition($id)) {
 150              return;
 151          }
 152  
 153          return $this->container->getDefinition($id);
 154      }
 155  }


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1