Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

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

ServiceLocatorTagPass.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 4.63 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\Alias;
015  use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
016  use Symfony\Component\DependencyInjection\ContainerBuilder;
017  use Symfony\Component\DependencyInjection\Definition;
018  use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
019  use Symfony\Component\DependencyInjection\Reference;
020  use Symfony\Component\DependencyInjection\ServiceLocator;
021   
022  /**
023   * Applies the "container.service_locator" tag by wrapping references into ServiceClosureArgument instances.
024   *
025   * @author Nicolas Grekas <p@tchwork.com>
026   */
027  final class ServiceLocatorTagPass extends AbstractRecursivePass
028  {
029      protected function processValue($value, $isRoot = false)
030      {
031          if (!$value instanceof Definition || !$value->hasTag('container.service_locator')) {
032              return parent::processValue($value, $isRoot);
033          }
034   
035          if (!$value->getClass()) {
036              $value->setClass(ServiceLocator::class);
037          }
038   
039          $arguments = $value->getArguments();
040          if (!isset($arguments[0]) || !\is_array($arguments[0])) {
041              throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": an array of references is expected as first argument when the "container.service_locator" tag is set.', $this->currentId));
042          }
043   
044          $i = 0;
045   
046          foreach ($arguments[0] as $k => $v) {
047              if ($v instanceof ServiceClosureArgument) {
048                  continue;
049              }
050              if (!$v instanceof Reference) {
051                  throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": an array of references is expected as first argument when the "container.service_locator" tag is set, "%s" found for key "%s".', $this->currentId, \is_object($v) ? \get_class($v) : \gettype($v), $k));
052              }
053   
054              if ($i === $k) {
055                  unset($arguments[0][$k]);
056   
057                  $k = (string) $v;
058                  ++$i;
059              } elseif (\is_int($k)) {
060                  $i = null;
061              }
062              $arguments[0][$k] = new ServiceClosureArgument($v);
063          }
064          ksort($arguments[0]);
065   
066          $value->setArguments($arguments);
067   
068          $id = 'service_locator.'.ContainerBuilder::hash($value);
069   
070          if ($isRoot) {
071              if ($id !== $this->currentId) {
072                  $this->container->setAlias($id, new Alias($this->currentId, false));
073              }
074   
075              return $value;
076          }
077   
078          $this->container->setDefinition($id, $value->setPublic(false));
079   
080          return new Reference($id);
081      }
082   
083      /**
084       * @param Reference[] $refMap
085       * @param string|null $callerId
086       *
087       * @return Reference
088       */
089      public static function register(ContainerBuilder $container, array $refMap, $callerId = null)
090      {
091          foreach ($refMap as $id => $ref) {
092              if (!$ref instanceof Reference) {
093                  throw new InvalidArgumentException(sprintf('Invalid service locator definition: only services can be referenced, "%s" found for key "%s". Inject parameter values using constructors instead.', \is_object($ref) ? \get_class($ref) : \gettype($ref), $id));
094              }
095              $refMap[$id] = new ServiceClosureArgument($ref);
096          }
097          ksort($refMap);
098   
099          $locator = (new Definition(ServiceLocator::class))
100              ->addArgument($refMap)
101              ->setPublic(false)
102              ->addTag('container.service_locator');
103   
104          if (null !== $callerId && $container->hasDefinition($callerId)) {
105              $locator->setBindings($container->getDefinition($callerId)->getBindings());
106          }
107   
108          if (!$container->hasDefinition($id = 'service_locator.'.ContainerBuilder::hash($locator))) {
109              $container->setDefinition($id, $locator);
110          }
111   
112          if (null !== $callerId) {
113              $locatorId = $id;
114              // Locators are shared when they hold the exact same list of factories;
115              // to have them specialized per consumer service, we use a cloning factory
116              // to derivate customized instances from the prototype one.
117              $container->register($id .= '.'.$callerId, ServiceLocator::class)
118                  ->setPublic(false)
119                  ->setFactory([new Reference($locatorId), 'withContext'])
120                  ->addArgument($callerId)
121                  ->addArgument(new Reference('service_container'));
122          }
123   
124          return new Reference($id);
125      }
126  }
127