method = strtoupper($method); $this->path = $path; $this->handler = $handler; } // ── Fluent middleware / permission builders ─────────────────────────────── public function middleware(string $name): self { $this->middleware = $name; return $this; } public function permission(string $permission): self { $this->requiredPermission = $permission; return $this; } public function getMiddleware(): ?string { return $this->middleware; } public function getRequiredPermission(): ?string { return $this->requiredPermission; } // ── Matching ────────────────────────────────────────────────────────────── public function matches(string $method, string $path): bool { if (strtoupper($method) !== $this->method) { return false; } $routePattern = preg_replace('#\{([a-zA-Z_][a-zA-Z0-9_]*)\}#', '([^/]+)', $this->path); $routePattern = '#^' . $routePattern . '$#'; if (!preg_match($routePattern, $path, $matches)) { return false; } array_shift($matches); preg_match_all('#\{([a-zA-Z_][a-zA-Z0-9_]*)\}#', $this->path, $names); $this->parameters = []; foreach ($names[1] as $index => $name) { $this->parameters[$name] = $matches[$index] ?? null; } return true; } public function dispatch(App $app): mixed { return $app->call($this->handler, $this->parameters); } }