- 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
1 changed files with 52 additions and 60 deletions

View File

@ -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 '<h2 style="text-align: center;margin: 25px 0px;">Error 404 - Página no encontrada</h2>';
};
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 '<h2 style="text-align: center;margin: 25px 0px;">Error 404 - Página no encontrada</h2>';
}
// Si no hay router que coincida llamamos a $notFoundCallBack
call_user_func_array(static::$notFoundCallBack, [$req]);
}
}
?>