From 32254bf39876cc36f7b9b24d5d71c6ad6c065ca8 Mon Sep 17 00:00:00 2001 From: flashwave Date: Thu, 7 Sep 2023 22:08:31 +0000 Subject: [PATCH] Added routing through attributes. --- VERSION | 2 +- src/Routing/Route.php | 49 +++++++++++++++++++++++++++++++ src/Routing/RouteHandlerTrait.php | 12 ++++++++ tests/RouterTest.php | 48 +++++++++++++++++++++++++++++- 4 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 src/Routing/Route.php create mode 100644 src/Routing/RouteHandlerTrait.php diff --git a/VERSION b/VERSION index 5a96943..f7b18b5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2309.61148 +0.2309.72158 diff --git a/src/Routing/Route.php b/src/Routing/Route.php new file mode 100644 index 0000000..678d454 --- /dev/null +++ b/src/Routing/Route.php @@ -0,0 +1,49 @@ +method; + } + + public function getPath(): string { + return $this->path; + } + + public static function handleAttributes(IRouter $router, IRouteHandler $handler): void { + $objectInfo = new ReflectionObject($handler); + $methodInfos = $objectInfo->getMethods(); + + foreach($methodInfos as $methodInfo) { + $attrInfos = $methodInfo->getAttributes(Route::class); + + foreach($attrInfos as $attrInfo) { + if($attrInfo->isRepeated()) + throw new UnexpectedValueException('Only one instance of the Route attribute should be used per method.'); + + $routeInfo = $attrInfo->newInstance(); + $router->add( + $routeInfo->getMethod(), + $routeInfo->getPath(), + $methodInfo->getClosure( + $methodInfo->isStatic() ? null : $handler + ) + ); + } + } + } +} diff --git a/src/Routing/RouteHandlerTrait.php b/src/Routing/RouteHandlerTrait.php new file mode 100644 index 0000000..3593fd5 --- /dev/null +++ b/src/Routing/RouteHandlerTrait.php @@ -0,0 +1,12 @@ +assertEquals('correct', $router3->resolve('GET', '/static/0')->run()); $this->assertEquals('correct', $router3->resolve('GET', '/variable/0')->run()); } + + public function testAttribute(): void { + $router = new Router; + $handler = new class implements IRouteHandler { + use RouteHandlerTrait; + + #[Route('GET', '/')] + public function getIndex() { + return 'index'; + } + + #[Route('POST', '/avatar')] + public function postAvatar() { + return 'avatar'; + } + + #[Route('PUT', '/static')] + public static function putStatic() { + return 'static'; + } + + public function hasNoAttr() { + return 'meow'; + } + }; + + $router->register($handler); + $this->assertEquals('index', $router->resolve('GET', '/')->run()); + $this->assertEquals('avatar', $router->resolve('POST', '/avatar')->run()); + $this->assertEquals('static', $router->resolve('PUT', '/static')->run()); + + $badHandler = new class implements IRouteHandler { + use RouteHandlerTrait; + + #[Route('GET', '/')] + #[Route('POST', '/meow')] + public function getPostBad() { + return 'this is bad'; + } + }; + $this->expectException(UnexpectedValueException::class); + $router->register($badHandler); + } }