[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/symfony/service-contracts/ -> ServiceLocatorTrait.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of the Symfony package.
   5   *
   6   * (c) Fabien Potencier <[email protected]>
   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\Contracts\Service;
  13  
  14  use Psr\Container\ContainerExceptionInterface;
  15  use Psr\Container\NotFoundExceptionInterface;
  16  
  17  // Help opcache.preload discover always-needed symbols
  18  class_exists(ContainerExceptionInterface::class);
  19  class_exists(NotFoundExceptionInterface::class);
  20  
  21  /**
  22   * A trait to help implement ServiceProviderInterface.
  23   *
  24   * @author Robin Chalas <[email protected]>
  25   * @author Nicolas Grekas <[email protected]>
  26   */
  27  trait ServiceLocatorTrait
  28  {
  29      private $factories;
  30      private $loading = [];
  31      private $providedTypes;
  32  
  33      /**
  34       * @param callable[] $factories
  35       */
  36      public function __construct(array $factories)
  37      {
  38          $this->factories = $factories;
  39      }
  40  
  41      /**
  42       * {@inheritdoc}
  43       *
  44       * @return bool
  45       */
  46      public function has(string $id)
  47      {
  48          return isset($this->factories[$id]);
  49      }
  50  
  51      /**
  52       * {@inheritdoc}
  53       *
  54       * @return mixed
  55       */
  56      public function get(string $id)
  57      {
  58          if (!isset($this->factories[$id])) {
  59              throw $this->createNotFoundException($id);
  60          }
  61  
  62          if (isset($this->loading[$id])) {
  63              $ids = array_values($this->loading);
  64              $ids = \array_slice($this->loading, array_search($id, $ids));
  65              $ids[] = $id;
  66  
  67              throw $this->createCircularReferenceException($id, $ids);
  68          }
  69  
  70          $this->loading[$id] = $id;
  71          try {
  72              return $this->factories[$id]($this);
  73          } finally {
  74              unset($this->loading[$id]);
  75          }
  76      }
  77  
  78      /**
  79       * {@inheritdoc}
  80       */
  81      public function getProvidedServices(): array
  82      {
  83          if (null === $this->providedTypes) {
  84              $this->providedTypes = [];
  85  
  86              foreach ($this->factories as $name => $factory) {
  87                  if (!\is_callable($factory)) {
  88                      $this->providedTypes[$name] = '?';
  89                  } else {
  90                      $type = (new \ReflectionFunction($factory))->getReturnType();
  91  
  92                      $this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '').($type instanceof \ReflectionNamedType ? $type->getName() : $type) : '?';
  93                  }
  94              }
  95          }
  96  
  97          return $this->providedTypes;
  98      }
  99  
 100      private function createNotFoundException(string $id): NotFoundExceptionInterface
 101      {
 102          if (!$alternatives = array_keys($this->factories)) {
 103              $message = 'is empty...';
 104          } else {
 105              $last = array_pop($alternatives);
 106              if ($alternatives) {
 107                  $message = sprintf('only knows about the "%s" and "%s" services.', implode('", "', $alternatives), $last);
 108              } else {
 109                  $message = sprintf('only knows about the "%s" service.', $last);
 110              }
 111          }
 112  
 113          if ($this->loading) {
 114              $message = sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $message);
 115          } else {
 116              $message = sprintf('Service "%s" not found: the current service locator %s', $id, $message);
 117          }
 118  
 119          return new class($message) extends \InvalidArgumentException implements NotFoundExceptionInterface {
 120          };
 121      }
 122  
 123      private function createCircularReferenceException(string $id, array $path): ContainerExceptionInterface
 124      {
 125          return new class(sprintf('Circular reference detected for service "%s", path: "%s".', $id, implode(' -> ', $path))) extends \RuntimeException implements ContainerExceptionInterface {
 126          };
 127      }
 128  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer