8000 [Routing] Add support for 'priority' option for annotated Routes by ghostika · Pull Request #11753 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Routing] Add support for 'priority' option for annotated Routes #11753

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
add support for routes with negative priority value
  • Loading branch information
Andras Ratz committed Aug 26, 2014
commit 992e38627d59b9e36d4c9134025a244a5471baf6
27 changes: 7 additions & 20 deletions src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,6 @@ public function setRouteAnnotationClass($class)
$this->routeAnnotationClass = $class;
}

public function hasRoutesWithPriority()
{
return !empty($this->routesWithPriority);
}

/**
* Loads from annotations from a class.
*
Expand Down Expand Up @@ -132,40 +127,32 @@ public function load($class, $type = null)
$this->defaultRouteIndex = 0;
foreach ($this->reader->getMethodAnnotations($method) as $annot) {
if ($annot instanceof $this->routeAnnotationClass) {
if ($annot->getOption('priority')) {
//These routes will be added to the collection later in File or Directory Loader
$this->routesWithPriority[$annot->getOption('priority')][]
= array($annot, $globals, $class, $method);
continue;
}
$this->addRoute($collection, $annot, $globals, $class, $method);
$priority = (int) $annot->getOption('priority');
$this->routesWithPriority[$priority][] = array($annot, $globals, $class, $method);
}
}
}

$collection = $this->addPriorityRoutes($collection);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you must reset the state of the loader here

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked for a way for that, but at the moment RouteCollection don't have such function, and if it's called in a directoryLoader, the named route will be removed and always appended to the end of the array, here in priority order. Or what do you mean by reseting?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$routesWithPriority is making the loader stateful. This means that if you import the routes from several classes explicitly, the second import will still see the priority routes of the first import, potentially creating weird issues

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see what you mean. The original goal was that if you import the routes for the Controller directory, you can set up priority between the files.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see my comment in the main discussion. This "feature" makes it very easy to break lots of things

return $collection;
}

/**
* Create a new collection of routes with priority
* These routes will be already sorted by priority
* and after that append all the other routes which
* don't have any priority
* Add the prioritised routes to the collection
*
* @param $originalCollection
* @param $collection
* @return RouteCollection
*/
public function addPriorityRoutes($originalCollection)
public function addPriorityRoutes($collection)
{
krsort($this->routesWithPriority);
$collection = new RouteCollection();

foreach ($this->routesWithPriority as $priorityGroup) {
foreach ($priorityGroup as $route) {
$this->addRoute($collection, $route[0], $route[1], $route[2], $route[3]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, here I had 2 option, one is when there is a priority key, I say continue, and I will not add the route initially there, and only here, but with this, if I add it again, routeCollection will remove the first addition and add the new one to the end of the list.

}
}
$collection->addCollection($originalCollection);

return $collection;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ public function load($path, $type = null)
}
}

if ($this->loader->hasRoutesWithPriority()) {
$collection = $this->loader->addPriorityRoutes($collection);
}
$collection = $this->loader->addPriorityRoutes($collection);

return $collection;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@ public function load($file, $type = null)
$collection->addCollection($this->loader->load($class, $type));
}

if ($this->loader->hasRoutesWithPriority()) {
$collection = $this->loader->addPriorityRoutes($collection);
}
$collection = $this->loader->addPriorityRoutes($collection);

return $collection;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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' => 'route1', 'options' => array('priority' => 10)),
array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
),
);
}

Expand Down Expand Up @@ -121,7 +126,6 @@ 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->assertSame(count($routeDatas['options']), count(array_intersect($route->getOptions(), $routeDatas['options'])), '->load preserves options annotation');
$this->assertEquals(array_key_exists('priority', $routeDatas['options']), $this->loader->hasRoutesWithPriority());
$this->assertSame(array_replace($methodArgs, $routeDa 9E88 tas['defaults']), $route->getDefaults(), '->load preserves defaults annotation');
$this->assertEquals($routeDatas['condition'], $route->getCondition(), '->load preserves condition annotation');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public function testRoutesWithPriority()
{
$routeDatas = array(
'foo' => new Route(array('name' => 'foo', 'path' => '/foo')),
'unimportant' => new Route(array('name' => 'unimportant', 'path' => '/unimportant', 'options' => array('priority' => -10))),
'bar' => new Route(array('name' => 'bar', 'path' => '/bar')),
'static_id' => new Route(array('name' => 'static_id', 'path' => '/static/{id}', 'options' => array('priority' => 1))),
'home' => new Route(array('name' => 'home', 'path' => '/home')),
Expand All @@ -70,7 +71,7 @@ public function testRoutesWithPriority()
->will($this->returnValue($routeDatas));

$routeCollection = $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses');
$expectedOrder = array( 'static_contact', 'static_location', 'static_id', 'foo', 'bar', 'home', 'login');
$expectedOrder = array( 'static_contact', 'static_location', 'static_id', 'foo', 'bar', 'home', 'login', 'unimportant');
$this->assertEquals($expectedOrder, array_keys($routeCollection->all()));
}
}
0