abstract class AnnotationClassLoader

AnnotationClassLoader loads routing information from a PHP class and its methods.

You need to define an implementation for the getRouteDefaults() method. Most of the time, this method should define some PHP callable to be called for the route (a controller in MVC speak).

The @Route annotation can be set on the class (for global parameters), and on each method.

The @Route annotation main value is the route path. The annotation also recognizes several parameters: requirements, options, defaults, schemes, methods, host, and name. The name parameter is mandatory. Here is an example of how you should be able to use it:

  • @Route("/Blog")
  • /

class Blog {

  • @Route("/", name="blog_index")
  • /

public function index() { }

  • @Route("/{id}", name="blog_post", requirements = {"id" = "\d+"})
  • /

public function show() { } }

@author Fabien Potencier <fabien@symfony.com>

Hierarchy

  • class \Symfony\Component\Routing\Loader\AnnotationClassLoader implements \Symfony\Component\Config\Loader\LoaderInterface

Expanded class hierarchy of AnnotationClassLoader

File

drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php, line 58

Namespace

Symfony\Component\Routing\Loader
View source
abstract class AnnotationClassLoader implements LoaderInterface {

  /**
   * @var Reader
   */
  protected $reader;

  /**
   * @var string
   */
  protected $routeAnnotationClass = 'Symfony\\Component\\Routing\\Annotation\\Route';

  /**
   * @var integer
   */
  protected $defaultRouteIndex = 0;

  /**
   * Constructor.
   *
   * @param Reader $reader
   */
  public function __construct(Reader $reader) {
    $this->reader = $reader;
  }

  /**
   * Sets the annotation class to read route properties from.
   *
   * @param string $class A fully-qualified class name
   */
  public function setRouteAnnotationClass($class) {
    $this->routeAnnotationClass = $class;
  }

  /**
   * Loads from annotations from a class.
   *
   * @param string      $class A class name
   * @param string|null $type  The resource type
   *
   * @return RouteCollection A RouteCollection instance
   *
   * @throws \InvalidArgumentException When route can't be parsed
   */
  public function load($class, $type = null) {
    if (!class_exists($class)) {
      throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
    }
    $globals = array(
      'path' => '',
      'requirements' => array(),
      'options' => array(),
      'defaults' => array(),
      'schemes' => array(),
      'methods' => array(),
      'host' => '',
    );
    $class = new \ReflectionClass($class);
    if ($class
      ->isAbstract()) {
      throw new \InvalidArgumentException(sprintf('Annotations from class "%s" cannot be read as it is abstract.', $class));
    }
    if ($annot = $this->reader
      ->getClassAnnotation($class, $this->routeAnnotationClass)) {

      // for BC reasons
      if (null !== $annot
        ->getPath()) {
        $globals['path'] = $annot
          ->getPath();
      }
      elseif (null !== $annot
        ->getPattern()) {
        $globals['path'] = $annot
          ->getPattern();
      }
      if (null !== $annot
        ->getRequirements()) {
        $globals['requirements'] = $annot
          ->getRequirements();
      }
      if (null !== $annot
        ->getOptions()) {
        $globals['options'] = $annot
          ->getOptions();
      }
      if (null !== $annot
        ->getDefaults()) {
        $globals['defaults'] = $annot
          ->getDefaults();
      }
      if (null !== $annot
        ->getSchemes()) {
        $globals['schemes'] = $annot
          ->getSchemes();
      }
      if (null !== $annot
        ->getMethods()) {
        $globals['methods'] = $annot
          ->getMethods();
      }
      if (null !== $annot
        ->getHost()) {
        $globals['host'] = $annot
          ->getHost();
      }
    }
    $collection = new RouteCollection();
    $collection
      ->addResource(new FileResource($class
      ->getFileName()));
    foreach ($class
      ->getMethods() as $method) {
      $this->defaultRouteIndex = 0;
      foreach ($this->reader
        ->getMethodAnnotations($method) as $annot) {
        if ($annot instanceof $this->routeAnnotationClass) {
          $this
            ->addRoute($collection, $annot, $globals, $class, $method);
        }
      }
    }
    return $collection;
  }
  protected function addRoute(RouteCollection $collection, $annot, $globals, \ReflectionClass $class, \ReflectionMethod $method) {
    $name = $annot
      ->getName();
    if (null === $name) {
      $name = $this
        ->getDefaultRouteName($class, $method);
    }
    $defaults = array_replace($globals['defaults'], $annot
      ->getDefaults());
    foreach ($method
      ->getParameters() as $param) {
      if ($param
        ->isOptional()) {
        $defaults[$param
          ->getName()] = $param
          ->getDefaultValue();
      }
    }
    $requirements = array_replace($globals['requirements'], $annot
      ->getRequirements());
    $options = array_replace($globals['options'], $annot
      ->getOptions());
    $schemes = array_replace($globals['schemes'], $annot
      ->getSchemes());
    $methods = array_replace($globals['methods'], $annot
      ->getMethods());
    $host = $annot
      ->getHost();
    if (null === $host) {
      $host = $globals['host'];
    }
    $route = new Route($globals['path'] . $annot
      ->getPath(), $defaults, $requirements, $options, $host, $schemes, $methods);
    $this
      ->configureRoute($route, $class, $method, $annot);
    $collection
      ->add($name, $route);
  }

  /**
   * {@inheritdoc}
   */
  public function supports($resource, $type = null) {
    return is_string($resource) && preg_match('/^(?:\\\\?[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)+$/', $resource) && (!$type || 'annotation' === $type);
  }

  /**
   * {@inheritdoc}
   */
  public function setResolver(LoaderResolverInterface $resolver) {
  }

  /**
   * {@inheritdoc}
   */
  public function getResolver() {
  }

  /**
   * Gets the default route name for a class method.
   *
   * @param \ReflectionClass  $class
   * @param \ReflectionMethod $method
   *
   * @return string
   */
  protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method) {
    $name = strtolower(str_replace('\\', '_', $class->name) . '_' . $method->name);
    if ($this->defaultRouteIndex > 0) {
      $name .= '_' . $this->defaultRouteIndex;
    }
    $this->defaultRouteIndex++;
    return $name;
  }
  protected abstract function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot);

}

Members

Namesort descending Modifiers Type Description Overrides
AnnotationClassLoader::$defaultRouteIndex protected property
AnnotationClassLoader::$reader protected property
AnnotationClassLoader::$routeAnnotationClass protected property
AnnotationClassLoader::addRoute protected function
AnnotationClassLoader::configureRoute abstract protected function
AnnotationClassLoader::getDefaultRouteName protected function Gets the default route name for a class method.
AnnotationClassLoader::getResolver public function
AnnotationClassLoader::load public function Loads from annotations from a class.
AnnotationClassLoader::setResolver public function
AnnotationClassLoader::setRouteAnnotationClass public function Sets the annotation class to read route properties from.
AnnotationClassLoader::supports public function
AnnotationClassLoader::__construct public function Constructor.