diff --git a/app/Application.php b/app/Application.php new file mode 100644 index 0000000..46d8c93 --- /dev/null +++ b/app/Application.php @@ -0,0 +1,14 @@ +handle(); \ No newline at end of file diff --git a/src/Bootstrap.php b/src/Bootstrap.php new file mode 100644 index 0000000..f434d27 --- /dev/null +++ b/src/Bootstrap.php @@ -0,0 +1,45 @@ +run(); + + return Bootstrap::getInstance(); + } + + /** + * Get the instance + * + * @return \Core\Factory\BootstrapFactory + */ + public static function getInstance(): BootstrapFactory + { + return self::$instance; + } + + /** + * Create new factory instance + * + * @return \Core\Factory\BootstrapFactory + */ + protected function run(): BootstrapFactory + { + return new BootstrapFactory(); + } +} \ No newline at end of file diff --git a/src/Exceptions/Exceptions.php b/src/Exceptions/ExceptionHandler.php similarity index 63% rename from src/Exceptions/Exceptions.php rename to src/Exceptions/ExceptionHandler.php index ec0f033..77f5355 100644 --- a/src/Exceptions/Exceptions.php +++ b/src/Exceptions/ExceptionHandler.php @@ -2,7 +2,6 @@ namespace Core\Exceptions; -use Core\Env\Env; use Core\Http\Request; use Throwable; use Whoops\Handler\Handler; @@ -11,7 +10,7 @@ use Whoops\Handler\PlainTextHandler; use Whoops\Handler\PrettyPageHandler; use Whoops\Run as Whoops; -class Exceptions +class ExceptionHandler { /** * Exceptions handler instance @@ -41,13 +40,12 @@ class Exceptions /** * Get correct handler * - * @param \Core\Http\Request|null $request * @return \Whoops\Handler\Handler */ - private static function handler(Request|null $request): Handler + private static function handler(): Handler { - if (Env::get('debug')) { - if ($request?->is('post')) { + if (env('debug')) { + if (request()?->is('post')) { return new JsonResponseHandler(); } @@ -60,24 +58,44 @@ class Exceptions /** * Catch all exceptions * - * @param \Core\Http\Request $request * @return void */ - public static function catch(Request $request): void + public static function catch(): void { - self::instance($request)->register(); + self::instance()->register(); } /** * Catch single exception * * @param \Throwable $exception - * @return void + * @return never */ - public static function catchOne(Throwable $exception): void + public static function catchOne(Throwable $exception): never { self::instance()->handleException($exception); exit(0); } + + /** + * Make new exception + * + * @param null $abstract + * @param string|null $message + * @return never + */ + public static function make(mixed $abstract = null, string|null $message = null): never + { + if(is_string($abstract)) { + $abstract = app()->make($abstract, $message); + } + + if(is_subclass_of($abstract, 'Exception')) { + self::catchOne($abstract); + } + + exit(0); + } + } \ No newline at end of file diff --git a/src/Exceptions/Exceptions/ClassNotFoundException.php b/src/Exceptions/Exceptions/ClassNotFoundException.php new file mode 100644 index 0000000..494b2b4 --- /dev/null +++ b/src/Exceptions/Exceptions/ClassNotFoundException.php @@ -0,0 +1,5 @@ +request = app()->make(Request::class, [$_POST + $_FILES]); + + // Capture all exceptions + ExceptionHandler::catch(); + + // Load routes + require '../config/routes.php'; + + try { + // Boot application + app()->make(Application::class)->bootstrap(); + + // Dispatch router + app()->make(RouteDispatcher::class)->dispatch($this->request, RouteCollection::retrieve()); + } catch (\Exception $e) { + ExceptionHandler::catchOne($e); + } + } + + /** + * @param string $abstract + * @param array $arguments + * @return mixed + */ + public function make(string $abstract, mixed $arguments = []): mixed + { + return $this->resolve($abstract, $arguments); + } + + /** + * @param string $abstract + * @param array $arguments + * @return mixed|null + */ + private function resolve(string $abstract, mixed $arguments = []): mixed + { + if (class_exists($abstract)) { + try { + $reflection = new \ReflectionClass($abstract); + return $reflection->newInstanceArgs($arguments); + } catch (\ReflectionException $e) { + ExceptionHandler::catchOne($e); + } + } + + ExceptionHandler::make(ClassNotFoundException::class, sprintf("Class '%s' not found", $abstract)); + } + + /** + * Get the request instance + * + * @return \Core\Http\Request + */ + public function request(): Request + { + return $this->request; + } + + /** + * Get path to file/folder in resources folder + * + * @param string $path + * @return string + */ + public function resourcePath(string $path = ''): string + { + return "../resources/" . $path; + } +} \ No newline at end of file diff --git a/src/Helpers/helpers.php b/src/Helpers/helpers.php new file mode 100644 index 0000000..9d3c5c4 --- /dev/null +++ b/src/Helpers/helpers.php @@ -0,0 +1,51 @@ +make($abstract, $arguments); + } +} + +if(!function_exists('env')) +{ + /** + * Get env variable + * + * @param string $key + * @return bool + */ + function env(string $key): mixed + { + return Env::get($key); + } +} + +if (!function_exists('request')) { + /** + * Get the request instance + * + * @return \Core\Http\Request + */ + function request(): Request + { + return app()->request(); + } +} diff --git a/src/Controllers/Controller.php b/src/Http/Controllers/Controller.php similarity index 93% rename from src/Controllers/Controller.php rename to src/Http/Controllers/Controller.php index e8f1cec..d428fcd 100644 --- a/src/Controllers/Controller.php +++ b/src/Http/Controllers/Controller.php @@ -1,6 +1,6 @@ data = $data; - - // Capture all exceptions - Exceptions::catch($this); } /** diff --git a/src/Http/Response.php b/src/Http/Response.php index 99d4fcb..bb5d38d 100644 --- a/src/Http/Response.php +++ b/src/Http/Response.php @@ -2,9 +2,9 @@ namespace Core\Http; -use Core\View\Render; -use Core\View\Render\HtmlRender; -use Core\View\Render\JsonRender; +use Core\Http\View\Engine\HtmlEngine; +use Core\Http\View\Engine\JsonEngine; +use Core\Http\View\Render; class Response { @@ -25,20 +25,20 @@ class Response * Render HTML * * @param string $view - * @return \Core\View\Render + * @return \Core\Http\View\Render */ public function view(string $view): Render { - return (new HtmlRender())->view($view); + return (new HtmlEngine())->view($view); } /** * Render JSON * - * @return \Core\View\Render + * @return \Core\Http\View\Render */ public function json(): Render { - return new JsonRender(); + return new JsonEngine(); } } \ No newline at end of file diff --git a/src/View/Render/HtmlRender.php b/src/Http/View/Engine/HtmlEngine.php similarity index 64% rename from src/View/Render/HtmlRender.php rename to src/Http/View/Engine/HtmlEngine.php index e0a53d7..c094be6 100644 --- a/src/View/Render/HtmlRender.php +++ b/src/Http/View/Engine/HtmlEngine.php @@ -1,10 +1,10 @@ view) . '.php'; + $viewsPath = app()->resourcePath('views/' . str_replace('.', '/', $this->view) . '.php'); if (file_exists($viewsPath)) { extract($this->data); diff --git a/src/View/Render/JsonRender.php b/src/Http/View/Engine/JsonEngine.php similarity index 70% rename from src/View/Render/JsonRender.php rename to src/Http/View/Engine/JsonEngine.php index 3dc68b5..f97d63c 100644 --- a/src/View/Render/JsonRender.php +++ b/src/Http/View/Engine/JsonEngine.php @@ -1,10 +1,11 @@ request = $request; $this->routeCollection = $routeCollection; @@ -48,18 +50,6 @@ class RouteDispatcher } } - /** - * Dispatch the router dispatcher - * - * @param \Core\Http\Request $request - * @param array $routeCollection - * @return void - */ - public static function dispatch(Request $request, array $routeCollection): void - { - new self($request, $routeCollection); - } - /** * Locate a matching route for the incoming request. * @@ -153,8 +143,8 @@ class RouteDispatcher */ private function handleException(Exception $e, int $statusCode, string $message): void { - if (Env::get('debug')) { - Exceptions::catchOne($e); + if (env('debug')) { + ExceptionHandler::catchOne($e); } http_response_code($statusCode);