Verzeichnisstruktur phpBB-3.3.16


Veröffentlicht
27.04.2026

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

AnnotationClassLoader.php

Zuletzt modifiziert: 01.05.2026, 11:27 - Dateigröße: 8.71 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\Routing\Loader;
 013   
 014  use Doctrine\Common\Annotations\Reader;
 015  use Symfony\Component\Config\Loader\LoaderInterface;
 016  use Symfony\Component\Config\Loader\LoaderResolverInterface;
 017  use Symfony\Component\Config\Resource\FileResource;
 018  use Symfony\Component\Routing\Annotation\Route as RouteAnnotation;
 019  use Symfony\Component\Routing\Route;
 020  use Symfony\Component\Routing\RouteCollection;
 021   
 022  /**
 023   * AnnotationClassLoader loads routing information from a PHP class and its methods.
 024   *
 025   * You need to define an implementation for the configureRoute() method. Most of the
 026   * time, this method should define some PHP callable to be called for the route
 027   * (a controller in MVC speak).
 028   *
 029   * The @Route annotation can be set on the class (for global parameters),
 030   * and on each method.
 031   *
 032   * The @Route annotation main value is the route path. The annotation also
 033   * recognizes several parameters: requirements, options, defaults, schemes,
 034   * methods, host, and name. The name parameter is mandatory.
 035   * Here is an example of how you should be able to use it:
 036   *     /**
 037   *      * @Route("/Blog")
 038   *      * /
 039   *     class Blog
 040   *     {
 041   *         /**
 042   *          * @Route("/", name="blog_index")
 043   *          * /
 044   *         public function index()
 045   *         {
 046   *         }
 047   *         /**
 048   *          * @Route("/{id}", name="blog_post", requirements = {"id" = "\d+"})
 049   *          * /
 050   *         public function show()
 051   *         {
 052   *         }
 053   *     }
 054   *
 055   * @author Fabien Potencier <fabien@symfony.com>
 056   */
 057  abstract class AnnotationClassLoader implements LoaderInterface
 058  {
 059      protected $reader;
 060   
 061      /**
 062       * @var string
 063       */
 064      protected $routeAnnotationClass = 'Symfony\\Component\\Routing\\Annotation\\Route';
 065   
 066      /**
 067       * @var int
 068       */
 069      protected $defaultRouteIndex = 0;
 070   
 071      public function __construct(Reader $reader)
 072      {
 073          $this->reader = $reader;
 074      }
 075   
 076      /**
 077       * Sets the annotation class to read route properties from.
 078       *
 079       * @param string $class A fully-qualified class name
 080       */
 081      public function setRouteAnnotationClass($class)
 082      {
 083          $this->routeAnnotationClass = $class;
 084      }
 085   
 086      /**
 087       * Loads from annotations from a class.
 088       *
 089       * @param string      $class A class name
 090       * @param string|null $type  The resource type
 091       *
 092       * @return RouteCollection A RouteCollection instance
 093       *
 094       * @throws \InvalidArgumentException When route can't be parsed
 095       */
 096      public function load($class, $type = null)
 097      {
 098          if (!class_exists($class)) {
 099              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  }
 279