diff --git a/src/Symfony/Component/Routing/Annotation/Routes.php b/src/Symfony/Component/Routing/Annotation/Routes.php new file mode 100644 index 000000000000..9d89276582c3 --- /dev/null +++ b/src/Symfony/Component/Routing/Annotation/Routes.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Annotation; + +/** + * Annotation class for @Routes(). + * + * @author Fabien Potencier + */ +class Routes +{ + protected $routes; + + /** + * Constructor. + * + * @param array $data An array of key/value parameters. + */ + public function __construct(array $data) + { + if (!isset($data['value']) || !is_array($data['value'])) { + throw new \LogicException('A @Routes annotation must have an array of @Route annotation as argument.'); + } + + $this->routes = $data['value']; + } + + public function setRoutes($routes) + { + $this->routes = $routes; + } + + public function getRoutes() + { + return $this->routes; + } +} diff --git a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php index 9ea4f02da046..ffeca17ec08e 100644 --- a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php +++ b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php @@ -58,7 +58,8 @@ abstract class AnnotationClassLoader implements LoaderInterface { protected $reader; - protected $annotationClass = 'Symfony\\Component\\Routing\\Annotation\\Route'; + protected $routeAnnotationClass = 'Symfony\\Component\\Routing\\Annotation\\Route'; + protected $routesAnnotationClass = 'Symfony\\Component\\Routing\\Annotation\\Routes'; /** * Constructor. @@ -73,11 +74,21 @@ public function __construct(AnnotationReader $reader) /** * Sets the annotation class to read route properties from. * - * @param string $annotationClass A fully-qualified class name + * @param string $class A fully-qualified class name */ - public function setAnnotationClass($annotationClass) + public function setRouteAnnotationClass($class) { - $this->annotationClass = $annotationClass; + $this->routeAnnotationClass = $class; + } + + /** + * Sets the annotation class to read routes properties from. + * + * @param string $class A fully-qualified class name + */ + public function setRoutesAnnotationClass($class) + { + $this->routesAnnotationClass = $class; } /** @@ -104,7 +115,7 @@ public function load($class, $type = null) ); $class = new \ReflectionClass($class); - if ($annot = $this->reader->getClassAnnotation($class, $this->annotationClass)) { + if ($annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) { if (null !== $annot->getPattern()) { $globals['pattern'] = $annot->getPattern(); } @@ -124,25 +135,35 @@ public function load($class, $type = null) $collection = new RouteCollection(); $collection->addResource(new FileResource($class->getFileName())); + foreach ($class->getMethods() as $method) { - if ($annot = $this->reader->getMethodAnnotation($method, $this->annotationClass)) { - if (null === $annot->getName()) { - $annot->setName($this->getDefaultRouteName($class, $method)); + if ($annots = $this->reader->getMethodAnnotation($method, $this->routesAnnotationClass)) { + foreach ($annots->getRoutes() as $annot) { + $this->addRoute($collection, $annot, $globals, $annot, $class, $method); } + } elseif ($annot = $this->reader->getMethodAnnotation($method, $this->routeAnnotationClass)) { + $this->addRoute($collection, $annot, $globals, $annot, $class, $method); + } + } - $defaults = array_merge($globals['defaults'], $annot->getDefaults()); - $requirements = array_merge($globals['requirements'], $annot->getRequirements()); - $options = array_merge($globals['options'], $annot->getOptions()); + return $collection; + } + + protected function addRoute(RouteCollection $collection, $annot, $globals, $annot, \ReflectionClass $class, \ReflectionMethod $method) + { + if (null === $annot->getName()) { + $annot->setName($this->getDefaultRouteName($class, $method)); + } - $route = new Route($globals['pattern'].$annot->getPattern(), $defaults, $requirements, $options); + $defaults = array_merge($globals['defaults'], $annot->getDefaults()); + $requirements = array_merge($globals['requirements'], $annot->getRequirements()); + $options = array_merge($globals['options'], $annot->getOptions()); - $this->configureRoute($route, $class, $method); + $route = new Route($globals['pattern'].$annot->getPattern(), $defaults, $requirements, $options); - $collection->add($annot->getName(), $route); - } - } + $this->configureRoute($route, $class, $method, $annot); - return $collection; + $collection->add($annot->getName(), $route); } /** @@ -189,5 +210,5 @@ protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMetho return strtolower(str_replace('\\', '_', $class->getName()).'_'.$method->getName()); } - abstract protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method); + abstract protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot); }