[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/symfony/routing/Loader/ -> AnnotationFileLoader.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\Routing\Loader;
  13  
  14  use Symfony\Component\Config\FileLocatorInterface;
  15  use Symfony\Component\Config\Loader\FileLoader;
  16  use Symfony\Component\Config\Resource\FileResource;
  17  use Symfony\Component\Routing\RouteCollection;
  18  
  19  /**
  20   * AnnotationFileLoader loads routing information from annotations set
  21   * on a PHP class and its methods.
  22   *
  23   * @author Fabien Potencier <fabien@symfony.com>
  24   */
  25  class AnnotationFileLoader extends FileLoader
  26  {
  27      protected $loader;
  28  
  29      /**
  30       * @throws \RuntimeException
  31       */
  32      public function __construct(FileLocatorInterface $locator, AnnotationClassLoader $loader)
  33      {
  34          if (!\function_exists('token_get_all')) {
  35              throw new \RuntimeException('The Tokenizer extension is required for the routing annotation loaders.');
  36          }
  37  
  38          parent::__construct($locator);
  39  
  40          $this->loader = $loader;
  41      }
  42  
  43      /**
  44       * Loads from annotations from a file.
  45       *
  46       * @param string      $file A PHP file path
  47       * @param string|null $type The resource type
  48       *
  49       * @return RouteCollection|null A RouteCollection instance
  50       *
  51       * @throws \InvalidArgumentException When the file does not exist or its routes cannot be parsed
  52       */
  53      public function load($file, $type = null)
  54      {
  55          $path = $this->locator->locate($file);
  56  
  57          $collection = new RouteCollection();
  58          if ($class = $this->findClass($path)) {
  59              $refl = new \ReflectionClass($class);
  60              if ($refl->isAbstract()) {
  61                  return null;
  62              }
  63  
  64              $collection->addResource(new FileResource($path));
  65              $collection->addCollection($this->loader->load($class, $type));
  66          }
  67          if (\PHP_VERSION_ID >= 70000) {
  68              // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
  69              gc_mem_caches();
  70          }
  71  
  72          return $collection;
  73      }
  74  
  75      /**
  76       * {@inheritdoc}
  77       */
  78      public function supports($resource, $type = null)
  79      {
  80          return \is_string($resource) && 'php' === pathinfo($resource, \PATHINFO_EXTENSION) && (!$type || 'annotation' === $type);
  81      }
  82  
  83      /**
  84       * Returns the full class name for the first class in the file.
  85       *
  86       * @param string $file A PHP file path
  87       *
  88       * @return string|false Full class name if found, false otherwise
  89       */
  90      protected function findClass($file)
  91      {
  92          $class = false;
  93          $namespace = false;
  94          $tokens = token_get_all(file_get_contents($file));
  95  
  96          if (1 === \count($tokens) && \T_INLINE_HTML === $tokens[0][0]) {
  97              throw new \InvalidArgumentException(sprintf('The file "%s" does not contain PHP code. Did you forgot to add the "<?php" start tag at the beginning of the file?', $file));
  98          }
  99  
 100          $nsTokens = [\T_NS_SEPARATOR => true, \T_STRING => true];
 101          if (\defined('T_NAME_QUALIFIED')) {
 102              $nsTokens[T_NAME_QUALIFIED] = true;
 103          }
 104  
 105          for ($i = 0; isset($tokens[$i]); ++$i) {
 106              $token = $tokens[$i];
 107  
 108              if (!isset($token[1])) {
 109                  continue;
 110              }
 111  
 112              if (true === $class && \T_STRING === $token[0]) {
 113                  return $namespace.'\\'.$token[1];
 114              }
 115  
 116              if (true === $namespace && isset($nsTokens[$token[0]])) {
 117                  $namespace = $token[1];
 118                  while (isset($tokens[++$i][1], $nsTokens[$tokens[$i][0]])) {
 119                      $namespace .= $tokens[$i][1];
 120                  }
 121                  $token = $tokens[$i];
 122              }
 123  
 124              if (\T_CLASS === $token[0]) {
 125                  // Skip usage of ::class constant and anonymous classes
 126                  $skipClassToken = false;
 127                  for ($j = $i - 1; $j > 0; --$j) {
 128                      if (!isset($tokens[$j][1])) {
 129                          break;
 130                      }
 131  
 132                      if (\T_DOUBLE_COLON === $tokens[$j][0] || \T_NEW === $tokens[$j][0]) {
 133                          $skipClassToken = true;
 134                          break;
 135                      } elseif (!\in_array($tokens[$j][0], [\T_WHITESPACE, \T_DOC_COMMENT, \T_COMMENT])) {
 136                          break;
 137                      }
 138                  }
 139  
 140                  if (!$skipClassToken) {
 141                      $class = true;
 142                  }
 143              }
 144  
 145              if (\T_NAMESPACE === $token[0]) {
 146                  $namespace = true;
 147              }
 148          }
 149  
 150          return false;
 151      }
 152  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1