*/ public function load(string $controllerClass): array { if (!class_exists($controllerClass)) { throw new RouteRegistrationException("Controller class not found: {$controllerClass}"); } try { $reflector = new ReflectionClass($controllerClass); } catch (ReflectionException $e) { throw new RouteRegistrationException("Unable to reflect controller: {$controllerClass}", 0, $e); } $classMiddleware = $this->middlewareClasses($reflector->getAttributes(Middleware::class)); $routes = []; foreach ($reflector->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { foreach ($this->loadMethod($controllerClass, $method, $classMiddleware) as $route) { $routes[] = $route; } } return $routes; } /** * @param list $classMiddleware * @return list */ private function loadMethod(string $controllerClass, ReflectionMethod $method, array $classMiddleware): array { $routeAttributes = $method->getAttributes(RouteAttribute::class, ReflectionAttribute::IS_INSTANCEOF); if ($routeAttributes === []) { return []; } $methodMiddleware = $this->middlewareClasses($method->getAttributes(Middleware::class)); $middleware = array_merge($classMiddleware, $methodMiddleware); $routes = []; foreach ($routeAttributes as $attribute) { /** @var RouteAttribute $route */ $route = $attribute->newInstance(); $routes[] = new RouteDef( strtoupper($route->method()), $route->path(), $controllerClass, $method->getName(), $middleware, ); } return $routes; } /** * @param list $attributes * @return list */ private function middlewareClasses(array $attributes): array { $classes = []; foreach ($attributes as $attribute) { /** @var Middleware $middleware */ $middleware = $attribute->newInstance(); $classes[] = $middleware->middlewareClass; } return $classes; } }