From 62d902bdaccf2f3afeafc52924c968848c8b2ceb Mon Sep 17 00:00:00 2001 From: eliseekn Date: Tue, 27 Feb 2024 20:46:19 +0000 Subject: [PATCH] Add routes attributes --- .../Auth/EmailVerificationController.php | 5 +- .../Auth/ForgotPasswordController.php | 8 ++- app/Http/Controllers/Auth/LoginController.php | 5 +- .../Controllers/Auth/LogoutController.php | 2 + .../Controllers/Auth/RegisterController.php | 3 + core/Routing/Attributes/Route.php | 16 +++++ core/Routing/Route.php | 58 +++++++++++++++---- routes/auth.php | 49 +--------------- 8 files changed, 83 insertions(+), 63 deletions(-) create mode 100644 core/Routing/Attributes/Route.php diff --git a/app/Http/Controllers/Auth/EmailVerificationController.php b/app/Http/Controllers/Auth/EmailVerificationController.php index 1116531..efee30c 100644 --- a/app/Http/Controllers/Auth/EmailVerificationController.php +++ b/app/Http/Controllers/Auth/EmailVerificationController.php @@ -13,6 +13,7 @@ use App\Http\UseCases\User\UpdateUseCase; use App\Mails\VerificationMail; use App\Mails\WelcomeMail; +use Core\Routing\Attributes\Route; use Core\Routing\Controller; use Core\Support\Alert; @@ -21,7 +22,8 @@ */ class EmailVerificationController extends Controller { - public function notify(): void + #[Route('GET', '/email/notify')] + public function notify(): void { $tokenValue = generate_token(15); $token = Token::findByDescription($this->request->queries('email'), TokenDescription::EMAIL_VERIFICATION_TOKEN->value); @@ -46,6 +48,7 @@ public function notify(): void $this->render('auth.login'); } + #[Route('GET', '/email/verify')] public function verify(UpdateUseCase $useCase): void { if (!$this->request->hasQuery(['email', 'token'])) { diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php index 58d8ebb..c28cf4c 100644 --- a/app/Http/Controllers/Auth/ForgotPasswordController.php +++ b/app/Http/Controllers/Auth/ForgotPasswordController.php @@ -13,6 +13,7 @@ use App\Http\UseCases\User\UpdateUseCase; use App\Http\Validators\Auth\LoginValidator; use App\Mails\TokenMail; +use Core\Routing\Attributes\Route; use Core\Routing\Controller; use Core\Support\Alert; @@ -21,6 +22,7 @@ */ class ForgotPasswordController extends Controller { + #[Route('POST', '/password/notify', ['csrf'])] public function notify(): void { $tokenValue = generate_token(15); @@ -45,7 +47,8 @@ public function notify(): void $this->redirectBack(); } - + + #[Route('GET', '/password/reset')] public function reset(): void { if (!$this->request->hasQuery(['email', 'token'])) { @@ -65,7 +68,8 @@ public function reset(): void $token->delete(); $this->render('auth.password.new', ['email' => $this->request->queries('email')]); } - + + #[Route('POST', '/password/update', ['csrf'])] public function update(UpdateUseCase $useCase): void { $validated = $this->validate(new LoginValidator()); diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 72e6faf..84c56f4 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -9,12 +9,14 @@ namespace App\Http\Controllers\Auth; use App\Http\Validators\Auth\LoginValidator; +use Core\Routing\Attributes\Route; use Core\Routing\Controller; use Core\Support\Alert; use Core\Support\Auth; class LoginController extends Controller -{ +{ + #[Route('GET', '/login', ['remember'])] public function index(): void { if (!Auth::check($this->request)) { @@ -24,6 +26,7 @@ public function index(): void $this->redirectUrl(config('app.home')); } + #[Route(methods: 'POST', middlewares: ['csrf'])] public function authenticate(): void { $this->validate(new LoginValidator()); diff --git a/app/Http/Controllers/Auth/LogoutController.php b/app/Http/Controllers/Auth/LogoutController.php index 3e755b6..bbb2842 100644 --- a/app/Http/Controllers/Auth/LogoutController.php +++ b/app/Http/Controllers/Auth/LogoutController.php @@ -8,12 +8,14 @@ namespace App\Http\Controllers\Auth; +use Core\Routing\Attributes\Route; use Core\Routing\Controller; use Core\Support\Alert; use Core\Support\Auth; class LogoutController extends Controller { + #[Route('POST', '/logout', ['auth'])] public function __invoke(): void { Auth::forget(); diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 29c3686..38700c2 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -11,12 +11,14 @@ use App\Events\UserRegistered\UserRegisteredEvent; use App\Http\UseCases\User\StoreUseCase; use App\Http\Validators\Auth\RegisterValidator; +use Core\Routing\Attributes\Route; use Core\Routing\Controller; use Core\Support\Alert; use Core\Support\Auth; class RegisterController extends Controller { + #[Route('GET', '/signup', ['remember'])] public function index(): void { if (!Auth::check($this->request)) { @@ -26,6 +28,7 @@ public function index(): void $this->redirectUrl(config('app.home')); } + #[Route(methods: 'POST', middlewares: ['csrf'])] public function register(StoreUseCase $useCase): void { $validated = $this->validate(new RegisterValidator()); diff --git a/core/Routing/Attributes/Route.php b/core/Routing/Attributes/Route.php new file mode 100644 index 0000000..66d2c58 --- /dev/null +++ b/core/Routing/Attributes/Route.php @@ -0,0 +1,16 @@ +classes()->get(); + + foreach ($controllers as $controller) { + $reflectionClass = new ReflectionClass($controller); + $methods = $reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC); + + foreach ($methods as $method) { + $attributes = $method->getAttributes(Attributes\Route::class); + + foreach ($attributes as $attribute) { + $attribute = $attribute->newInstance(); + $route = self::match($attribute->methods, $attribute->uri ?? $method->getName(), [$controller, $method->getName()]); + + if ($attribute->middlewares) { + $route->middleware($attribute->middlewares); + } + + if ($attribute->name) { + $route->name($attribute->name); + } + + $route->register(); + } + } + } + } + public static function load(): void { - if (empty(config('routes.paths'))) { + self::loadFromAttributes(); + + if (empty(config('routes.paths')) && empty(self::$routes)) { throw new RoutesPathsNotDefinedException(); } - $paths = array_map(function ($path) { - $path = $path === '/' - ? config('storage.routes') - : Storage::path(config('storage.routes'))->addPath($path)->getPath(); + if (!empty(config('routes.paths'))) { + $paths = array_map(function ($path) { + $path = $path === '/' + ? config('storage.routes') + : Storage::path(config('storage.routes'))->addPath($path)->getPath(); - return str_replace(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, $path); - }, config('routes.paths')); + return str_replace(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, $path); + }, config('routes.paths')); - foreach ($paths as $path) { - $routes = Storage::path($path)->addPath('')->getFiles(); + foreach ($paths as $path) { + $routes = Storage::path($path)->addPath('')->getFiles(); - foreach ($routes as $route) { - require_once $path . $route; + foreach ($routes as $route) { + require_once $path . $route; + } } } } diff --git a/routes/auth.php b/routes/auth.php index 9cddf9a..4e9c1da 100644 --- a/routes/auth.php +++ b/routes/auth.php @@ -6,57 +6,10 @@ * @link https://github.com/eliseekn/tinymvc */ -use Core\Http\Request; use Core\Routing\Route; -use Core\Http\Response; -use App\Http\Controllers\Auth\LoginController; -use App\Http\Controllers\Auth\LogoutController; -use App\Http\Controllers\Auth\RegisterController; -use App\Http\Controllers\Auth\ForgotPasswordController; -use App\Http\Controllers\Auth\EmailVerificationController; /** * Authentication routes */ -Route::group(function () { - Route::get('/login', [LoginController::class, 'index']); - Route::get('/signup', [RegisterController::class, 'index']); -}) - ->byMiddleware('remember') - ->register(); - -Route::group(function () { - Route::post('/authenticate', [LoginController::class, 'authenticate']); - Route::post('/register', [RegisterController::class, 'register']); -}) - ->byMiddleware('csrf') - ->register(); - -Route::group(function () { - Route::get('/reset', [ForgotPasswordController::class, 'reset']); - Route::view('/forgot', 'auth.password.forgot'); -}) - ->byPrefix('password') - ->register(); - -Route::group(function () { - Route::post('/notify', 'notify'); - Route::post('/update', 'update'); -}) - ->byPrefix('password') - ->byController(ForgotPasswordController::class) - ->byMiddleware('csrf') - ->register(); - -Route::group(function () { - Route::get('/verify', 'verify'); - Route::get('/notify', 'notify'); -}) - ->byPrefix('email') - ->byController(EmailVerificationController::class) - ->register(); - -Route::post('/logout', LogoutController::class) - ->middleware('auth') - ->register(); +Route::view('/password/forgot', 'auth.password.forgot')->register();