[ Index ]

PHP Cross Reference of phpBB-3.3.5-deutsch

title

Body

[close]

/vendor/symfony/routing/Loader/ -> AnnotationClassLoader.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 Doctrine\Common\Annotations\Reader;
  15  use Symfony\Component\Config\Loader\LoaderInterface;
  16  use Symfony\Component\Config\Loader\LoaderResolverInterface;
  17  use Symfony\Component\Config\Resource\FileResource;
  18  use Symfony\Component\Routing\Annotation\Route as RouteAnnotation;
  19  use Symfony\Component\Routing\Route;
  20  use Symfony\Component\Routing\RouteCollection;
  21  
  22  /**
  23   * AnnotationClassLoader loads routing information from a PHP class and its methods.
  24   *
  25   * You need to define an implementation for the configureRoute() method. Most of the
  26   * time, this method should define some PHP callable to be called for the route
  27   * (a controller in MVC speak).
  28   *
  29   * The @Route annotation can be set on the class (for global parameters),
  30   * and on each method.
  31   *
  32   * The @Route annotation main value is the route path. The annotation also
  33   * recognizes several parameters: requirements, options, defaults, schemes,
  34   * methods, host, and name. The name parameter is mandatory.
  35   * Here is an example of how you should be able to use it:
  36   *     /**
  37   *      * @Route("/Blog")
  38   *      * /
  39   *     class Blog
  40   *     {
  41   *         /**
  42   *          * @Route("/", name="blog_index")
  43   *          * /
  44   *         public function index()
  45   *         {
  46   *         }
  47   *         /**
  48   *          * @Route("/{id}", name="blog_post", requirements = {"id" = "\d+"})
  49   *          * /
  50   *         public function show()
  51   *         {
  52   *         }
  53   *     }
  54   *
  55   * @author Fabien Potencier <fabien@symfony.com>
  56   */
  57  abstract class AnnotationClassLoader implements LoaderInterface
  58  {
  59      protected $reader;
  60  
  61      /**
  62       * @var string
  63       */
  64      protected $routeAnnotationClass = 'Symfony\\Component\\Routing\\Annotation\\Route';
  65  
  66      /**
  67       * @var int
  68       */
  69      protected $defaultRouteIndex = 0;
  70  
  71      public function __construct(Reader $reader)
  72      {
  73          $this->reader = $reader;
  74      }
  75  
  76      /**
  77       * Sets the annotation class to read route properties from.
  78       *
  79       * @param string $class A fully-qualified class name
  80       */
  81      public function setRouteAnnotationClass($class)
  82      {
  83          $this->routeAnnotationClass = $class;
  84      }
  85  
  86      /**
  87       * Loads from annotations from a class.
  88       *
  89       * @param string      $class A class name
  90       * @param string|null $type  The resource type
  91       *
  92       * @return RouteCollection A RouteCollection instance
  93       *
  94       * @throws \InvalidArgumentException When route can't be parsed
  95       */
  96      public function load($class, $type = null)
  97      {
  98          if (!class_exists($class)) {
  99              throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
 100          }
 101  
 102          $class = new \ReflectionClass($class);
 103          if ($class->isAbstract()) {
 104              throw new \InvalidArgumentException(sprintf('Annotations from class "%s" cannot be read as it is abstract.', $class->getName()));
 105          }
 106  
 107          $globals = $this->getGlobals($class);
 108  
 109          $collection = new RouteCollection();
 110          $collection->addResource(new FileResource($class->getFileName()));
 111  
 112          foreach ($class->getMethods() as $method) {
 113              $this->defaultRouteIndex = 0;
 114              foreach ($this->reader->getMethodAnnotations($method) as $annot) {
 115                  if ($annot instanceof $this->routeAnnotationClass) {
 116                      $this->addRoute($collection, $annot, $globals, $class, $method);
 117                  }
 118              }
 119          }
 120  
 121          if (0 === $collection->count() && $class->hasMethod('__invoke')) {
 122              $globals = $this->resetGlobals();
 123              foreach ($this->reader->getClassAnnotations($class) as $annot) {
 124                  if ($annot instanceof $this->routeAnnotationClass) {
 125                      $this->addRoute($collection, $annot, $globals, $class, $class->getMethod('__invoke'));
 126                  }
 127              }
 128          }
 129  
 130          return $collection;
 131      }
 132  
 133      /**
 134       * @param RouteAnnotation $annot   or an object that exposes a similar interface
 135       * @param array           $globals
 136       */
 137      protected function addRoute(RouteCollection $collection, $annot, $globals, \ReflectionClass $class, \ReflectionMethod $method)
 138      {
 139          $name = $annot->getName();
 140          if (null === $name) {
 141              $name = $this->getDefaultRouteName($class, $method);
 142          }
 143          $name = $globals['name'].$name;
 144  
 145          $defaults = array_replace($globals['defaults'], $annot->getDefaults());
 146          foreach ($method->getParameters() as $param) {
 147              if (false !== strpos($globals['path'].$annot->getPath(), sprintf('{%s}', $param->getName())) && !isset($defaults[$param->getName()]) && $param->isDefaultValueAvailable()) {
 148                  $defaults[$param->getName()] = $param->getDefaultValue();
 149              }
 150          }
 151          $requirements = array_replace($globals['requirements'], $annot->getRequirements());
 152          $options = array_replace($globals['options'], $annot->getOptions());
 153          $schemes = array_merge($globals['schemes'], $annot->getSchemes());
 154          $methods = array_merge($globals['methods'], $annot->getMethods());
 155  
 156          $host = $annot->getHost();
 157          if (null === $host) {
 158              $host = $globals['host'];
 159          }
 160  
 161          $condition = $annot->getCondition();
 162          if (null === $condition) {
 163              $condition = $globals['condition'];
 164          }
 165  
 166          $route = $this->createRoute($globals['path'].$annot->getPath(), $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
 167  
 168          $this->configureRoute($route, $class, $method, $annot);
 169  
 170          $collection->add($name, $route);
 171      }
 172  
 173      /**
 174       * {@inheritdoc}
 175       */
 176      public function supports($resource, $type = null)
 177      {
 178          return \is_string($resource) && preg_match('/^(?:\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)+$/', $resource) && (!$type || 'annotation' === $type);
 179      }
 180  
 181      /**
 182       * {@inheritdoc}
 183       */
 184      public function setResolver(LoaderResolverInterface $resolver)
 185      {
 186      }
 187  
 188      /**
 189       * {@inheritdoc}
 190       */
 191      public function getResolver()
 192      {
 193      }
 194  
 195      /**
 196       * Gets the default route name for a class method.
 197       *
 198       * @return string
 199       */
 200      protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method)
 201      {
 202          $name = str_replace('\\', '_', $class->name).'_'.$method->name;
 203          $name = \function_exists('mb_strtolower') && preg_match('//u', $name) ? mb_strtolower($name, 'UTF-8') : strtolower($name);
 204          if ($this->defaultRouteIndex > 0) {
 205              $name .= '_'.$this->defaultRouteIndex;
 206          }
 207          ++$this->defaultRouteIndex;
 208  
 209          return $name;
 210      }
 211  
 212      protected function getGlobals(\ReflectionClass $class)
 213      {
 214          $globals = $this->resetGlobals();
 215  
 216          if ($annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) {
 217              if (null !== $annot->getName()) {
 218                  $globals['name'] = $annot->getName();
 219              }
 220  
 221              if (null !== $annot->getPath()) {
 222                  $globals['path'] = $annot->getPath();
 223              }
 224  
 225              if (null !== $annot->getRequirements()) {
 226                  $globals['requirements'] = $annot->getRequirements();
 227              }
 228  
 229              if (null !== $annot->getOptions()) {
 230                  $globals['options'] = $annot->getOptions();
 231              }
 232  
 233              if (null !== $annot->getDefaults()) {
 234                  $globals['defaults'] = $annot->getDefaults();
 235              }
 236  
 237              if (null !== $annot->getSchemes()) {
 238                  $globals['schemes'] = $annot->getSchemes();
 239              }
 240  
 241              if (null !== $annot->getMethods()) {
 242                  $globals['methods'] = $annot->getMethods();
 243              }
 244  
 245              if (null !== $annot->getHost()) {
 246                  $globals['host'] = $annot->getHost();
 247              }
 248  
 249              if (null !== $annot->getCondition()) {
 250                  $globals['condition'] = $annot->getCondition();
 251              }
 252          }
 253  
 254          return $globals;
 255      }
 256  
 257      private function resetGlobals()
 258      {
 259          return [
 260              'path' => '',
 261              'requirements' => [],
 262              'options' => [],
 263              'defaults' => [],
 264              'schemes' => [],
 265              'methods' => [],
 266              'host' => '',
 267              'condition' => '',
 268              'name' => '',
 269          ];
 270      }
 271  
 272      protected function createRoute($path, $defaults, $requirements, $options, $host, $schemes, $methods, $condition)
 273      {
 274          return new Route($path, $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
 275      }
 276  
 277      abstract protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot);
 278  }


Generated: Mon Oct 4 17:42:11 2021 Cross-referenced by PHPXref 0.7.1