diff --git a/src/Libs/Router.php b/src/Libs/Router.php index f88d4e7..981a9e3 100644 --- a/src/Libs/Router.php +++ b/src/Libs/Router.php @@ -19,7 +19,10 @@ class Router { private static $put = []; private static $delete = []; private static $last; - public static $notFoundCallBack; + public static $notFoundCallBack = function () { + header("HTTP/1.0 404 Not Found"); + echo '

Error 404 - Página no encontrada

'; + }; private function __construct() {} @@ -38,6 +41,9 @@ class Router { * callback - Contiene el callback en formato Namespace\Clase::Método */ private static function parse($path, $callback) { + preg_match_all('/{([\w-]+)}/s', $path, $matches, PREG_PATTERN_ORDER); + $paramNames = $matches[1]; + $path = preg_quote($path, '/'); $path = preg_replace( ['/\\\{[\w-]+\\\}/s'], @@ -47,9 +53,11 @@ class Router { if (!is_callable($callback)) { $callback = 'Controllers\\'.$callback; } + return [ - 'path'=> $path, - 'callback' => $callback + 'path' => $path, + 'callback' => $callback, + 'paramNames' => $paramNames ]; } @@ -63,7 +71,7 @@ class Router { public static function baseURI() { if (defined('SITE_URL')) return parse_url(SITE_URL, PHP_URL_PATH); - return str_replace($_SERVER['DOCUMENT_ROOT'],'/', ROOT_DIR); + return str_replace($_SERVER['DOCUMENT_ROOT'], '/', ROOT_DIR); } /* @@ -83,14 +91,26 @@ class Router { /* * Añade un middleware a la última ruta usada. * Solo se puede usar un middleware a la vez. + * + * @param string $callback + * + * @return static + * Devuelve un enlace estático */ - public static function middleware($middleware){ - if (!isset(static::$last)) return; + public static function middleware($callback){ + if (!isset(static::$last)) + return; $method = static::$last[0]; $index = static::$last[1]; - static::$$method[$index]['middleware'] = 'Middlewares\\'.$middleware; + if (!is_callable($callback)) { + $callback = 'Middlewares\\'.$callback; + } + + static::$$method[$index]['middleware'] = $callback; + + return new static(); } /* @@ -106,6 +126,7 @@ class Router { $req->get = new Neuron($_GET); $req->post = new Neuron($_POST); $req->json = new Neuron(static::get_json()); + $req->params = new Neuron(); $req->path = static::URIPath(); return $req; } @@ -208,37 +229,19 @@ class Router { * * 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, - * pueden suecedor los siguientes casos: + * En caso que la URI actual coincida con un router configurado, se comprueba si hay middleware; Si hay + * middleware, se enviará el callback y los datos de la petición como un Neuron. Caso contrario, se enviarán + * los datos directamente al callback. * - * 1. Tiene pseudovariables por URI + * Con middleware: + * $middleware($callback, $req) * - * 1.1. Tiene middleware, por lo que se llama al middleware enviándole los datos - * en el siguiente orden: - * - Función callback del router - * - Objeto que contiene $_POST, $_GET y el JSON recibido - * - Todas las pseudovariables (en el mismo orden que están escritas) + * Sin middleware: + * $callback($req) * - * 1.1. No tiene middleware, por lo que se llama a la función callback del 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 + * $req es una instancia de Neuron que tiene los datos de la petición. * - * 2. No tiene pseudovariables por URI - * - * 2.1. Tiene middleware, por lo que se llama al middleware enviándole los datos - * En el siguiente orden: - * - Función callback del router - * - Todas las pseudovariables (en el mismo orden que están escritas) - * - * 2.2. No tiene middleware, por lo que se llama a la función callback del router - * enviándole solo ún parámetro: - * - Objeto que contiene $_POST, $_GET y el JSON recibido - * - * Nota: Gracias a que se usa call_user_func_array, los callbacks no es necesario que reciban - * la misma cantidad de parámetros que se les envía. De ese modo, pueden recibir solo - * los parámetros que van a utilizar, con el detalle de que siempre se respeta el orden - * especificado anteriormente a la hora de recibirlos. + * Si no la uri no coincide con ninguna de las */ public static function apply() { $uri = static::URIPath(); @@ -259,31 +262,24 @@ class Router { } 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)){ + if (preg_match_all('/^'.$router['path'].'\/?$/si',$uri, $matches, PREG_PATTERN_ORDER)) { 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]"; + // Comprobando pseudo variables en URI + if (isset($matches[1])) { + foreach ($matches as $index => $match) { + $paramName = $router['paramNames'][$index-1]; + $args->params->$paramName = urldecode($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); - } - } else { // Caso 2 - Sin Pseudo variables por URI - if (isset($router['middleware'])) { // Caso 2.1 - Con middleware - $middleware = explode('::',$router['middleware']); - $data = call_user_func_array($middleware, [$router['callback'], $args]); - } else { // Caso 2.2 - Sin middleware - $data = call_user_func_array($router['callback'], [$args]); - } + // Comprobando si hay middleware + if (isset($router['middleware'])) { + //$middleware = explode('::',$router['middleware']); + $data = call_user_func_array($router['middleware'], [$router['callback'], $args]); + } else { + $data = call_user_func_array($router['callback'], [$args]); } if (isset($data)) { @@ -295,12 +291,8 @@ class Router { } } - 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

'; - } + // Si no hay router que coincida llamamos a $notFoundCallBack + call_user_func_array(static::$notFoundCallBack, [$req]); } } ?>