From d23ecfbde661d899e69308573cca2681fd8480e0 Mon Sep 17 00:00:00 2001 From: kj Date: Thu, 25 Mar 2021 12:02:50 -0400 Subject: [PATCH] Add a 404 custom controller option on Router. --- src/Libs/Router.php | 64 +++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/src/Libs/Router.php b/src/Libs/Router.php index f1d7fa5..9620127 100644 --- a/src/Libs/Router.php +++ b/src/Libs/Router.php @@ -2,7 +2,7 @@ /* * DuckBrain - Microframework * -* Librería de Enrrutador. +* Librería de Enrrutador. * Depende de manera forzada de que la constante ROOT_DIR esté definida * y de manera optativa de que la constante SITE_URL lo esté también. * @@ -21,9 +21,10 @@ class Router { private static $put = []; private static $delete = []; private static $last; - + public static $notFoundCallBack; + private function __construct() {} - + /* * Parsea para deectar las pseudovariables (ej: {variable}) * @@ -44,7 +45,7 @@ class Router { ['/\\\{[\w-]+\\\}/s'], ['([^\/]+)'], $path); - + if (!is_callable($callback)) { $callback = 'Controllers\\'.$callback; } @@ -53,20 +54,20 @@ class Router { 'callback' => $callback ]; } - - + + /* * Devuelve el path o URI base sobre la que trabajará el router. * * Ej: Si la url del sistema está en "https://ejemplo.com/duckbrain" - * entonces la URI base sería "/duckbrain" + * entonces la URI base sería "/duckbrain" */ public static function baseURI() { if (defined('SITE_URL')) return parse_url(SITE_URL, PHP_URL_PATH); return str_replace($_SERVER['DOCUMENT_ROOT'],'/', ROOT_DIR); } - + /* * Redirije a una ruta relativa interna. * @@ -80,20 +81,20 @@ class Router { public static function redirect($uri) { header('Location: '.static::baseURI().substr($uri,1)); } - + /* * Añade un middleware a la última ruta usada. * Solo se puede usar un middleware a la vez. */ public static function middleware($middleware){ if (!isset(static::$last)) return; - + $method = static::$last[0]; $index = static::$last[1]; - + static::$$method[$index]['middleware'] = 'Middlewares\\'.$middleware; } - + /* * @return object * Devuelve un objeto que contiene los atributos: @@ -110,7 +111,7 @@ class Router { $req->path = static::URIPath(); return $req; } - + /* * @return object * Devuelve un objeto con los datos recibidos en JSON @@ -122,7 +123,7 @@ class Router { } return (object) ''; } - + /* * Define los routers para el método GET. * @@ -140,7 +141,7 @@ class Router { static::$last = ['get', count(static::$get)-1]; return new static(); } - + /* * Define los routers para el método POST. * @@ -171,13 +172,13 @@ class Router { * @return static * Devuelve un enlace estático */ - + public static function put($path, $callback) { static::$put[] = static::parse($path, $callback); static::$last = ['put', count(static::$put)-1]; return new static(); } - + /* * Define los routers para el método DELETE. * @@ -195,7 +196,7 @@ class Router { static::$last = ['delete', count(static::$delete)-1]; return new static(); } - + /* * Devuelve el URI path actual */ @@ -203,10 +204,10 @@ class Router { return preg_replace('/'.preg_quote(static::baseURI(), '/').'/', '/', strtok($_SERVER['REQUEST_URI'], '?'), 1); } - + /* * Aplica los routers. - * + * * Este método ha de ser llamado luego de que todos los routers hayan sido configurados. * * En caso que la URI actual coincida con un router configurado, @@ -224,7 +225,7 @@ class Router { * enviándole los datos en el siguiente orden: * - Todas las pseudovariables (en el mismo orden que están escritas) * - Objeto que contiene $_POST, $_GET y el JSON recibido - * + * * 2. No tiene pseudovariables por URI * * 2.1. Tiene middleware, por lo que se llama al middleware enviándole los datos @@ -258,25 +259,25 @@ class Router { $routers = static::$get; break; } - + foreach ($routers as $router) { // revisa todos los routers para ver si coinciden con la URI actual if (preg_match_all('/^'.$router['path'].'\/?$/si',$uri, $matches)){ unset($matches[0]); $args = static::getReq(); - + if (isset($matches[1])) { // Caso 1 - Con pseudovariables por URI $params = []; foreach ($matches as $match) { if (!empty($match)) $params[] = "$match[0]"; } - + if (isset($router['middleware'])) { // Caso 1.1 - Con middleware $middleware = explode('::',$router['middleware']); $data = call_user_func_array($middleware, [$router['callback'], $args, $params]); } else { // Caso 1.2 - Sin middleware $params[] = $args; - $data = call_user_func_array($router['callback'], $params); + $data = call_user_func_array($router['callback'], $params); } } else { // Caso 2 - Sin Pseudo variables por URI if (isset($router['middleware'])) { // Caso 2.1 - Con middleware @@ -286,17 +287,22 @@ class Router { $data = call_user_func_array($router['callback'], [$args]); } } - + if (isset($data)) { header('Content-Type: application/json'); print(json_encode($data)); } - + return; } } - header("HTTP/1.0 404 Not Found"); // Si no hay router que coincida, se devuelve error 404 - echo '

Error 404 - Página no encontrada

'; + + if (isset(static::$notFoundCallBack)) + call_user_func_array(static::$notFoundCallBack, []); + else { + header("HTTP/1.0 404 Not Found"); // Si no hay router que coincida, se devuelve error 404 + echo '

Error 404 - Página no encontrada

'; + } } } ?>