- Change middleware for accept any callable function as param.

- $notFoundCallback now has a function as default value (the normal 404 page as before).
- Change the way to manipulate the {pseudoVars} on uri, now it go into the same Neuron onject that "post", "get", and "json" and not more as separate params into the callback (the callback now only receive one param by default).
- $notFoundCallback now receive the $req, as param.
This commit is contained in:
kj 2021-10-15 17:23:20 -04:00
parent 68bc906ecf
commit e1fe93a04c

View File

@ -19,7 +19,10 @@ class Router {
private static $put = []; private static $put = [];
private static $delete = []; private static $delete = [];
private static $last; private static $last;
public static $notFoundCallBack; public static $notFoundCallBack = function () {
header("HTTP/1.0 404 Not Found");
echo '<h2 style="text-align: center;margin: 25px 0px;">Error 404 - Página no encontrada</h2>';
};
private function __construct() {} private function __construct() {}
@ -38,6 +41,9 @@ class Router {
* callback - Contiene el callback en formato Namespace\Clase::Método * callback - Contiene el callback en formato Namespace\Clase::Método
*/ */
private static function parse($path, $callback) { 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_quote($path, '/');
$path = preg_replace( $path = preg_replace(
['/\\\{[\w-]+\\\}/s'], ['/\\\{[\w-]+\\\}/s'],
@ -47,9 +53,11 @@ class Router {
if (!is_callable($callback)) { if (!is_callable($callback)) {
$callback = 'Controllers\\'.$callback; $callback = 'Controllers\\'.$callback;
} }
return [ return [
'path'=> $path, 'path' => $path,
'callback' => $callback 'callback' => $callback,
'paramNames' => $paramNames
]; ];
} }
@ -63,7 +71,7 @@ class Router {
public static function baseURI() { public static function baseURI() {
if (defined('SITE_URL')) if (defined('SITE_URL'))
return parse_url(SITE_URL, PHP_URL_PATH); 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. * Añade un middleware a la última ruta usada.
* Solo se puede usar un middleware a la vez. * Solo se puede usar un middleware a la vez.
*
* @param string $callback
*
* @return static
* Devuelve un enlace estático
*/ */
public static function middleware($middleware){ public static function middleware($callback){
if (!isset(static::$last)) return; if (!isset(static::$last))
return;
$method = static::$last[0]; $method = static::$last[0];
$index = static::$last[1]; $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->get = new Neuron($_GET);
$req->post = new Neuron($_POST); $req->post = new Neuron($_POST);
$req->json = new Neuron(static::get_json()); $req->json = new Neuron(static::get_json());
$req->params = new Neuron();
$req->path = static::URIPath(); $req->path = static::URIPath();
return $req; return $req;
} }
@ -208,37 +229,19 @@ class Router {
* *
* Este método ha de ser llamado luego de que todos los routers hayan sido configurados. * 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, * En caso que la URI actual coincida con un router configurado, se comprueba si hay middleware; Si hay
* pueden suecedor los siguientes casos: * 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 * Sin middleware:
* en el siguiente orden: * $callback($req)
* - 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)
* *
* 1.1. No tiene middleware, por lo que se llama a la función callback del router * $req es una instancia de Neuron que tiene los datos de la petición.
* 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 * Si no la uri no coincide con ninguna de las
*
* 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.
*/ */
public static function apply() { public static function apply() {
$uri = static::URIPath(); $uri = static::URIPath();
@ -259,32 +262,25 @@ class Router {
} }
foreach ($routers as $router) { // revisa todos los routers para ver si coinciden con la URI actual 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]); unset($matches[0]);
$args = static::getReq(); $args = static::getReq();
if (isset($matches[1])) { // Caso 1 - Con pseudovariables por URI // Comprobando pseudo variables en URI
$params = []; if (isset($matches[1])) {
foreach ($matches as $match) { foreach ($matches as $index => $match) {
if (!empty($match)) $paramName = $router['paramNames'][$index-1];
$params[] = "$match[0]"; $args->params->$paramName = urldecode($match[0]);
}
} }
if (isset($router['middleware'])) { // Caso 1.1 - Con middleware // Comprobando si hay middleware
$middleware = explode('::',$router['middleware']); if (isset($router['middleware'])) {
$data = call_user_func_array($middleware, [$router['callback'], $args, $params]); //$middleware = explode('::',$router['middleware']);
} else { // Caso 1.2 - Sin middleware $data = call_user_func_array($router['middleware'], [$router['callback'], $args]);
$params[] = $args; } else {
$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]); $data = call_user_func_array($router['callback'], [$args]);
} }
}
if (isset($data)) { if (isset($data)) {
header('Content-Type: application/json'); header('Content-Type: application/json');
@ -295,12 +291,8 @@ class Router {
} }
} }
if (isset(static::$notFoundCallBack)) // Si no hay router que coincida llamamos a $notFoundCallBack
call_user_func_array(static::$notFoundCallBack, []); call_user_func_array(static::$notFoundCallBack, [$req]);
else {
header("HTTP/1.0 404 Not Found"); // Si no hay router que coincida, se devuelve error 404
echo '<h2 style="text-align: center;margin: 25px 0px;">Error 404 - Página no encontrada</h2>';
}
} }
} }
?> ?>