From f2289a608dd98a2f479b8c0a3396720a113eb2ec Mon Sep 17 00:00:00 2001 From: Vladyslav G Date: Tue, 22 Oct 2024 18:14:14 +0200 Subject: [PATCH] Add WithoutMiddleware option to route --- src/Attributes/Any.php | 2 + src/Attributes/Delete.php | 2 + src/Attributes/Get.php | 2 + src/Attributes/Patch.php | 2 + src/Attributes/Post.php | 2 + src/Attributes/Put.php | 2 + src/Attributes/Route.php | 4 ++ src/RouteRegistrar.php | 23 ++++++++-- .../AttributeTests/FallbackAttributeTest.php | 8 +++- .../WithoutMiddlewareAttributeTest.php | 26 +++++++++++ tests/TestCase.php | 44 ++++++++++++------- .../WithoutMiddlewareTestController.php | 14 ++++++ .../Middleware/SkippedMiddleware.php | 14 ++++++ 13 files changed, 123 insertions(+), 22 deletions(-) create mode 100644 tests/AttributeTests/WithoutMiddlewareAttributeTest.php create mode 100644 tests/TestClasses/Controllers/WithoutMiddlewareTestController.php create mode 100644 tests/TestClasses/Middleware/SkippedMiddleware.php diff --git a/src/Attributes/Any.php b/src/Attributes/Any.php index cc81b88..529cc87 100644 --- a/src/Attributes/Any.php +++ b/src/Attributes/Any.php @@ -12,12 +12,14 @@ public function __construct( string $uri, ?string $name = null, array | string $middleware = [], + array | string $withoutMiddleware = [], ) { parent::__construct( methods: Router::$verbs, uri: $uri, name: $name, middleware: $middleware, + withoutMiddleware: $withoutMiddleware ); } } diff --git a/src/Attributes/Delete.php b/src/Attributes/Delete.php index a69ba9d..8c6c640 100644 --- a/src/Attributes/Delete.php +++ b/src/Attributes/Delete.php @@ -11,12 +11,14 @@ public function __construct( string $uri, ?string $name = null, array | string $middleware = [], + array | string $withoutMiddleware = [], ) { parent::__construct( methods: ['delete'], uri: $uri, name: $name, middleware: $middleware, + withoutMiddleware: $withoutMiddleware ); } } diff --git a/src/Attributes/Get.php b/src/Attributes/Get.php index 6409ee3..801b026 100644 --- a/src/Attributes/Get.php +++ b/src/Attributes/Get.php @@ -11,12 +11,14 @@ public function __construct( string $uri, ?string $name = null, array | string $middleware = [], + array | string $withoutMiddleware = [], ) { parent::__construct( methods: ['get'], uri: $uri, name: $name, middleware: $middleware, + withoutMiddleware: $withoutMiddleware ); } } diff --git a/src/Attributes/Patch.php b/src/Attributes/Patch.php index bb57496..0c3ef2a 100644 --- a/src/Attributes/Patch.php +++ b/src/Attributes/Patch.php @@ -11,12 +11,14 @@ public function __construct( string $uri, ?string $name = null, array | string $middleware = [], + array | string $withoutMiddleware = [], ) { parent::__construct( methods: ['patch'], uri: $uri, name: $name, middleware: $middleware, + withoutMiddleware: $withoutMiddleware ); } } diff --git a/src/Attributes/Post.php b/src/Attributes/Post.php index 5ab3df6..2293e6a 100644 --- a/src/Attributes/Post.php +++ b/src/Attributes/Post.php @@ -11,12 +11,14 @@ public function __construct( string $uri, ?string $name = null, array | string $middleware = [], + array | string $withoutMiddleware = [], ) { parent::__construct( methods: ['post'], uri: $uri, name: $name, middleware: $middleware, + withoutMiddleware: $withoutMiddleware ); } } diff --git a/src/Attributes/Put.php b/src/Attributes/Put.php index 20c575b..752c572 100644 --- a/src/Attributes/Put.php +++ b/src/Attributes/Put.php @@ -11,12 +11,14 @@ public function __construct( string $uri, ?string $name = null, array | string $middleware = [], + array | string $withoutMiddleware = [], ) { parent::__construct( methods: ['put'], uri: $uri, name: $name, middleware: $middleware, + withoutMiddleware: $withoutMiddleware ); } } diff --git a/src/Attributes/Route.php b/src/Attributes/Route.php index c4b9bbc..005ed37 100644 --- a/src/Attributes/Route.php +++ b/src/Attributes/Route.php @@ -13,11 +13,14 @@ class Route implements RouteAttribute public array $middleware; + public array $withoutMiddleware; + public function __construct( array | string $methods, public string $uri, public ?string $name = null, array | string $middleware = [], + array | string $withoutMiddleware = [], ) { $this->methods = array_map( static fn (string $verb) => in_array( @@ -29,5 +32,6 @@ public function __construct( Arr::wrap($methods) ); $this->middleware = Arr::wrap($middleware); + $this->withoutMiddleware = Arr::wrap($withoutMiddleware); } } diff --git a/src/RouteRegistrar.php b/src/RouteRegistrar.php index 753042a..607ff38 100644 --- a/src/RouteRegistrar.php +++ b/src/RouteRegistrar.php @@ -116,19 +116,19 @@ protected function processAttributes(string $className): void $class = new ReflectionClass($className); $classRouteAttributes = new ClassRouteAttributes($class); - + $groups = $classRouteAttributes->groups(); - + foreach ($groups as $group) { $router = $this->router; $router->group($group, fn () => $this->registerRoutes($class, $classRouteAttributes)); } - + if ($classRouteAttributes->resource()) { $this->registerResource($class, $classRouteAttributes); } - + } protected function registerResource(ReflectionClass $class, ClassRouteAttributes $classRouteAttributes): void @@ -174,6 +174,9 @@ protected function registerRoutes(ReflectionClass $class, ClassRouteAttributes $ $this->addMiddlewareToRoute($classRouteAttributes, $attributeClass, $route); + $this->addWithoutMiddlewareToRoute($classRouteAttributes, $attributeClass, $route); + + $this->setWithTrashedIfAvailable($classRouteAttributes, $withTrashedAttribute, $route); @@ -264,6 +267,18 @@ public function addMiddlewareToRoute(ClassRouteAttributes $classRouteAttributes, $route->middleware([...$this->middleware, ...$classMiddleware, ...$methodMiddleware]); } + /** + * @param ClassRouteAttributes $classRouteAttributes + * @param Route $attributeClass + * @param \Illuminate\Routing\Route $route + * @return void + */ + private function addWithoutMiddlewareToRoute(ClassRouteAttributes $classRouteAttributes, Route $attributeClass, \Illuminate\Routing\Route $route): void + { + $methodWithoutMiddleware = $attributeClass->withoutMiddleware; + $route->withoutMiddleware($methodWithoutMiddleware); + } + /** * @param ClassRouteAttributes $classRouteAttributes * @param mixed $defaultAttributes diff --git a/tests/AttributeTests/FallbackAttributeTest.php b/tests/AttributeTests/FallbackAttributeTest.php index 9b87c9c..10f13ac 100644 --- a/tests/AttributeTests/FallbackAttributeTest.php +++ b/tests/AttributeTests/FallbackAttributeTest.php @@ -14,6 +14,12 @@ public function it_can_register_a_route_as_fallback() $this ->assertRegisteredRoutesCount(1) - ->assertRouteRegistered(FallbackTestController::class, 'myFallbackMethod', 'get', 'my-fallback-method', [], null, null, [], true); + ->assertRouteRegistered( + controller: FallbackTestController::class, + controllerMethod: 'myFallbackMethod', + httpMethods: 'get', + uri: 'my-fallback-method', + isFallback: true + ); } } diff --git a/tests/AttributeTests/WithoutMiddlewareAttributeTest.php b/tests/AttributeTests/WithoutMiddlewareAttributeTest.php new file mode 100644 index 0000000..35a5d12 --- /dev/null +++ b/tests/AttributeTests/WithoutMiddlewareAttributeTest.php @@ -0,0 +1,26 @@ +routeRegistrar->registerClass(WithoutMiddlewareTestController::class); + + + $this + ->assertRegisteredRoutesCount(1) + ->assertRouteRegistered( + WithoutMiddlewareTestController::class, + controllerMethod: 'withoutMiddleware', + uri: 'without-middleware', + withoutMiddleware: [SkippedMiddleware::class], + ); + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php index 6556344..444a3a1 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -40,28 +40,34 @@ public function assertRegisteredRoutesCount(int $expectedNumber): self } public function assertRouteRegistered( - string $controller, - string $controllerMethod = 'myMethod', - string | array $httpMethods = ['get'], - string $uri = 'my-method', - string | array $middleware = [], - ?string $name = null, - ?string $domain = null, - ?array $wheres = [], - ?bool $isFallback = false, - ?bool $enforcesScopedBindings = false, - ?bool $preventsScopedBindings = false, - ?array $defaults = [], - ?bool $withTrashed = false, - ): self { - if (! is_array($middleware)) { + string $controller, + string $controllerMethod = 'myMethod', + string|array $httpMethods = ['get'], + string $uri = 'my-method', + string|array $middleware = [], + string|array $withoutMiddleware = [], + ?string $name = null, + ?string $domain = null, + ?array $wheres = [], + ?bool $isFallback = false, + ?bool $enforcesScopedBindings = false, + ?bool $preventsScopedBindings = false, + ?array $defaults = [], + ?bool $withTrashed = false, + ): self + { + if (!is_array($middleware)) { $middleware = Arr::wrap($middleware); } + if (!is_array($withoutMiddleware)) { + $withoutMiddleware = Arr::wrap($withoutMiddleware); + } + $routeRegistered = collect($this->getRouteCollection()->getRoutes()) - ->contains(function (Route $route) use ($name, $middleware, $controllerMethod, $controller, $uri, $httpMethods, $domain, $wheres, $isFallback, $enforcesScopedBindings, $preventsScopedBindings, $defaults, $withTrashed) { + ->contains(function (Route $route) use ($name, $middleware, $withoutMiddleware, $controllerMethod, $controller, $uri, $httpMethods, $domain, $wheres, $isFallback, $enforcesScopedBindings, $preventsScopedBindings, $defaults, $withTrashed) { foreach (Arr::wrap($httpMethods) as $httpMethod) { - if (! in_array(strtoupper($httpMethod), $route->methods)) { + if (!in_array(strtoupper($httpMethod), $route->methods)) { return false; } } @@ -84,6 +90,10 @@ public function assertRouteRegistered( return false; } + if (array_diff($withoutMiddleware, $route->excludedMiddleware())) { + return false; + } + if ($route->getName() !== $name) { return false; } diff --git a/tests/TestClasses/Controllers/WithoutMiddlewareTestController.php b/tests/TestClasses/Controllers/WithoutMiddlewareTestController.php new file mode 100644 index 0000000..0fe631f --- /dev/null +++ b/tests/TestClasses/Controllers/WithoutMiddlewareTestController.php @@ -0,0 +1,14 @@ +