From 62afd267d709dcc9d42558b53e5a734b6b414fdc Mon Sep 17 00:00:00 2001 From: Ollie Read Date: Mon, 28 Oct 2024 17:26:57 +0000 Subject: [PATCH 1/4] Add builder option for disabling controller middleware --- .../Configuration/ApplicationBuilder.php | 4 ++ .../Foundation/Configuration/Middleware.php | 41 +++++++++++++++++++ src/Illuminate/Foundation/Http/Kernel.php | 10 +++++ src/Illuminate/Routing/Route.php | 2 +- src/Illuminate/Routing/Router.php | 41 +++++++++++++++++++ 5 files changed, 97 insertions(+), 1 deletion(-) diff --git a/src/Illuminate/Foundation/Configuration/ApplicationBuilder.php b/src/Illuminate/Foundation/Configuration/ApplicationBuilder.php index 89ec3b9cc50f..f4f3ea8a6ae5 100644 --- a/src/Illuminate/Foundation/Configuration/ApplicationBuilder.php +++ b/src/Illuminate/Foundation/Configuration/ApplicationBuilder.php @@ -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; diff --git a/src/Illuminate/Foundation/Configuration/Middleware.php b/src/Illuminate/Foundation/Configuration/Middleware.php index 52b83acf518b..fce0617b1520 100644 --- a/src/Illuminate/Foundation/Configuration/Middleware.php +++ b/src/Illuminate/Foundation/Configuration/Middleware.php @@ -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. * @@ -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; + } } diff --git a/src/Illuminate/Foundation/Http/Kernel.php b/src/Illuminate/Foundation/Http/Kernel.php index 90c9fb010f4d..7fdf36f35ace 100644 --- a/src/Illuminate/Foundation/Http/Kernel.php +++ b/src/Illuminate/Foundation/Http/Kernel.php @@ -699,4 +699,14 @@ public function setApplication(Application $app) return $this; } + + /** + * Get the router. + * + * @return \Illuminate\Routing\Router + */ + public function getRouter() + { + return $this->router; + } } diff --git a/src/Illuminate/Routing/Route.php b/src/Illuminate/Routing/Route.php index f59b47ce032d..24899b78994f 100755 --- a/src/Illuminate/Routing/Route.php +++ b/src/Illuminate/Routing/Route.php @@ -1103,7 +1103,7 @@ public function can($ability, $models = []) */ public function controllerMiddleware() { - if (! $this->isControllerAction()) { + if ($this->router->shouldSkipControllerMiddleware() || ! $this->isControllerAction()) { return []; } diff --git a/src/Illuminate/Routing/Router.php b/src/Illuminate/Routing/Router.php index 2be5d05e3a14..99d2fdba1ca8 100644 --- a/src/Illuminate/Routing/Router.php +++ b/src/Illuminate/Routing/Router.php @@ -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. * @@ -1503,4 +1510,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; + } } From b6e5c4c2b66d01d74af30be65e8ad8f5e65ca256 Mon Sep 17 00:00:00 2001 From: Ollie Read Date: Wed, 30 Oct 2024 13:33:15 +0000 Subject: [PATCH 2/4] Add a test for disabling controller middleware --- tests/Routing/RoutingRouteTest.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/Routing/RoutingRouteTest.php b/tests/Routing/RoutingRouteTest.php index bb7964a7b07b..ab15a82667a9 100644 --- a/tests/Routing/RoutingRouteTest.php +++ b/tests/Routing/RoutingRouteTest.php @@ -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); From 43db755101604014fecc09c268ff033ddd339277 Mon Sep 17 00:00:00 2001 From: Ollie Read Date: Wed, 30 Oct 2024 13:45:19 +0000 Subject: [PATCH 3/4] Styling fixes --- src/Illuminate/Foundation/Configuration/Middleware.php | 2 +- src/Illuminate/Routing/Router.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Foundation/Configuration/Middleware.php b/src/Illuminate/Foundation/Configuration/Middleware.php index fce0617b1520..6dd832eb5a99 100644 --- a/src/Illuminate/Foundation/Configuration/Middleware.php +++ b/src/Illuminate/Foundation/Configuration/Middleware.php @@ -146,7 +146,7 @@ class Middleware protected $priority = []; /** - * Whether to disable controller middleware + * Whether to disable controller middleware. * * @var bool */ diff --git a/src/Illuminate/Routing/Router.php b/src/Illuminate/Routing/Router.php index 99d2fdba1ca8..897946a419d9 100644 --- a/src/Illuminate/Routing/Router.php +++ b/src/Illuminate/Routing/Router.php @@ -101,7 +101,7 @@ class Router implements BindingRegistrar, RegistrarContract public $middlewarePriority = []; /** - * Whether to disable controller middleware + * Whether to disable controller middleware. * * @var bool */ From 3280419212b9e7d3d254b38cecaeda9e11ce5631 Mon Sep 17 00:00:00 2001 From: Ollie Read Date: Wed, 30 Oct 2024 14:41:02 +0000 Subject: [PATCH 4/4] Add router to abstract route collection --- .../Routing/AbstractRouteCollection.php | 34 +++++++++++++++++-- .../Routing/CompiledRouteCollection.php | 13 ------- src/Illuminate/Routing/Router.php | 2 ++ 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/Illuminate/Routing/AbstractRouteCollection.php b/src/Illuminate/Routing/AbstractRouteCollection.php index d87441ea2f1b..08df760d5b81 100644 --- a/src/Illuminate/Routing/AbstractRouteCollection.php +++ b/src/Illuminate/Routing/AbstractRouteCollection.php @@ -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. * @@ -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()); diff --git a/src/Illuminate/Routing/CompiledRouteCollection.php b/src/Illuminate/Routing/CompiledRouteCollection.php index 189bee7d339d..d27d405ca9d4 100644 --- a/src/Illuminate/Routing/CompiledRouteCollection.php +++ b/src/Illuminate/Routing/CompiledRouteCollection.php @@ -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. * diff --git a/src/Illuminate/Routing/Router.php b/src/Illuminate/Routing/Router.php index 897946a419d9..f87514bb6a28 100644 --- a/src/Illuminate/Routing/Router.php +++ b/src/Illuminate/Routing/Router.php @@ -154,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); } /**