[ Index ]

PHP Cross Reference of phpBB-3.3.9-deutsch

title

Body

[close]

/vendor/symfony/dependency-injection/Compiler/ -> ResolveInstanceofConditionalsPass.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\ChildDefinition;
  15  use Symfony\Component\DependencyInjection\ContainerBuilder;
  16  use Symfony\Component\DependencyInjection\Definition;
  17  use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
  18  use Symfony\Component\DependencyInjection\Exception\RuntimeException;
  19  
  20  /**
  21   * Applies instanceof conditionals to definitions.
  22   *
  23   * @author Nicolas Grekas <p@tchwork.com>
  24   */
  25  class ResolveInstanceofConditionalsPass implements CompilerPassInterface
  26  {
  27      /**
  28       * {@inheritdoc}
  29       */
  30      public function process(ContainerBuilder $container)
  31      {
  32          foreach ($container->getAutoconfiguredInstanceof() as $interface => $definition) {
  33              if ($definition->getArguments()) {
  34                  throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines arguments but these are not supported and should be removed.', $interface));
  35              }
  36              if ($definition->getMethodCalls()) {
  37                  throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines method calls but these are not supported and should be removed.', $interface));
  38              }
  39          }
  40  
  41          foreach ($container->getDefinitions() as $id => $definition) {
  42              if ($definition instanceof ChildDefinition) {
  43                  // don't apply "instanceof" to children: it will be applied to their parent
  44                  continue;
  45              }
  46              $container->setDefinition($id, $this->processDefinition($container, $id, $definition));
  47          }
  48      }
  49  
  50      private function processDefinition(ContainerBuilder $container, $id, Definition $definition)
  51      {
  52          $instanceofConditionals = $definition->getInstanceofConditionals();
  53          $autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : [];
  54          if (!$instanceofConditionals && !$autoconfiguredInstanceof) {
  55              return $definition;
  56          }
  57  
  58          if (!$class = $container->getParameterBag()->resolveValue($definition->getClass())) {
  59              return $definition;
  60          }
  61  
  62          $conditionals = $this->mergeConditionals($autoconfiguredInstanceof, $instanceofConditionals, $container);
  63  
  64          $definition->setInstanceofConditionals([]);
  65          $parent = $shared = null;
  66          $instanceofTags = [];
  67          $reflectionClass = null;
  68  
  69          foreach ($conditionals as $interface => $instanceofDefs) {
  70              if ($interface !== $class && !(null === $reflectionClass ? $reflectionClass = ($container->getReflectionClass($class, false) ?: false) : $reflectionClass)) {
  71                  continue;
  72              }
  73  
  74              if ($interface !== $class && !is_subclass_of($class, $interface)) {
  75                  continue;
  76              }
  77  
  78              foreach ($instanceofDefs as $key => $instanceofDef) {
  79                  /** @var ChildDefinition $instanceofDef */
  80                  $instanceofDef = clone $instanceofDef;
  81                  $instanceofDef->setAbstract(true)->setParent($parent ?: 'abstract.instanceof.'.$id);
  82                  $parent = 'instanceof.'.$interface.'.'.$key.'.'.$id;
  83                  $container->setDefinition($parent, $instanceofDef);
  84                  $instanceofTags[] = $instanceofDef->getTags();
  85                  $instanceofDef->setTags([]);
  86  
  87                  if (isset($instanceofDef->getChanges()['shared'])) {
  88                      $shared = $instanceofDef->isShared();
  89                  }
  90              }
  91          }
  92  
  93          if ($parent) {
  94              $bindings = $definition->getBindings();
  95              $abstract = $container->setDefinition('abstract.instanceof.'.$id, $definition);
  96  
  97              // cast Definition to ChildDefinition
  98              $definition->setBindings([]);
  99              $definition = serialize($definition);
 100              $definition = substr_replace($definition, '53', 2, 2);
 101              $definition = substr_replace($definition, 'Child', 44, 0);
 102              $definition = unserialize($definition);
 103              $definition->setParent($parent);
 104  
 105              if (null !== $shared && !isset($definition->getChanges()['shared'])) {
 106                  $definition->setShared($shared);
 107              }
 108  
 109              $i = \count($instanceofTags);
 110              while (0 <= --$i) {
 111                  foreach ($instanceofTags[$i] as $k => $v) {
 112                      foreach ($v as $v) {
 113                          if ($definition->hasTag($k) && \in_array($v, $definition->getTag($k))) {
 114                              continue;
 115                          }
 116                          $definition->addTag($k, $v);
 117                      }
 118                  }
 119              }
 120  
 121              $definition->setBindings($bindings);
 122  
 123              // reset fields with "merge" behavior
 124              $abstract
 125                  ->setBindings([])
 126                  ->setArguments([])
 127                  ->setMethodCalls([])
 128                  ->setDecoratedService(null)
 129                  ->setTags([])
 130                  ->setAbstract(true);
 131          }
 132  
 133          return $definition;
 134      }
 135  
 136      private function mergeConditionals(array $autoconfiguredInstanceof, array $instanceofConditionals, ContainerBuilder $container)
 137      {
 138          // make each value an array of ChildDefinition
 139          $conditionals = array_map(function ($childDef) { return [$childDef]; }, $autoconfiguredInstanceof);
 140  
 141          foreach ($instanceofConditionals as $interface => $instanceofDef) {
 142              // make sure the interface/class exists (but don't validate automaticInstanceofConditionals)
 143              if (!$container->getReflectionClass($interface)) {
 144                  throw new RuntimeException(sprintf('"%s" is set as an "instanceof" conditional, but it does not exist.', $interface));
 145              }
 146  
 147              if (!isset($autoconfiguredInstanceof[$interface])) {
 148                  $conditionals[$interface] = [];
 149              }
 150  
 151              $conditionals[$interface][] = $instanceofDef;
 152          }
 153  
 154          return $conditionals;
 155      }
 156  }


Generated: Wed Dec 7 15:09:22 2022 Cross-referenced by PHPXref 0.7.1