From faf188c951770f1a8393d37db52fb2e105126726 Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 19 Aug 2025 00:36:03 -0400 Subject: [PATCH] provider --- src/classes/app.php | 52 ++++++++++------ src/classes/http/response.php | 4 ++ src/classes/http/route_service_provider.php | 69 +++++++++++++++++++++ src/classes/page_not_found.php | 11 ++-- src/classes/router.php | 5 +- 5 files changed, 116 insertions(+), 25 deletions(-) create mode 100644 src/classes/http/route_service_provider.php diff --git a/src/classes/app.php b/src/classes/app.php index 9ab4aaa..b607bf8 100644 --- a/src/classes/app.php +++ b/src/classes/app.php @@ -26,7 +26,7 @@ class app { $offset = strlen($route) - $dot_position; $ext = common::get_string_right($route, $offset); if ($ext === ".php") { - $this->local404(); + return $this->local404(); } return substr($route, 0, $dot_position); } @@ -48,7 +48,7 @@ class app { /** * Do not declare a return type here, as it will Error out!! */ - public function __construct() { + public function __construct(private Request $request, private Response $response) { $full_route = bootstrap\site_helper::get_route(); $no_file_ext = $this->get_without_file_extension($full_route); @@ -91,26 +91,26 @@ class app { try { $filtered_uri = security::filter_uri($uri); } catch (Exception $ex) { - $this->local404(); // Route Un-Safe URI to Local 404 Page + return $this->local404(); // Route Un-Safe URI to Local 404 Page } $safe_folders = bootstrap\requires::filter_dir_path( $this->get_first_chunks($filtered_uri) ); if (bootstrap\requires::is_dangerous($safe_folders)) { - $this->local404(); + return $this->local404(); } $safe_folders = rtrim($safe_folders, '/'); if (empty($ROOT)) { - $this->local404(); + return $this->local404(); } $safe_file = bootstrap\requires::filter_dir_path( $this->get_last_part($filtered_uri) ); if (bootstrap\requires::is_dangerous($safe_file)) { - $this->local404(); + return $this->local404(); } $test = $this->get_ctrl_dir(); @@ -118,13 +118,13 @@ class app { //check for default site controller first if ($dir === false) { - $this->local404(); + return $this->local404(); } else { $file = bootstrap\requires::safer_file_exists(basename($safe_file) . '_ctrl.php', $dir); if ($file !== false) { $class = security::filter_class($safe_folders) . "\\" . security::filter_class($safe_file . "_ctrl"); } else { - $this->local404(); + return $this->local404(); } } @@ -146,8 +146,11 @@ class app { } } - private function local404() { - page_not_found::error404(); + private function local404(): string { + $this->response->set_status_code(404); + $content = page_not_found::error404(); + $this->response->set_content($content); + return $this->response; } /** @@ -157,20 +160,23 @@ class app { * @param string $method * @retval type */ - private function action(Request $request, Response $response, string $file, string $class, string $method, $params) { + private function action(string $file, string $class, string $method, $params) { $safer_file = bootstrap\requires::safer_file_exists($file); if (! $safer_file) { - $this->local404(); + return ['data'=>$this->local404()]; } if (empty($class)) { - $this->local404(); + return ['data'=>$this->local404()]; } $use_api = misc::is_api(); $test = $this->get_ctrl_dir(); $call_class = "\\Project\\" . $test . 'controllers\\' . $class; - $controller = new $call_class($request, $response); + $controller = new $call_class($this->request, $this->response); + + // Collect controller-level middleware + $controller_middleware = $controller::$middleware ?? []; if ($method === "error" && str_contains($class, "app") && method_exists($controller, $method) === false @@ -185,18 +191,24 @@ class app { } $method .= "_api"; if (method_exists($controller, $method)) { - return $controller->$method($params); + return [ + 'data'=>$controller->$method($params), 'middleware'=>$controller_middleware + ]; } else { page_not_found::error404_cli(); } } else { if (!empty($method) && method_exists($controller, $method)) { - return $controller->$method($params); + return [ + 'data'=>$controller->$method($params), 'middleware'=>$controller_middleware + ]; } else { if (empty($method) && method_exists($controller, 'index')) { - return $controller->index($params); + return [ + 'data'=>$controller->index($params), 'middleware'=>$controller_middleware + ]; } else { - $this->local404(); + return ['data'=>$this->local404()]; } } } @@ -205,8 +217,8 @@ class app { /** * Does load controller by calling action */ - public function load_controller(Request $request, Response $response) { - return $this->action($request, $response, $this->file, $this->class, $this->method, $this->params); + public function load_controller() { + return $this->action($this->file, $this->class, $this->method, $this->params); } } // end of app diff --git a/src/classes/http/response.php b/src/classes/http/response.php index f91b227..789742d 100644 --- a/src/classes/http/response.php +++ b/src/classes/http/response.php @@ -35,6 +35,10 @@ class response echo $this->content; } + public function get_content(): string { + return $this->content; + } + public function set_content(string $content): self { $this->content = $content; return $this; diff --git a/src/classes/http/route_service_provider.php b/src/classes/http/route_service_provider.php new file mode 100644 index 0000000..3ff7c9b --- /dev/null +++ b/src/classes/http/route_service_provider.php @@ -0,0 +1,69 @@ + + * @copyright (c) 2025, Robert Strutts + * @license MIT + */ + +namespace CodeHydrater\http; + +use \CodeHydrater\http\service_provider as ServiceProvider; +use \CodeHydrater\http\kernel as Kernel; +use \CodeHydrater\http\request as Request; +use \CodeHydrater\http\response as Response; +use \CodeHydrater\router as Router; +use \CodeHydrater\app as App; + +/** + * Description of route_service_provider + * Setup Router and Controllers + * + * @author Robert Strutts + */ +class route_service_provider extends ServiceProvider { + + protected Kernel $kernel; + + public function __construct(Kernel $kernel) { + $this->kernel = $kernel; + } + + private function build($handler, $response, $request, $next, $controller_middleware) { + // Build middleware stack + $middleware_stack = array_reduce( + array_reverse($controller_middleware), + function ($next, $middleware) { + return function ($request, $response) use ($next, $middleware) { + if ($middleware !== null ) { + $instance = new $middleware(); + return $instance($request, $response, $next); + } + }; + }, + function ($request, $response) use ($handler) { + $response->set_content($handler->get_content()); + return $response; + } + ); + return $middleware_stack($request, $response); + } + + public function register(): void { + // Add router middleware + $this->kernel->add_middleware(function (Request $request, Response $response, $next) { + $returned_route = Router::execute($request, $response); + if ($returned_route["found"] === false) { + $app = new App($request, $response); + $returned = $app->load_controller(); + $a_middleware = $returned['middleware'] ?? []; + $data = $returned['data'] ?? ""; + return $this->build($data, $response, $request, $next, $a_middleware); + } else { + return $this->build($returned_route['returned'], $response, $request, $next, $returned_route['middleware']); + } + }); + } +} diff --git a/src/classes/page_not_found.php b/src/classes/page_not_found.php index 12892fb..08f377c 100644 --- a/src/classes/page_not_found.php +++ b/src/classes/page_not_found.php @@ -37,7 +37,7 @@ class page_not_found { /** * Displays 404 Page not Found */ - public static function error404(): void { + public static function error404(): string { if (console_app::is_cli()) { self::error404_cli(); } else { @@ -47,14 +47,17 @@ class page_not_found { if ($use_api === true) { self::api_method_not_found(); } + + $loadA = bootstrap\requires::secure_include('404_page.php', bootstrap\UseDir::ONERROR); // Show 404, Page Not Found Error Page! - if (bootstrap\requires::secure_include('404_page.php', bootstrap\UseDir::ONERROR) === false) { + if ($loadA === false) { $loaded = bootstrap\requires::secure_include('views/on_error/404_page.php', bootstrap\UseDir::FRAMEWORK); if ($loaded === false) { - echo "

404 Page Not Found!

"; + return "

404 Page Not Found!

"; } + return $loaded; } - exit(1); + return $loadA; } /** diff --git a/src/classes/router.php b/src/classes/router.php index 6b5b7a4..90df4bc 100644 --- a/src/classes/router.php +++ b/src/classes/router.php @@ -431,6 +431,9 @@ class router // init new controller $controller = new $controller($my_request, $my_response); + // Collect controller-level middleware + $controller_middleware = $controller::$middleware ?? []; + // Check if class has parent $parentControllers = class_parents($controller); if (!empty($parentControllers)) { @@ -447,7 +450,7 @@ class router //Call method if (method_exists($controller, $method)) { $returned = call_user_func_array([$controller, $method], $params); - return ["found"=> true, "returned"=> $returned]; + return ["found"=> true, "returned"=> $returned, "middleware"=>$controller_middlewares]; } } }