[ Index ]

PHP Cross Reference of phpBB-3.3.7-deutsch

title

Body

[close]

/vendor/symfony/dependency-injection/Compiler/ -> RegisterServiceSubscribersPass.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\ContainerInterface;
  15  use Symfony\Component\DependencyInjection\Definition;
  16  use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
  17  use Symfony\Component\DependencyInjection\Reference;
  18  use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
  19  use Symfony\Component\DependencyInjection\TypedReference;
  20  
  21  /**
  22   * Compiler pass to register tagged services that require a service locator.
  23   *
  24   * @author Nicolas Grekas <p@tchwork.com>
  25   */
  26  class RegisterServiceSubscribersPass extends AbstractRecursivePass
  27  {
  28      protected function processValue($value, $isRoot = false)
  29      {
  30          if (!$value instanceof Definition || $value->isAbstract() || $value->isSynthetic() || !$value->hasTag('container.service_subscriber')) {
  31              return parent::processValue($value, $isRoot);
  32          }
  33  
  34          $serviceMap = [];
  35          $autowire = $value->isAutowired();
  36  
  37          foreach ($value->getTag('container.service_subscriber') as $attributes) {
  38              if (!$attributes) {
  39                  $autowire = true;
  40                  continue;
  41              }
  42              ksort($attributes);
  43              if ([] !== array_diff(array_keys($attributes), ['id', 'key'])) {
  44                  throw new InvalidArgumentException(sprintf('The "container.service_subscriber" tag accepts only the "key" and "id" attributes, "%s" given for service "%s".', implode('", "', array_keys($attributes)), $this->currentId));
  45              }
  46              if (!\array_key_exists('id', $attributes)) {
  47                  throw new InvalidArgumentException(sprintf('Missing "id" attribute on "container.service_subscriber" tag with key="%s" for service "%s".', $attributes['key'], $this->currentId));
  48              }
  49              if (!\array_key_exists('key', $attributes)) {
  50                  $attributes['key'] = $attributes['id'];
  51              }
  52              if (isset($serviceMap[$attributes['key']])) {
  53                  continue;
  54              }
  55              $serviceMap[$attributes['key']] = new Reference($attributes['id']);
  56          }
  57          $class = $value->getClass();
  58  
  59          if (!$r = $this->container->getReflectionClass($class)) {
  60              throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $this->currentId));
  61          }
  62          if (!$r->isSubclassOf(ServiceSubscriberInterface::class)) {
  63              throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $this->currentId, ServiceSubscriberInterface::class));
  64          }
  65          $class = $r->name;
  66  
  67          $subscriberMap = [];
  68          $declaringClass = (new \ReflectionMethod($class, 'getSubscribedServices'))->class;
  69  
  70          foreach ($class::getSubscribedServices() as $key => $type) {
  71              if (!\is_string($type) || !preg_match('/^\??[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+$/', $type)) {
  72                  throw new InvalidArgumentException(sprintf('"%s::getSubscribedServices()" must return valid PHP types for service "%s" key "%s", "%s" returned.', $class, $this->currentId, $key, \is_string($type) ? $type : \gettype($type)));
  73              }
  74              if ($optionalBehavior = '?' === $type[0]) {
  75                  $type = substr($type, 1);
  76                  $optionalBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
  77              }
  78              if (\is_int($key)) {
  79                  $key = $type;
  80              }
  81              if (!isset($serviceMap[$key])) {
  82                  if (!$autowire) {
  83                      throw new InvalidArgumentException(sprintf('Service "%s" misses a "container.service_subscriber" tag with "key"/"id" attributes corresponding to entry "%s" as returned by "%s::getSubscribedServices()".', $this->currentId, $key, $class));
  84                  }
  85                  $serviceMap[$key] = new Reference($type);
  86              }
  87  
  88              $subscriberMap[$key] = new TypedReference($this->container->normalizeId($serviceMap[$key]), $type, $declaringClass, $optionalBehavior ?: ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE);
  89              unset($serviceMap[$key]);
  90          }
  91  
  92          if ($serviceMap = array_keys($serviceMap)) {
  93              $message = sprintf(1 < \count($serviceMap) ? 'keys "%s" do' : 'key "%s" does', str_replace('%', '%%', implode('", "', $serviceMap)));
  94              throw new InvalidArgumentException(sprintf('Service %s not exist in the map returned by "%s::getSubscribedServices()" for service "%s".', $message, $class, $this->currentId));
  95          }
  96  
  97          $value->addTag('container.service_subscriber.locator', ['id' => (string) ServiceLocatorTagPass::register($this->container, $subscriberMap, $this->currentId)]);
  98  
  99          return parent::processValue($value);
 100      }
 101  }


Generated: Thu Mar 24 21:31:15 2022 Cross-referenced by PHPXref 0.7.1