diff --git a/src/Illuminate/Routing/PendingResourceRegistration.php b/src/Illuminate/Routing/PendingResourceRegistration.php index b7d158ddd7b..4f88fbe7680 100644 --- a/src/Illuminate/Routing/PendingResourceRegistration.php +++ b/src/Illuminate/Routing/PendingResourceRegistration.php @@ -2,6 +2,7 @@ namespace Illuminate\Routing; +use Illuminate\Support\Arr; use Illuminate\Support\Traits\Macroable; class PendingResourceRegistration @@ -153,6 +154,21 @@ public function middleware($middleware) return $this; } + /** + * Specify middleware that should be removed from the resource routes. + * + * @param array|string $middleware + * @return $this|array + */ + public function withoutMiddleware($middleware) + { + $this->options['excluded_middleware'] = array_merge( + (array) ($this->options['excluded_middleware'] ?? []), Arr::wrap($middleware) + ); + + return $this; + } + /** * Indicate that the resource routes should have "shallow" nesting. * diff --git a/src/Illuminate/Routing/ResourceRegistrar.php b/src/Illuminate/Routing/ResourceRegistrar.php index f9353da035e..c4230ba1a8b 100644 --- a/src/Illuminate/Routing/ResourceRegistrar.php +++ b/src/Illuminate/Routing/ResourceRegistrar.php @@ -389,6 +389,10 @@ protected function getResourceAction($resource, $controller, $method, $options) $action['middleware'] = $options['middleware']; } + if (isset($options['excluded_middleware'])) { + $action['excluded_middleware'] = $options['excluded_middleware']; + } + return $action; } diff --git a/tests/Routing/RouteRegistrarTest.php b/tests/Routing/RouteRegistrarTest.php index 1fd036c5fba..f055fbc4d42 100644 --- a/tests/Routing/RouteRegistrarTest.php +++ b/tests/Routing/RouteRegistrarTest.php @@ -513,6 +513,18 @@ public function testCanSetMiddlewareOnRegisteredResource() $this->seeMiddleware(RouteRegistrarMiddlewareStub::class); } + public function testResourceWithoutMiddlewareRegistration() + { + $this->router->resource('users', RouteRegistrarControllerStub::class) + ->only('index') + ->middleware(['one', 'two']) + ->withoutMiddleware('one'); + + $this->seeResponse('controller', Request::create('users', 'GET')); + + $this->assertEquals(['one'], $this->getRoute()->excludedMiddleware()); + } + public function testCanSetRouteName() { $this->router->as('users.index')->get('users', function () { diff --git a/tests/Routing/RoutingRouteTest.php b/tests/Routing/RoutingRouteTest.php index 7e85f1744a4..5750a5761a8 100644 --- a/tests/Routing/RoutingRouteTest.php +++ b/tests/Routing/RoutingRouteTest.php @@ -205,6 +205,18 @@ public function testMiddlewareCanBeSkipped() $this->assertEquals('hello', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent()); } + public function testMiddlewareCanBeSkippedFromResources() + { + $router = $this->getRouter(); + $router->aliasMiddleware('web', RoutingTestMiddlewareGroupTwo::class); + + $router->resource('foo', RouteTestControllerMiddlewareGroupStub::class) + ->middleware('web') + ->withoutMiddleware(RoutingTestMiddlewareGroupTwo::class); + + $this->assertEquals('Hello World', $router->dispatch(Request::create('foo', 'GET'))->getContent()); + } + public function testMiddlewareWorksIfControllerThrowsHttpResponseException() { // Before calling controller