diff --git a/src/Illuminate/Routing/CompiledRouteCollection.php b/src/Illuminate/Routing/CompiledRouteCollection.php index a20979bf4e41..939a07b6a762 100644 --- a/src/Illuminate/Routing/CompiledRouteCollection.php +++ b/src/Illuminate/Routing/CompiledRouteCollection.php @@ -73,6 +73,17 @@ public function add(Route $route) return $this->routes->add($route); } + /** + * Remove the given route from the collection. + * + * @param \Illuminate\Routing\Route $route + * @return void + */ + public function remove(Route $route) + { + $this->routes->remove($route); + } + /** * Refresh the name look-up table. * diff --git a/src/Illuminate/Routing/RouteCollection.php b/src/Illuminate/Routing/RouteCollection.php index 2898f0fa5eb6..2605925a1b36 100644 --- a/src/Illuminate/Routing/RouteCollection.php +++ b/src/Illuminate/Routing/RouteCollection.php @@ -50,6 +50,19 @@ public function add(Route $route) return $route; } + /** + * Remove the given route from the collection. + * + * @param \Illuminate\Routing\Route $route + * @return void + */ + public function remove(Route $route) + { + $this->removeFromCollections($route); + + $this->removeLookups($route); + } + /** * Add the given route to the arrays of routes. * @@ -80,6 +93,24 @@ protected function addToCollections($route) } } + /** + * Remove the given route from the arrays of routes. + * + * @param \Illuminate\Routing\Route $route + * @return void + */ + protected function removeFromCollections(Route $route) + { + $methods = $route->methods(); + $domainAndUri = $route->getDomain().$route->uri(); + + foreach ($methods as $method) { + unset($this->routes[$method][$domainAndUri]); + } + + unset($this->allRoutes[implode('|', $methods).$domainAndUri]); + } + /** * Add the route to any look-up tables if necessary. * @@ -105,6 +136,24 @@ protected function addLookups($route) } } + /** + * Remove the route from any look-up tables. + * + * @param \Illuminate\Routing\Route $route + * @return void + */ + protected function removeLookups(Route $route) + { + if ($name = $route->getName()) { + unset($this->nameList[$name]); + } + + $action = $route->getAction(); + if (isset($action['controller'])) { + $this->removeFromActionList($action); + } + } + /** * Add a route to the controller action dictionary. * @@ -117,6 +166,17 @@ protected function addToActionList($action, $route) $this->actionList[trim($action['controller'], '\\')] = $route; } + /** + * Remove a route from the controller action dictionary. + * + * @param array $action + * @return void + */ + protected function removeFromActionList(array $action) + { + unset($this->actionList[trim($action['controller'], '\\')]); + } + /** * Refresh the name look-up table. * diff --git a/src/Illuminate/Routing/RouteCollectionInterface.php b/src/Illuminate/Routing/RouteCollectionInterface.php index 8e25d0fa1056..ccb02fce1602 100644 --- a/src/Illuminate/Routing/RouteCollectionInterface.php +++ b/src/Illuminate/Routing/RouteCollectionInterface.php @@ -14,6 +14,14 @@ interface RouteCollectionInterface */ public function add(Route $route); + /** + * Remove a Route instance from the collection. + * + * @param \Illuminate\Routing\Route $route + * @return void + */ + public function remove(Route $route); + /** * Refresh the name look-up table. * diff --git a/tests/Integration/Routing/CompiledRouteCollectionTest.php b/tests/Integration/Routing/CompiledRouteCollectionTest.php index fcaa4dad5d4e..6cb072f16ba5 100644 --- a/tests/Integration/Routing/CompiledRouteCollectionTest.php +++ b/tests/Integration/Routing/CompiledRouteCollectionTest.php @@ -57,6 +57,20 @@ public function testRouteCollectionCanAddRoute() $this->assertCount(1, $this->collection()); } + public function testRouteCollectionCanRemoveRoute() + { + $route = $this->newRoute('GET', 'foo', [ + 'uses' => 'FooController@index', + 'as' => 'foo_index', + ]); + + $this->routeCollection->add($route); + $this->assertCount(1, $this->collection()); + + $this->routeCollection->remove($route); + $this->assertCount(0, $this->collection()); + } + public function testRouteCollectionAddReturnsTheRoute() { $outputRoute = $this->collection()->add($inputRoute = $this->newRoute('GET', 'foo', [ diff --git a/tests/Routing/RouteCollectionTest.php b/tests/Routing/RouteCollectionTest.php index e061b9ba777b..9fe1b27d7796 100644 --- a/tests/Routing/RouteCollectionTest.php +++ b/tests/Routing/RouteCollectionTest.php @@ -34,6 +34,28 @@ public function testRouteCollectionCanAddRoute() $this->assertCount(1, $this->routeCollection); } + public function testRouteCanBeRemoved() + { + $route = new Route('GET', 'foo', [ + 'uses' => 'FooController@index', + 'as' => 'foo_index', + 'controller' => 'FooController@index', + ]); + + $this->routeCollection->add($route); + $this->assertCount(1, $this->routeCollection); + $this->assertSame($route, $this->routeCollection->getByName('foo_index')); + $this->assertSame($route, $this->routeCollection->getRoutes()[0]); + $this->assertSame($route, $this->routeCollection->getByAction('FooController@index')); + + $this->routeCollection->remove($route); + + $this->assertCount(0, $this->routeCollection); + $this->assertNull($this->routeCollection->getByName('foo_index')); + $this->assertEmpty($this->routeCollection->getRoutes()); + $this->assertNull($this->routeCollection->getByAction('FooController@index')); + } + public function testRouteCollectionAddReturnsTheRoute() { $outputRoute = $this->routeCollection->add($inputRoute = new Route('GET', 'foo', [