diff --git a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php index f6d44252157a1..7b958d5e4daa4 100644 --- a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php +++ b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php @@ -72,6 +72,11 @@ abstract class AnnotationClassLoader implements LoaderInterface */ protected $defaultRouteIndex = 0; + /** + * @var bool + */ + protected $routeWithPriority = false; + /** * Constructor. * @@ -92,6 +97,16 @@ public function setRouteAnnotationClass($class) $this->routeAnnotationClass = $class; } + /** + * Tells if one of the annotationed route has priority info + * + * @return bool + */ + public function hasRouteWithPriority() + { + return $this->routeWithPriority; + } + /** * Loads from annotations from a class. * @@ -104,6 +119,8 @@ public function setRouteAnnotationClass($class) */ public function load($class, $type = null) { + $hasPriority = false; + if (!class_exists($class)) { throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); } @@ -123,6 +140,9 @@ public function load($class, $type = null) foreach ($this->reader->getMethodAnnotations($method) as $annot) { if ($annot instanceof $this->routeAnnotationClass) { $this->addRoute($collection, $annot, $globals, $class, $method); + if (array_key_exists('priority',$annot->getOptions())) { + $this->routeWithPriority = true; + } } } } diff --git a/src/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php b/src/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php index abd68ed6c4fab..1e7adc685a688 100644 --- a/src/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php +++ b/src/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Routing\Loader; +use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Config\Resource\DirectoryResource; @@ -58,6 +59,15 @@ public function load($path, $type = null) } } + if ($this->loader->hasRouteWithPriority()) { + $collection->getIterator()->uasort(function(Route $a, Route $b) { + if ($a->getOption('priority') == $b->getOption('priority')) { + return 0; + } + return $a->getOption('priority') > $b->getOption('priority') ? 1 : -1; + }); + } + return $collection; } diff --git a/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php index 3b39a666edc26..be453e50684b1 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php @@ -91,6 +91,11 @@ public function getLoadTests() array('name' => 'route1', 'defaults' => array('arg2' => 'foo'), 'condition' => 'context.getMethod() == "GET"'), array('arg2' => 'defaultValue2', 'arg3' =>'defaultValue3') ), + array( + 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass', + array('name' => 'route_priority', 'options' => array('priority' => '10')), + array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3') + ), ); } @@ -120,9 +125,10 @@ public function testLoad($className, $routeDatas = array(), $methodArgs = array( $this->assertSame($routeDatas['path'], $route->getPath(), '->load preserves path annotation'); $this->assertSame($routeDatas['requirements'],$route->getRequirements(), '->load preserves requirements annotation'); - $this->assertCount(0, array_intersect($route->getOptions(), $routeDatas['options']), '->load preserves options annotation'); + $this->assertSame(count($routeDatas['options']), count(array_intersect($route->getOptions(), $routeDatas['options'])), '->load preserves options annotation'); $this->assertSame(array_replace($methodArgs, $routeDatas['defaults']), $route->getDefaults(), '->load preserves defaults annotation'); $this->assertEquals($routeDatas['condition'], $route->getCondition(), '->load preserves condition annotation'); + $this->assertSame(isset($routeDatas['options']['priority']), $this->loader->hasRouteWithPriority()); } public function testClassRouteLoad()