Commit 091240ea authored by Radosław Kowalewski's avatar Radosław Kowalewski Committed by Fabien Potencier

Use shared RouteCollection among nested routes and apply prefix to route path...

Use shared RouteCollection among nested routes and apply prefix to route path before generating unique route name

Fixes #1106
parent e9bd89bb
......@@ -42,6 +42,7 @@ class ControllerCollection
protected $defaultRoute;
protected $defaultController;
protected $prefix;
protected $routes;
public function __construct(Route $defaultRoute)
{
......@@ -51,6 +52,16 @@ class ControllerCollection
};
}
/**
* Use existing route collection to resolve conflicting autogenerated route names among mounted routes
*
* @param RouteCollection $routes
*/
public function shareRoutes(RouteCollection $routes)
{
$this->routes = $routes;
}
/**
* Mounts controllers under the given route prefix.
*
......@@ -59,6 +70,10 @@ class ControllerCollection
*/
public function mount($prefix, ControllerCollection $controllers)
{
if (!($this->routes instanceof RouteCollection)) {
$this->routes = new RouteCollection();
}
$controllers->shareRoutes($this->routes);
$controllers->prefix = $prefix;
$this->controllers[] = $controllers;
......@@ -188,12 +203,17 @@ class ControllerCollection
*/
public function flush($prefix = '')
{
$routes = new RouteCollection();
if ($prefix !== '') {
$prefix = '/'.trim(trim($prefix), '/');
}
$routes = $this->routes ?: new RouteCollection();
foreach ($this->controllers as $controller) {
if ($controller instanceof Controller) {
$controller->getRoute()->setPath($prefix.$controller->getRoute()->getPath());
if (!$name = $controller->getRouteName()) {
$name = $controller->generateRouteName($prefix);
$name = $controller->generateRouteName('');
while ($routes->get($name)) {
$name .= '_';
}
......@@ -202,12 +222,10 @@ class ControllerCollection
$routes->add($name, $controller->getRoute());
$controller->freeze();
} else {
$routes->addCollection($controller->flush($controller->prefix));
$routes->addCollection($controller->flush($prefix.$controller->prefix));
}
}
$routes->addPrefix($prefix);
$this->controllers = array();
return $routes;
......
......@@ -89,6 +89,41 @@ class ControllerCollectionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array('_a_a', '_a_a_'), array_keys($routes->all()));
}
public function testUniqueGeneratedRouteNamesAmongMounts()
{
$controllers = new ControllerCollection(new Route());
$controllers->mount('/root-a', $rootA = new ControllerCollection(new Route()));
$controllers->mount('/root_a', $rootB = new ControllerCollection(new Route()));
$rootA->match('/leaf', function () {});
$rootB->match('/leaf', function () {});
$routes = $controllers->flush();
$this->assertCount(2, $routes->all());
$this->assertEquals(array('_root_a_leaf', '_root_a_leaf_'), array_keys($routes->all()));
}
public function testUniqueGeneratedRouteNamesAmongNestedMounts()
{
$controllers = new ControllerCollection(new Route());
$controllers->mount('/root-a', $rootA = new ControllerCollection(new Route()));
$controllers->mount('/root_a', $rootB = new ControllerCollection(new Route()));
$rootA->mount('/tree', $treeA = new ControllerCollection(new Route()));
$rootB->mount('/tree', $treeB = new ControllerCollection(new Route()));
$treeA->match('/leaf', function () {});
$treeB->match('/leaf', function () {});
$routes = $controllers->flush();
$this->assertCount(2, $routes->all());
$this->assertEquals(array('_root_a_tree_leaf', '_root_a_tree_leaf_'), array_keys($routes->all()));
}
public function testAssert()
{
$controllers = new ControllerCollection(new Route());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment