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

AnnotationClassLoader.php

Zuletzt modifiziert: 02.04.2025, 15:03 - 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