<?php
namespace Symfony\Component\Routing\Loader;
use Doctrine\Common\Annotations\Reader;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\Config\Loader\LoaderResolverInterface;
abstract class AnnotationClassLoader implements LoaderInterface {
protected $reader;
protected $routeAnnotationClass = 'Symfony\\Component\\Routing\\Annotation\\Route';
protected $defaultRouteIndex = 0;
public function __construct(Reader $reader) {
$this->reader = $reader;
}
public function setRouteAnnotationClass($class) {
$this->routeAnnotationClass = $class;
}
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)) {
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);
}
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);
}
public function setResolver(LoaderResolverInterface $resolver) {
}
public function getResolver() {
}
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);
}