Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

CheckReferenceValidityPass.php

Zuletzt modifiziert: 09.10.2024, 12:56 - Dateigröße: 5.44 KiB


 001  <?php
 002   
 003  /*
 004   * This file is part of the Symfony package.
 005   *
 006   * (c) Fabien Potencier <fabien@symfony.com>
 007   *
 008   * For the full copyright and license information, please view the LICENSE
 009   * file that was distributed with this source code.
 010   */
 011   
 012  namespace Symfony\Component\DependencyInjection\Compiler;
 013   
 014  use Symfony\Component\DependencyInjection\Definition;
 015  use Symfony\Component\DependencyInjection\ContainerInterface;
 016  use Symfony\Component\DependencyInjection\Reference;
 017  use Symfony\Component\DependencyInjection\ContainerBuilder;
 018  use Symfony\Component\DependencyInjection\Exception\RuntimeException;
 019  use Symfony\Component\DependencyInjection\Exception\ScopeCrossingInjectionException;
 020  use Symfony\Component\DependencyInjection\Exception\ScopeWideningInjectionException;
 021   
 022  /**
 023   * Checks the validity of references.
 024   *
 025   * The following checks are performed by this pass:
 026   * - target definitions are not abstract
 027   * - target definitions are of equal or wider scope
 028   * - target definitions are in the same scope hierarchy
 029   *
 030   * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 031   */
 032  class CheckReferenceValidityPass implements CompilerPassInterface
 033  {
 034      private $container;
 035      private $currentId;
 036      private $currentScope;
 037      private $currentScopeAncestors;
 038      private $currentScopeChildren;
 039   
 040      /**
 041       * Processes the ContainerBuilder to validate References.
 042       *
 043       * @param ContainerBuilder $container
 044       */
 045      public function process(ContainerBuilder $container)
 046      {
 047          $this->container = $container;
 048   
 049          $children = $this->container->getScopeChildren(false);
 050          $ancestors = array();
 051   
 052          $scopes = $this->container->getScopes(false);
 053          foreach ($scopes as $name => $parent) {
 054              $ancestors[$name] = array($parent);
 055   
 056              while (isset($scopes[$parent])) {
 057                  $ancestors[$name][] = $parent = $scopes[$parent];
 058              }
 059          }
 060   
 061          foreach ($container->getDefinitions() as $id => $definition) {
 062              if ($definition->isSynthetic() || $definition->isAbstract()) {
 063                  continue;
 064              }
 065   
 066              $this->currentId = $id;
 067              $this->currentScope = $scope = $definition->getScope(false);
 068   
 069              if (ContainerInterface::SCOPE_CONTAINER === $scope) {
 070                  $this->currentScopeChildren = array_keys($scopes);
 071                  $this->currentScopeAncestors = array();
 072              } elseif (ContainerInterface::SCOPE_PROTOTYPE !== $scope) {
 073                  $this->currentScopeChildren = isset($children[$scope]) ? $children[$scope] : array();
 074                  $this->currentScopeAncestors = isset($ancestors[$scope]) ? $ancestors[$scope] : array();
 075              }
 076   
 077              $this->validateReferences($definition->getArguments());
 078              $this->validateReferences($definition->getMethodCalls());
 079              $this->validateReferences($definition->getProperties());
 080          }
 081      }
 082   
 083      /**
 084       * Validates an array of References.
 085       *
 086       * @param array $arguments An array of Reference objects
 087       *
 088       * @throws RuntimeException when there is a reference to an abstract definition.
 089       */
 090      private function validateReferences(array $arguments)
 091      {
 092          foreach ($arguments as $argument) {
 093              if (is_array($argument)) {
 094                  $this->validateReferences($argument);
 095              } elseif ($argument instanceof Reference) {
 096                  $targetDefinition = $this->getDefinition((string) $argument);
 097   
 098                  if (null !== $targetDefinition && $targetDefinition->isAbstract()) {
 099                      throw new RuntimeException(sprintf(
 100                          'The definition "%s" has a reference to an abstract definition "%s". '
 101                         .'Abstract definitions cannot be the target of references.',
 102                         $this->currentId,
 103                         $argument
 104                      ));
 105                  }
 106   
 107                  $this->validateScope($argument, $targetDefinition);
 108              }
 109          }
 110      }
 111   
 112      /**
 113       * Validates the scope of a single Reference.
 114       *
 115       * @param Reference  $reference
 116       * @param Definition $definition
 117       *
 118       * @throws ScopeWideningInjectionException when the definition references a service of a narrower scope
 119       * @throws ScopeCrossingInjectionException when the definition references a service of another scope hierarchy
 120       */
 121      private function validateScope(Reference $reference, Definition $definition = null)
 122      {
 123          if (ContainerInterface::SCOPE_PROTOTYPE === $this->currentScope) {
 124              return;
 125          }
 126   
 127          if (!$reference->isStrict(false)) {
 128              return;
 129          }
 130   
 131          if (null === $definition) {
 132              return;
 133          }
 134   
 135          if ($this->currentScope === $scope = $definition->getScope(false)) {
 136              return;
 137          }
 138   
 139          $id = (string) $reference;
 140   
 141          if (in_array($scope, $this->currentScopeChildren, true)) {
 142              throw new ScopeWideningInjectionException($this->currentId, $this->currentScope, $id, $scope);
 143          }
 144   
 145          if (!in_array($scope, $this->currentScopeAncestors, true)) {
 146              throw new ScopeCrossingInjectionException($this->currentId, $this->currentScope, $id, $scope);
 147          }
 148      }
 149   
 150      /**
 151       * Returns the Definition given an id.
 152       *
 153       * @param string $id Definition identifier
 154       *
 155       * @return Definition
 156       */
 157      private function getDefinition($id)
 158      {
 159          if (!$this->container->hasDefinition($id)) {
 160              return;
 161          }
 162   
 163          return $this->container->getDefinition($id);
 164      }
 165  }
 166