diff --git a/app/Controllers/TestController.php b/app/Controllers/TestController.php deleted file mode 100644 index 8a944a4..0000000 --- a/app/Controllers/TestController.php +++ /dev/null @@ -1,22 +0,0 @@ -response->view('subnet'); - } -} \ No newline at end of file diff --git a/config/routes.php b/config/routes.php index fd1f717..33b550b 100644 --- a/config/routes.php +++ b/config/routes.php @@ -2,10 +2,7 @@ use App\Controllers\Api\SubnetController; use App\Controllers\HomeController; -use App\Controllers\TestController; -use Core\Routing\Route; +use Core\Router\Router; -Route::get('/', HomeController::class, 'index'); -Route::post('/api/subnet', SubnetController::class, 'data'); -Route::get('/test/{id}', TestController::class, 'test'); -Route::get('/test/{id}/update', TestController::class, 'test'); \ No newline at end of file +Router::get('/', HomeController::class, 'index'); +Router::post('/api/subnet', SubnetController::class, 'data'); \ No newline at end of file diff --git a/public/index.php b/public/index.php index 2bc027d..a3c2da1 100644 --- a/public/index.php +++ b/public/index.php @@ -1,7 +1,7 @@ handleException($exception); - - exit(0); } } \ No newline at end of file diff --git a/src/Exceptions/Exceptions/HttpException.php b/src/Exceptions/Exceptions/HttpException.php deleted file mode 100644 index 833aeeb..0000000 --- a/src/Exceptions/Exceptions/HttpException.php +++ /dev/null @@ -1,5 +0,0 @@ -data = $data; - - // Capture all exceptions - Exceptions::catch($this); - } - /** * Get request method * @@ -60,7 +43,7 @@ class Request */ public final function has(string $param): bool { - return isset($this->data[$param]); + return isset($_POST[$param]); } /** @@ -73,11 +56,11 @@ class Request public final function get(string|null $param = null, mixed $default = null): mixed { if($param == null) { - return $this->data; + return $_POST; } if($this->has($param)) { - return $this->data[$param]; + return $_POST[$param]; } return $default; diff --git a/src/Router/Router.php b/src/Router/Router.php new file mode 100644 index 0000000..a8b57a2 --- /dev/null +++ b/src/Router/Router.php @@ -0,0 +1,109 @@ + $controller, + 'action' => $action, + ]; + } + + /** + * Dispatch router and run application + * + * @return void + */ + public static function dispatch(): void + { + // Init request + $request = new Request(); + $url = $request->url(); + $method = $request->method(); + + // Capture all exceptions + Exceptions::catch($request); + + try { + if (array_key_exists($url, self::$routes[$method])) { + $controllerName = self::$routes[$method][$url]['controller']; + $actionName = self::$routes[$method][$url]['action']; + + // Check for controller existence + if (!class_exists($controllerName)) { + throw new Exception(sprintf("Controller '%s' missing", $controllerName)); + } + + // Create controller object + $controller = new $controllerName($request); + + // Check for method on controller + if (!method_exists($controller, $actionName)) { + throw new Exception(sprintf("Method '%s' not found on '%s'", $actionName, $controllerName)); + } + + // Build response object of action + $response = $controller->$actionName(); + + // Render action + if ($response instanceof Render) { + $response->render(); + } + } else { + throw new Exception(sprintf("No route found for: %s", $url)); + } + } catch (Exception $e) { + Exceptions::catchOne($e); + } + } +} \ No newline at end of file diff --git a/src/Routing/Route.php b/src/Routing/Route.php deleted file mode 100644 index 86c4a28..0000000 --- a/src/Routing/Route.php +++ /dev/null @@ -1,32 +0,0 @@ - $controller, - 'action' => $action, - 'original' => $route, - ]; - } - - /** - * Reveal the treasure trove of routes. - * - * @return array - */ - public static function retrieve(): array - { - return self::$routes; - } - - /** - * Convert a route pattern into a regex for matching requests. - * - * @param string $route - * @return string - */ - protected static function convertToRegex(string $route): string - { - $regex = preg_replace('/\{([a-zA-Z0-9_]+)\}/', '(?P<\1>[a-zA-Z0-9_-]+)', $route); - return '#^' . $regex . '$#'; - } - - /** - * Retrieve a specific route by method and URL. - * - * @param string $method - * @param string $url - * @return array|null - */ - public static function find(string $method, string $url): ?array - { - foreach (self::$routes[$method] ?? [] as $routeRegex => $route) { - if (preg_match($routeRegex, $url, $matches)) { - $route['params'] = array_filter( - $matches, - fn($key) => !is_numeric($key), - ARRAY_FILTER_USE_KEY - ); - return $route; - } - } - - return null; - } - - /** - * Purge all routes from the collection. - * - * @return void - */ - public static function clear(): void - { - self::$routes = []; - } -} \ No newline at end of file diff --git a/src/Routing/RouteDispatcher.php b/src/Routing/RouteDispatcher.php deleted file mode 100644 index 3ca7782..0000000 --- a/src/Routing/RouteDispatcher.php +++ /dev/null @@ -1,162 +0,0 @@ -request = $request; - $this->routeCollection = $routeCollection; - - try { - $route = $this->findMatchingRoute(); - $controller = $this->instantiateController($route['controller']); - $action = $this->validateActionExists($controller, $route['action']); - $params = $this->resolveParameters($controller, $action, $route['params'] ?? []); - - $this->executeAction($controller, $action, $params); - } catch (NotFoundHttpException $e) { - $this->handleException($e, 404, 'page not found'); - } catch (Exception $e) { - $this->handleException($e, 500, 'something went wrong'); - } - } - - public static function dispatch(Request $request, array $routeCollection): void - { - new self($request, $routeCollection); - } - - /** - * Locate a matching route for the incoming request. - * - * @return array - * @throws \Core\Exceptions\Exceptions\NotFoundHttpException - */ - private function findMatchingRoute(): array - { - $url = $this->request->url(); - $method = $this->request->method(); - - foreach ($this->routeCollection[$method] ?? [] as $routeRegex => $route) { - if (preg_match($routeRegex, $url, $matches)) { - $params = array_filter( - $matches, - fn($key) => !is_numeric($key), - ARRAY_FILTER_USE_KEY - ); - return array_merge($route, ['params' => $params]); - } - } - - throw new NotFoundHttpException(sprintf("No route found for: %s", $url)); - } - - /** - * Create an instance of the requested controller. - * - * @param string $controllerName - * @return object - * @throws \Core\Exceptions\Exceptions\NotFoundHttpException - */ - private function instantiateController(string $controllerName): object - { - if (!class_exists($controllerName)) { - throw new NotFoundHttpException(sprintf("Controller '%s' missing", $controllerName)); - } - - return new $controllerName($this->request); - } - - /** - * Validate that the action exists in the controller. - * - * @param object $controller - * @param string $actionName - * @return string - * @throws \Core\Exceptions\Exceptions\NotFoundHttpException - */ - private function validateActionExists(object $controller, string $actionName): string - { - if (!method_exists($controller, $actionName)) { - throw new NotFoundHttpException(sprintf("Method '%s' not found on '%s'", $actionName, get_class($controller))); - } - - return $actionName; - } - - /** - * Validate and resolve parameters for the controller action. - * - * @param object $controller - * @param string $action - * @param array $params - * @return array - * @throws \Exception - */ - private function resolveParameters(object $controller, string $action, array $params): array - { - return RouteValidator::resolve($controller, $action, $params); - } - - /** - * Execute the resolved action on the controller with validated parameters. - * - * @param object $controller - * @param string $action - * @param array $params - * @return void - */ - private function executeAction(object $controller, string $action, array $params): void - { - $response = $controller->$action(...$params); - - if ($response instanceof Render) { - $response->render(); - } - } - - /** - * Handle exceptions gracefully. - * - * @param Exception $e - * @param int $statusCode - * @param string $message - * @return void - */ - private function handleException(Exception $e, int $statusCode, string $message): void - { - if (Env::get('debug')) { - Exceptions::catchOne($e); - } - - http_response_code($statusCode); - echo $message; - } -} \ No newline at end of file diff --git a/src/Routing/RouteValidator.php b/src/Routing/RouteValidator.php deleted file mode 100644 index 2852407..0000000 --- a/src/Routing/RouteValidator.php +++ /dev/null @@ -1,89 +0,0 @@ -getParameters(); - $validatedParams = []; - - foreach ($methodParameters as $methodParameter) { - $paramName = $methodParameter->getName(); - $paramType = $methodParameter->getType(); - $isOptional = $methodParameter->isOptional(); - $defaultValue = $isOptional ? $methodParameter->getDefaultValue() : null; - - if (!array_key_exists($paramName, $params)) { - if ($isOptional) { - $validatedParams[$paramName] = $defaultValue; - continue; - } - throw new NotFoundHttpException(sprintf("Missing parameter '%s' for action '%s'", $paramName, $action)); - } - - $value = $params[$paramName]; - $validatedParams[$paramName] = self::validateType($paramName, $value, $paramType, $action); - } - - return $validatedParams; - } - - /** - * Validate and cast a parameter based on its type. - * - * @param string $paramName - * @param mixed $value - * @param ReflectionNamedType|null $paramType - * @param string $action - * @return mixed - * @throws \Core\Exceptions\Exceptions\NotFoundHttpException - */ - private static function validateType(string $paramName, mixed $value, ?ReflectionNamedType $paramType, string $action): mixed - { - if (!$paramType || $paramType->allowsNull() && $value === null) { - return $value; // No type or allows null, return as-is. - } - - $typeName = $paramType->getName(); - - switch ($typeName) { - case 'int': - if (!ctype_digit((string)$value)) { - throw new NotFoundHttpException(sprintf("Invalid type for parameter '%s'. Expected integer, got '%s'", $paramName, gettype($value))); - } - return (int)$value; - - case 'float': - if (!is_numeric($value)) { - throw new NotFoundHttpException(sprintf("Invalid type for parameter '%s'. Expected float, got '%s'", $paramName, gettype($value))); - } - return (float)$value; - - case 'string': - if (!is_string($value)) { - throw new NotFoundHttpException(sprintf("Invalid type for parameter '%s'. Expected string, got '%s'", $paramName, gettype($value))); - } - return $value; - - default: - throw new NotFoundHttpException(sprintf("Unsupported type '%s' for parameter '%s'", $typeName, $paramName)); - } - } -} \ No newline at end of file diff --git a/src/Routing/Router.php b/src/Routing/Router.php deleted file mode 100644 index 6d90c2a..0000000 --- a/src/Routing/Router.php +++ /dev/null @@ -1,22 +0,0 @@ -