Skip to content
This repository has been archived by the owner on Jul 4, 2018. It is now read-only.

Commit

Permalink
Use shared RouteCollection among nested routes and apply prefix to ro…
Browse files Browse the repository at this point in the history
…ute path before generating unique route name

Fixes #1106
  • Loading branch information
srsbiz authored and fabpot committed Aug 3, 2015
1 parent e9bd89b commit 091240e
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 5 deletions.
28 changes: 23 additions & 5 deletions src/Silex/ControllerCollection.php
Expand Up @@ -42,6 +42,7 @@ class ControllerCollection
protected $defaultRoute;
protected $defaultController;
protected $prefix;
protected $routes;

public function __construct(Route $defaultRoute)
{
Expand All @@ -51,6 +52,16 @@ public function __construct(Route $defaultRoute)
};
}

/**
* 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.
*
Expand All @@ -59,6 +70,10 @@ public function __construct(Route $defaultRoute)
*/
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;
Expand Down Expand Up @@ -188,12 +203,17 @@ public function __call($method, $arguments)
*/
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 .= '_';
}
Expand All @@ -202,12 +222,10 @@ public function flush($prefix = '')
$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;
Expand Down
35 changes: 35 additions & 0 deletions tests/Silex/Tests/ControllerCollectionTest.php
Expand Up @@ -89,6 +89,41 @@ public function testUniqueGeneratedRouteNames()
$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());
Expand Down

0 comments on commit 091240e

Please sign in to comment.