Skip to content
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

Add ability to disable controller middleware #53350

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,10 @@ public function withMiddleware(?callable $callback = null)
if ($priorities = $middleware->getMiddlewarePriority()) {
$kernel->setMiddlewarePriority($priorities);
}

if ($middleware->shouldDisableControllerMiddleware()) {
$kernel->getRouter()->disableControllerMiddleware();
}
});

return $this;
Expand Down
41 changes: 41 additions & 0 deletions src/Illuminate/Foundation/Configuration/Middleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,13 @@ class Middleware
*/
protected $priority = [];

/**
* Whether to disable controller middleware.
*
* @var bool
*/
protected $disableControllerMiddleware = false;

/**
* Prepend middleware to the application's global middleware stack.
*
Expand Down Expand Up @@ -766,4 +773,38 @@ public function getMiddlewarePriority()
{
return $this->priority;
}

/**
* Disable controller middleware.
*
* @return $this
*/
public function withoutControllerMiddleware()
{
$this->disableControllerMiddleware = true;

return $this;
}

/**
* Disable controller middleware.
*
* @return $this
*/
public function withControllerMiddleware()
{
$this->disableControllerMiddleware = false;

return $this;
}

/**
* Whether controller middleware should be disabled.
*
* @return bool
*/
public function shouldDisableControllerMiddleware()
{
return $this->disableControllerMiddleware;
}
}
10 changes: 10 additions & 0 deletions src/Illuminate/Foundation/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -699,4 +699,14 @@ public function setApplication(Application $app)

return $this;
}

/**
* Get the router.
*
* @return \Illuminate\Routing\Router
*/
public function getRouter()
{
return $this->router;
}
}
34 changes: 32 additions & 2 deletions src/Illuminate/Routing/AbstractRouteCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,36 @@

abstract class AbstractRouteCollection implements Countable, IteratorAggregate, RouteCollectionInterface
{
/**
* The router instance used by the route.
*
* @var \Illuminate\Routing\Router
*/
protected $router;

/**
* Get the router instance.
*
* @return \Illuminate\Routing\Router
*/
public function getRouter()
{
return $this->router;
}

/**
* Set the router instance on the route.
*
* @param \Illuminate\Routing\Router $router
* @return $this
*/
public function setRouter(Router $router)
{
$this->router = $router;

return $this;
}

/**
* Handle the matched route.
*
Expand Down Expand Up @@ -99,9 +129,9 @@ protected function matchAgainstRoutes(array $routes, $request, $includingMethod
protected function getRouteForMethods($request, array $methods)
{
if ($request->isMethod('OPTIONS')) {
return (new Route('OPTIONS', $request->path(), function () use ($methods) {
return $this->getRouter()->newRoute('OPTIONS', $request->path(), function () use ($methods) {
return new Response('', 200, ['Allow' => implode(',', $methods)]);
}))->bind($request);
})->bind($request);
}

$this->requestMethodNotAllowed($request, $methods, $request->method());
Expand Down
13 changes: 0 additions & 13 deletions src/Illuminate/Routing/CompiledRouteCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -302,19 +302,6 @@ protected function newRoute(array $attributes)
->withTrashed($attributes['withTrashed'] ?? false);
}

/**
* Set the router instance on the route.
*
* @param \Illuminate\Routing\Router $router
* @return $this
*/
public function setRouter(Router $router)
{
$this->router = $router;

return $this;
}

/**
* Set the container instance on the route.
*
Expand Down
2 changes: 1 addition & 1 deletion src/Illuminate/Routing/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,7 @@ public function can($ability, $models = [])
*/
public function controllerMiddleware()
{
if (! $this->isControllerAction()) {
if ($this->router->shouldSkipControllerMiddleware() || ! $this->isControllerAction()) {
return [];
}

Expand Down
43 changes: 43 additions & 0 deletions src/Illuminate/Routing/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ class Router implements BindingRegistrar, RegistrarContract
*/
public $middlewarePriority = [];

/**
* Whether to disable controller middleware.
*
* @var bool
*/
protected $disableControllerMiddleware = false;

/**
* The registered route value binders.
*
Expand Down Expand Up @@ -147,6 +154,8 @@ public function __construct(Dispatcher $events, ?Container $container = null)
$this->events = $events;
$this->routes = new RouteCollection;
$this->container = $container ?: new Container;

$this->routes->setRouter($this);
}

/**
Expand Down Expand Up @@ -1503,4 +1512,38 @@ public function __call($method, $parameters)

return (new RouteRegistrar($this))->attribute($method, array_key_exists(0, $parameters) ? $parameters[0] : true);
}

/**
* Skip the gathering of controller middleware.
*
* @return $this
*/
public function skipControllerMiddleware()
{
$this->disableControllerMiddleware = true;

return $this;
}

/**
* Allow the gathering of controller middleware.
*
* @return $this
*/
public function allowControllerMiddleware()
{
$this->disableControllerMiddleware = false;

return $this;
}

/**
* Whether the router should gather controller middleware.
*
* @return bool
*/
public function shouldSkipControllerMiddleware()
{
return $this->disableControllerMiddleware;
}
}
20 changes: 20 additions & 0 deletions tests/Routing/RoutingRouteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,26 @@ public function testControllerClosureMiddleware()
);
}

public function testControllerMiddlewareCanBeSkipped()
{
$router = $this->getRouter();
$router->skipControllerMiddleware();
$router->get('foo/bar', [
'uses' => RouteTestClosureMiddlewareController::class.'@index',
'middleware' => 'foo',
]);
$router->aliasMiddleware('foo', function ($request, $next) {
$request['foo-middleware'] = 'foo-middleware';

return $next($request);
});

$this->assertSame(
'index',
$router->dispatch(Request::create('foo/bar', 'GET'))->getContent()
);
}

public function testFluentRouting()
{
$this->expectException(LogicException::class);
Expand Down