Compare commits
89
Commits
6b470a181d
..
v0.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b6da45b01 | ||
|
|
b7260b5199 | ||
|
|
1f29622914 | ||
|
|
eb882db0c8 | ||
|
|
9ba43e3f25 | ||
|
|
54e96ba4bb | ||
|
|
9027f36748 | ||
|
|
2ae9ef39f3 | ||
|
|
ee0db0307e | ||
|
|
44cbe6bbdc | ||
|
|
31728af351 | ||
|
|
4845d14ef5 | ||
|
|
aca4e732ed | ||
|
|
f475c9125f | ||
|
|
4fe7314389 | ||
|
|
1f366830bc | ||
|
|
15df7c8d96 | ||
|
|
b8dd1fd0f6 | ||
|
|
83c80bd4ab | ||
|
|
b13c07d3c4 | ||
|
|
b95747bfe0 | ||
|
|
01c5eceeb4 | ||
|
|
ee9c109ed9 | ||
|
|
7eed69725d | ||
|
|
e37035eed8 | ||
|
|
5312e5060e | ||
|
|
3c9db3ac53 | ||
|
|
2b5d19ecd5 | ||
|
|
53e862d126 | ||
|
|
b6baeef32f | ||
|
|
159da01d5c | ||
|
|
3770dd6d9b | ||
|
|
76a69e5ef8 | ||
|
|
c5a4967ae4 | ||
|
|
c0b9f3851a | ||
|
|
78e199e300 | ||
|
|
8cd5e114dd | ||
|
|
ce03bdb27d | ||
|
|
b24598b118 | ||
|
|
5019b89cc0 | ||
|
|
d030e8d30e | ||
|
|
b2672ad92f | ||
|
|
4c57770b43 | ||
|
|
8e84450f95 | ||
|
|
ece32b9bbe | ||
|
|
a5cf9d239d | ||
|
|
b9509c49ed | ||
|
|
6e433b4d06 | ||
|
|
892b3614ec | ||
|
|
a0b544eae5 | ||
|
|
20fd78ab53 | ||
|
|
f5411daaa5 | ||
|
|
7e7ec68fd7 | ||
|
|
ac9a661bc0 | ||
|
|
c8d7b69367 | ||
|
|
7f62e06ff9 | ||
|
|
674c9d5ff4 | ||
|
|
2f50532e13 | ||
|
|
b41514a491 | ||
|
|
a1a15f492c | ||
|
|
b19e7d8789 | ||
|
|
4dfdb52519 | ||
|
|
b0891885f9 | ||
|
|
b282d5479f | ||
|
|
c9f467345b | ||
|
|
0f46848d15 | ||
|
|
b2cb8d6883 | ||
|
|
e9126e7cde | ||
|
|
7169d2cae3 | ||
|
|
66b2bc0d91 | ||
|
|
c8ab2aa2cc | ||
|
|
1e302a9ea7 | ||
|
|
d0d0d4dc76 | ||
|
|
595e9c1316 | ||
|
|
45abea5301 | ||
|
|
d441f001ec | ||
|
|
19da122e05 | ||
|
|
1a0164c8ed | ||
|
|
ad9f8ec67d | ||
|
|
31c5c63952 | ||
|
|
6aef212350 | ||
|
|
c600688725 | ||
|
|
3e27b1b7af | ||
|
|
73b7b8f72a | ||
|
|
7baad428ec | ||
|
|
3d2a607768 | ||
|
|
df424ffab5 | ||
|
|
daf7250882 | ||
|
|
05cd83fd10 |
@@ -1,6 +1,9 @@
|
|||||||
<IfModule mod_rewrite.c>
|
<IfModule mod_rewrite.c>
|
||||||
RewriteEngine On
|
RewriteEngine On
|
||||||
|
|
||||||
|
# Bloquear acceso a las carpetas vendor/ y src/
|
||||||
|
RewriteRule ^(vendor|src)/.*$ - [F,L]
|
||||||
|
|
||||||
# Handle Front Controller...
|
# Handle Front Controller...
|
||||||
RewriteCond %{REQUEST_FILENAME} !-d
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
RewriteCond %{REQUEST_FILENAME} !-f
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once('config.php');
|
||||||
|
|
||||||
|
// Autoloader for the core classes
|
||||||
|
spl_autoload_register(function ($className) {
|
||||||
|
$fp = str_replace('\\', '/', $className);
|
||||||
|
$name = basename($fp);
|
||||||
|
$dir = dirname($fp);
|
||||||
|
$file = ROOT_CORE . '/' . $dir . '/' . $name . '.php';
|
||||||
|
if (file_exists($file)) {
|
||||||
|
require_once $file;
|
||||||
|
}
|
||||||
|
});
|
||||||
+5
-4
@@ -1,14 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
// Configuración de la base de datos
|
|
||||||
|
// Database configuration
|
||||||
define('DB_TYPE', 'mysql');
|
define('DB_TYPE', 'mysql');
|
||||||
define('DB_HOST', 'localhost');
|
define('DB_HOST', 'localhost');
|
||||||
define('DB_NAME', '');
|
define('DB_NAME', '');
|
||||||
define('DB_USER', '');
|
define('DB_USER', '');
|
||||||
define('DB_PASS', '');
|
define('DB_PASS', '');
|
||||||
|
|
||||||
// Configuración del sitio
|
// Site configuration
|
||||||
define('SITE_URL', '');
|
define('SITE_URL', '');
|
||||||
|
|
||||||
// Configuración avanzada
|
// Advanced configuration
|
||||||
define('ROOT_DIR', __DIR__);
|
define('ROOT_DIR', __DIR__);
|
||||||
define('ROOT_CORE', ROOT_DIR.'/src');
|
define('ROOT_CORE', ROOT_DIR . '/src');
|
||||||
|
|||||||
@@ -1,24 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once('config.php');
|
|
||||||
|
|
||||||
// Incluir clases
|
use Libs\Loader;
|
||||||
spl_autoload_register(function ($className) {
|
use Libs\Router;
|
||||||
$fp = str_replace('\\','/',$className);
|
|
||||||
$name = basename($fp);
|
|
||||||
$dir = dirname($fp);
|
|
||||||
$file = ROOT_CORE.'/'.$dir.'/'.$name.'.php';
|
|
||||||
if (file_exists($file)) {
|
|
||||||
require_once $file;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Incluir routers
|
require_once('autoload.php');
|
||||||
$routers = glob(ROOT_CORE.'/Routers/*.php');
|
|
||||||
|
|
||||||
foreach($routers as $file){
|
// Router autoload
|
||||||
require_once($file);
|
Loader::load(ROOT_CORE . '/Routers/');
|
||||||
}
|
|
||||||
|
|
||||||
\Libs\Router::apply();
|
// Other autoloads
|
||||||
?>
|
Loader::load(ROOT_CORE . '/Autoloads/');
|
||||||
|
|
||||||
|
// Run the routers
|
||||||
|
Router::apply();
|
||||||
|
|||||||
+83
-71
@@ -28,79 +28,91 @@ En la siguiente tabla se encuentra la lista de estados de los gestores de bases
|
|||||||
+ *En blanco* como que no ha sido probado aún.
|
+ *En blanco* como que no ha sido probado aún.
|
||||||
+ *error* como que fue probado, no funciona y no ha sido aún arreglado.
|
+ *error* como que fue probado, no funciona y no ha sido aún arreglado.
|
||||||
+ *not supported* como no soportado por el gestor de bases de datos.
|
+ *not supported* como no soportado por el gestor de bases de datos.
|
||||||
+ *fixed* para aquello que no existe en el gestor de DB, pero la librería lo traduce a un equivalente.
|
+ *fixed* para aquello que no existe en el gestor de BD, pero la librería lo traduce a un equivalente.
|
||||||
|
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| method | MySQL/MariaDB | sqlite3 | postgreSQL |
|
| method | MySQL/MariaDB | sqlite3 | postgreSQL |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| db | ok | ok | |
|
| db | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| query | ok | ok | |
|
| query | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| resetQuery | ok | ok | |
|
| resetQuery | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| buildQuery | ok | ok | |
|
| buildQuery | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| getInstance | ok | ok | |
|
| getInstance | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| getVars | ok | ok | |
|
| getVars | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| className | ok | ok | |
|
| className | ok | ok | pk |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| table | ok | ok | |
|
| table | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| update | ok | ok | |
|
| update | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| beginTransaction | ok | ok | |
|
| beginTransaction | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| rollBack | ok | ok | |
|
| rollBack | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| commit | ok | ok | |
|
| commit | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| add | ok | ok | |
|
| add | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| save | ok | ok | |
|
| save | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| delete | ok | ok | |
|
| delete | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| select | ok | ok | |
|
| select | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| from | ok | ok | |
|
| from | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| where | ok | ok | |
|
| where | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| where_in | ok | ok | |
|
| whereIn | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| leftJoin | ok | ok | |
|
| whereNotIn | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| rightJoin | ok | not supported | |
|
| whereNull | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| innerJoin | ok | ok | |
|
| whereNotNull | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| and | ok | ok | |
|
| whereExists | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| or | ok | ok | |
|
| whereNotExists | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| groupBy | ok | ok | |
|
| leftJoin | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| limit | ok | ok | |
|
| rightJoin | ok | fixed | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| orderBy | ok | ok | |
|
| innerJoin | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| count | ok | ok | |
|
| crossJoin | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| getById | ok | ok | |
|
| and | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| search | ok | ok | |
|
| or | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| get | ok | ok | |
|
| groupBy | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| getFirst | ok | ok | |
|
| limit | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| all | ok | ok | |
|
| orderBy | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
| setNull | ok | ok | |
|
| count | ok | ok | ok |
|
||||||
|------------------+---------------+---------------+------------|
|
|------------------+---------------+---------+------------|
|
||||||
|
| getById | ok | ok | ok |
|
||||||
|
|------------------+---------------+---------+------------|
|
||||||
|
| search | ok | ok | ok |
|
||||||
|
|------------------+---------------+---------+------------|
|
||||||
|
| get | ok | ok | ok |
|
||||||
|
|------------------+---------------+---------+------------|
|
||||||
|
| getFirst | ok | ok | ok |
|
||||||
|
|------------------+---------------+---------+------------|
|
||||||
|
| all | ok | ok | ok |
|
||||||
|
|------------------+---------------+---------+------------|
|
||||||
|
| setNull | ok | ok | ok |
|
||||||
|
|------------------+---------------+---------+------------|
|
||||||
|
|
||||||
* Contacto
|
* Contacto
|
||||||
|
|
||||||
|
|||||||
+29
-24
@@ -1,45 +1,51 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* Database - DuckBrain
|
|
||||||
*
|
|
||||||
* Clase diseñada para crear y devolver una única instancia PDO (database).
|
|
||||||
*
|
|
||||||
* @author KJ
|
|
||||||
* @website https://kj2.me
|
|
||||||
* @licence MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Libs;
|
namespace Libs;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use PDO;
|
use PDO;
|
||||||
use PDOException;
|
use PDOException;
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class Database extends PDO {
|
/**
|
||||||
static private array $databases = [];
|
* Database - DuckBrain
|
||||||
|
*
|
||||||
private function __construct() {}
|
* Class designed to create and return a single PDO instance (database).
|
||||||
|
*
|
||||||
|
* @author KJ
|
||||||
|
* @website https://kj2.me
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
class Database extends PDO
|
||||||
|
{
|
||||||
|
private static array $databases = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Devuelve una instancia homogénea (singlenton) de la base de datos (PDO).
|
* Private constructor to prevent direct instantiation.
|
||||||
|
*/
|
||||||
|
private function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a homogeneous (singleton) instance of the database (PDO).
|
||||||
*
|
*
|
||||||
* @return PDO
|
* @return PDO
|
||||||
|
* @throws Exception If there is an error connecting to the database.
|
||||||
*/
|
*/
|
||||||
static public function getInstance(
|
public static function getInstance(
|
||||||
string $type = 'mysql',
|
string $type = 'mysql',
|
||||||
string $host = 'localhost',
|
string $host = 'localhost',
|
||||||
string $name = '',
|
string $name = '',
|
||||||
string $user = '',
|
string $user = '',
|
||||||
string $pass = '',
|
string $pass = '',
|
||||||
): PDO
|
): PDO {
|
||||||
{
|
$key = $type . '/' . $host . '/' . $name . '/' . $user;
|
||||||
$key = $type.'/'.$host.'/'.$name.'/'.$user;
|
|
||||||
if (empty(static::$databases[$key])) {
|
if (empty(static::$databases[$key])) {
|
||||||
|
|
||||||
if ($type == 'sqlite') {
|
if ($type == 'sqlite') {
|
||||||
$dsn = $type .':'. $name;
|
$dsn = $type . ':' . $name;
|
||||||
} else
|
} else {
|
||||||
$dsn = $type.':dbname='.$name.';host='.$host;
|
$dsn = $type . ':dbname=' . $name . ';host=' . $host;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
static::$databases[$key] = new PDO($dsn, $user, $pass);
|
static::$databases[$key] = new PDO($dsn, $user, $pass);
|
||||||
@@ -55,4 +61,3 @@ class Database extends PDO {
|
|||||||
return static::$databases[$key];
|
return static::$databases[$key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Libs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loader - DuckBrain
|
||||||
|
*
|
||||||
|
* Simple library to bulk load multiple php files inside a folder.
|
||||||
|
*
|
||||||
|
* @author KJ
|
||||||
|
* @website https://kj2.me
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
class Loader
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Loads all PHP files from a specified directory.
|
||||||
|
* If the directory does not exist or is not a directory, no files will be loaded.
|
||||||
|
*
|
||||||
|
* @param string $directoryPath The path to the directory containing the PHP files to load.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function load(string $directoryPath): void
|
||||||
|
{
|
||||||
|
if (is_dir($directoryPath)) {
|
||||||
|
foreach (glob(rtrim($directoryPath, '/') . '/*.php') as $file) {
|
||||||
|
require_once($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Middleware - DuckBrain
|
|
||||||
*
|
|
||||||
* Librería base para middlewares.
|
|
||||||
*
|
|
||||||
* @author KJ
|
|
||||||
* @website https://kj2.me
|
|
||||||
* @licence MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Libs;
|
|
||||||
|
|
||||||
class Middleware {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Llama al siguiente callback.
|
|
||||||
*
|
|
||||||
* @param Neuron $req
|
|
||||||
*
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public static function next(Neuron $req): mixed
|
|
||||||
{
|
|
||||||
$next = array_pop($req->next);
|
|
||||||
return call_user_func_array($next, [$req]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+629
-351
File diff suppressed because it is too large
Load Diff
+30
-25
@@ -1,54 +1,59 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace Libs;
|
||||||
|
|
||||||
|
use AllowDynamicProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Neuron - DuckBrain
|
* Neuron - DuckBrain
|
||||||
*
|
*
|
||||||
* Neuron, sirve para crear un objeto que alojará valores, pero
|
* Neuron, serves to create an object that will hold values.
|
||||||
* además tiene la característica especial de que al intentar
|
* In addition, it has the special characteristic that when trying
|
||||||
* acceder a un atributo que no está definido devolerá nulo en
|
* to access an undefined property, it will return null instead
|
||||||
* lugar de generar un error php notice que indica que se está
|
* of generating a notice (PHP notice) for an undefined variable or property.
|
||||||
* intentando acceder a un valor no definido.
|
|
||||||
*
|
*
|
||||||
* El constructor recibe un objeto o arreglo con los valores que
|
* The constructor accepts an object or an array containing the
|
||||||
* sí estarán definidos.
|
* values that will be defined.
|
||||||
*
|
*
|
||||||
* @author KJ
|
* @author KJ
|
||||||
* @website https://kj2.me
|
* @website https://kj2.me
|
||||||
* @licence MIT
|
* @license MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Libs;
|
|
||||||
use AllowDynamicProperties;
|
|
||||||
|
|
||||||
#[AllowDynamicProperties]
|
#[AllowDynamicProperties]
|
||||||
class Neuron {
|
class Neuron
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* __construct
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param array $data
|
* @param array $data Data to initialize the Neuron with. Can be an array or an object.
|
||||||
*/
|
*/
|
||||||
public function __construct(...$data)
|
public function __construct(...$data)
|
||||||
{
|
{
|
||||||
if (count($data) === 1 &&
|
if (
|
||||||
|
count($data) === 1 &&
|
||||||
isset($data[0]) &&
|
isset($data[0]) &&
|
||||||
(is_array($data[0]) ||
|
(is_array($data[0]) ||
|
||||||
is_object($data[0])))
|
is_object($data[0]))
|
||||||
|
) {
|
||||||
$data = $data[0];
|
$data = $data[0];
|
||||||
|
}
|
||||||
|
|
||||||
foreach($data as $key => $value)
|
foreach ($data as $key => $value) {
|
||||||
$this->{$key} = $value;
|
$this->{$key} = $value;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __get
|
* Magic method __get
|
||||||
*
|
*
|
||||||
* @param string $index
|
* This method is called when an undefined property is accessed.
|
||||||
* @return null
|
* It returns null instead of triggering an E_NOTICE.
|
||||||
|
*
|
||||||
|
* @param string $index The name of the property being accessed.
|
||||||
|
* @return null Always returns null for undefined properties.
|
||||||
*/
|
*/
|
||||||
public function __get(string $index): null
|
public function __get(string $index)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
|
|||||||
+107
-49
@@ -1,122 +1,180 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* Request - DuckBrain
|
|
||||||
*
|
|
||||||
* Libería complementaria de la libería Router.
|
|
||||||
* Contiene el cuerpo básico de la petición http (POST, GET, JSON, etc).
|
|
||||||
*
|
|
||||||
* @author KJ
|
|
||||||
* @website https://kj2.me
|
|
||||||
* @licence MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Libs;
|
namespace Libs;
|
||||||
|
|
||||||
class Request extends Neuron {
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request - DuckBrain
|
||||||
|
*
|
||||||
|
* Complementary library to the Router library.
|
||||||
|
* Contains the basic body of the http request (POST, GET, JSON, etc).
|
||||||
|
*
|
||||||
|
* @author KJ
|
||||||
|
* @website https://kj2.me
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
class Request extends Neuron
|
||||||
|
{
|
||||||
public Neuron $get;
|
public Neuron $get;
|
||||||
public Neuron $post;
|
public Neuron $post;
|
||||||
|
public Neuron $put;
|
||||||
|
public Neuron $patch;
|
||||||
|
public Neuron $delete;
|
||||||
public Neuron $json;
|
public Neuron $json;
|
||||||
public Neuron $params;
|
public Neuron $params;
|
||||||
public string $path;
|
public string $path;
|
||||||
public string $error;
|
public string $error;
|
||||||
public array $next;
|
public string $body;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __construct
|
* __construct
|
||||||
*
|
|
||||||
* @param string $path Ruta actual tomando como raíz la instalación de DuckBrain.
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->path = Router::currentPath();
|
$this->path = Router::currentPath();
|
||||||
$this->get = new Neuron($_GET);
|
$this->get = new Neuron($_GET);
|
||||||
$this->post = new Neuron($_POST);
|
$this->post = new Neuron($_POST);
|
||||||
|
$this->put = new Neuron();
|
||||||
|
$this->patch = new Neuron();
|
||||||
|
$this->delete = new Neuron();
|
||||||
|
$this->params = Router::$params ?? new Neuron();
|
||||||
|
$this->body = file_get_contents("php://input");
|
||||||
|
|
||||||
$contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';
|
$contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';
|
||||||
if ($contentType === "application/json")
|
if ($contentType === "application/json") {
|
||||||
$this->json = new Neuron(
|
$this->json = new Neuron(
|
||||||
(object) json_decode(trim(file_get_contents("php://input")), false)
|
(object) json_decode(trim($this->body), false)
|
||||||
);
|
);
|
||||||
else
|
} else {
|
||||||
$this->json = new Neuron();
|
$this->json = new Neuron();
|
||||||
|
if (
|
||||||
|
in_array($_SERVER['REQUEST_METHOD'], ['PUT', 'PATCH', 'DELETE']) &&
|
||||||
|
preg_match('/^[^;?\/:@&=+$,]{1,255}[=]/', $this->body, $matches)
|
||||||
|
) {
|
||||||
|
// With the regular expression, we verify that it is a valid
|
||||||
|
// http query string and avoid memory errors in case
|
||||||
|
// the body contains something larger than that.
|
||||||
|
parse_str($this->body, $input_vars);
|
||||||
|
$this->{strtolower($_SERVER['REQUEST_METHOD'])} = new Neuron($input_vars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->params = new Neuron();
|
// Run configured validations
|
||||||
|
$this->validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inicia la validación que se haya configurado.
|
* Starts the configured validation.
|
||||||
*
|
*
|
||||||
* @return mixed
|
* On failure the single error message is built with Validator::message()
|
||||||
|
* and handed to onInvalid(), which throws by default: failures travel up
|
||||||
|
* as exceptions instead of answering HTTP here.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @throws Exception When a configured rule fails.
|
||||||
*/
|
*/
|
||||||
public function validate(): mixed
|
public function validate(): void
|
||||||
{
|
{
|
||||||
if ($_SERVER['REQUEST_METHOD'] == 'GET')
|
$actual = match ($_SERVER['REQUEST_METHOD']) {
|
||||||
$actual = $this->get;
|
'POST', 'PUT', 'PATCH', 'DELETE' => $this->{strtolower($_SERVER['REQUEST_METHOD'])},
|
||||||
else
|
default => $this->get
|
||||||
$actual = $this->post;
|
};
|
||||||
|
|
||||||
if (Validator::validateList(static::paramRules(), $this->params) &&
|
// Merge uploaded files ($_FILES) into the body data set so the file rules
|
||||||
Validator::validateList(static::getRules(), $this->get ) &&
|
// (file/image/mimes and the routed min/max/required...) can validate
|
||||||
Validator::validateList(static::rules(), $actual))
|
// uploads through a Request. $this->post is left untouched.
|
||||||
return Middleware::next($this);
|
$body = empty($_FILES)
|
||||||
|
? $actual
|
||||||
|
: new Neuron(array_merge(get_object_vars($actual), $_FILES));
|
||||||
|
|
||||||
if (isset(static::messages()[Validator::$lastFailed]))
|
if (
|
||||||
$error = static::messages()[Validator::$lastFailed];
|
Validator::validateList(static::paramRules(), $this->params) &&
|
||||||
else {
|
Validator::validateList(static::getRules(), $this->get) &&
|
||||||
|
Validator::validateList(static::rules(), $body)
|
||||||
$error = 'Error: validation failed of '.preg_replace('/\./', ' as ', Validator::$lastFailed, 1);
|
) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return static::onInvalid($error);
|
$error = Validator::message(
|
||||||
|
Validator::$lastFailed,
|
||||||
|
static::messages(),
|
||||||
|
static::attributes()
|
||||||
|
);
|
||||||
|
|
||||||
|
static::onInvalid($error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reglas para el método actual.
|
* Rules for the current method.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function rules(): array {
|
public function rules(): array
|
||||||
|
{
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reglas para los parámetros por URL.
|
* Rules for URL parameters.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function paramRules(): array {
|
public function paramRules(): array
|
||||||
|
{
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reglas para los parámetros GET.
|
* Rules for GET parameters.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function getRules(): array {
|
public function getRules(): array
|
||||||
|
{
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mensajes de error en caso de fallar una validación.
|
* Error messages in case a validation fails.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function messages(): array {
|
public function messages(): array
|
||||||
|
{
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Función a ejecutar cuando se ha detectado un valor no válido.
|
* Human-readable names for the fields.
|
||||||
|
*
|
||||||
|
* Forwarded to Validator::message() so the :attribute marker in the error
|
||||||
|
* text can be replaced with a friendlier name (e.g. "edad" => "la edad").
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to execute when an invalid value has been detected.
|
||||||
|
*
|
||||||
|
* The default implementation always throws a generic \Exception carrying
|
||||||
|
* the single error message and HTTP 422 as its code; the framework's
|
||||||
|
* exception boundary (Router::apply) renders the response. Override it to
|
||||||
|
* throw a more specific exception type instead. The never return type is
|
||||||
|
* the contract: an override that returned would let the request continue
|
||||||
|
* with invalid data, so PHP rejects such an override at compile time.
|
||||||
*
|
*
|
||||||
* @param string $error
|
* @param string $error
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return never
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function onInvalid(string $error): mixed
|
public function onInvalid(string $error): never
|
||||||
{
|
{
|
||||||
http_response_code(422);
|
throw new Exception($error, 422);
|
||||||
print($error);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+244
-149
@@ -1,57 +1,138 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* Router - DuckBrain
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @author KJ
|
|
||||||
* @website https://kj2.me
|
|
||||||
* @licence MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Libs;
|
namespace Libs;
|
||||||
|
|
||||||
class Router {
|
/**
|
||||||
private static $get = [];
|
* Router - DuckBrain
|
||||||
private static $post = [];
|
*
|
||||||
private static $put = [];
|
* Router library.
|
||||||
private static $patch = [];
|
* It strictly depends on the ROOT_DIR constant being defined
|
||||||
private static $delete = [];
|
* and optionally on the SITE_URL constant being defined.
|
||||||
private static $last;
|
*
|
||||||
|
* @author KJ
|
||||||
|
* @website https://kj2.me
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
class Router
|
||||||
|
{
|
||||||
|
private static array $get = [];
|
||||||
|
private static array $post = [];
|
||||||
|
private static array $put = [];
|
||||||
|
private static array $patch = [];
|
||||||
|
private static array $delete = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores a temporary stack of middlewares to be applied to routes defined
|
||||||
|
* within a specific scope, typically configured by `withMiddleware()`.
|
||||||
|
* These middlewares are active only during the execution of the scope's callback.
|
||||||
|
*
|
||||||
|
* @var array $withMiddlewares<callable>
|
||||||
|
*/
|
||||||
|
private static array $withMiddlewares = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the method and index of the last configured route, e.g., ['get', 0].
|
||||||
|
* Used for chaining methods like middleware() or reconfigure().
|
||||||
|
*
|
||||||
|
* @var array $last
|
||||||
|
*/
|
||||||
|
private static array $last;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the parameters extracted from the current matching route.
|
||||||
|
*
|
||||||
|
* @var Neuron $params
|
||||||
|
*/
|
||||||
|
public static Neuron $params;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The callback function to be executed when no route matches.
|
||||||
|
*
|
||||||
|
* @var callable $notFoundCallback
|
||||||
|
*/
|
||||||
public static $notFoundCallback = 'Libs\Router::defaultNotFound';
|
public static $notFoundCallback = 'Libs\Router::defaultNotFound';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Función callback por defectio para cuando
|
* Default callback function for when
|
||||||
* no se encuentra configurada la ruta.
|
* the route is not found.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function defaultNotFound (): void
|
public static function defaultNotFound(): void
|
||||||
{
|
{
|
||||||
header("HTTP/1.0 404 Not Found");
|
header("HTTP/1.0 404 Not Found");
|
||||||
echo '<h2 style="text-align: center;margin: 25px 0px;">Error 404 - Página no encontrada</h2>';
|
echo '<h2 style="text-align: center;margin: 25px 0px;">Error 404 - Page Not Found</h2>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The callback function to be executed when the router's boundary
|
||||||
|
* catches an exception thrown anywhere in the matched route chain.
|
||||||
|
* It receives the exception as a named argument: the handler must
|
||||||
|
* declare its parameter as $exception (typeable as \Throwable).
|
||||||
|
*
|
||||||
|
* @var callable $exceptionCallback
|
||||||
|
*/
|
||||||
|
public static $exceptionCallback = 'Libs\Router::defaultException';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default callback function for exception responses.
|
||||||
|
*
|
||||||
|
* The HTTP status comes from the exception's code only when it is an
|
||||||
|
* integer in the 400-599 range; anything else (0, arbitrary codes, the
|
||||||
|
* SQLSTATE string carried by PDOException) answers 500. The body is
|
||||||
|
* negotiated from the request's Accept header: JSON when the client asks
|
||||||
|
* for application/json, plain text otherwise. The trace is serialized
|
||||||
|
* from getTraceAsString() because json_encode() of a Throwable yields an
|
||||||
|
* empty object: its properties are protected.
|
||||||
|
*
|
||||||
|
* @param \Throwable $exception
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function defaultException(\Throwable $exception): void
|
||||||
|
{
|
||||||
|
$code = $exception->getCode();
|
||||||
|
http_response_code(is_int($code) && $code >= 400 && $code <= 599 ? $code : 500);
|
||||||
|
|
||||||
|
$accept = $_SERVER['HTTP_ACCEPT'] ?? '';
|
||||||
|
|
||||||
|
if (str_contains($accept, 'application/json')) {
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
print(json_encode([
|
||||||
|
'error' => $exception->getMessage(),
|
||||||
|
'exception' => get_class($exception),
|
||||||
|
'file' => $exception->getFile(),
|
||||||
|
'line' => $exception->getLine(),
|
||||||
|
'trace' => explode(PHP_EOL, $exception->getTraceAsString()),
|
||||||
|
]));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print($exception->getMessage() . PHP_EOL . $exception->getTraceAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __construct
|
* __construct
|
||||||
*/
|
*/
|
||||||
private function __construct() {}
|
private function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parsea para deectar las pseudovariables (ej: {variable})
|
* Parses to detect pseudovariables (e.g., {variable})
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* Ruta con pseudovariables.
|
* Route with pseudovariables.
|
||||||
*
|
*
|
||||||
* @param callable $callback
|
* @param callable $callback
|
||||||
* Callback que será llamado cuando la ruta configurada en $path coincida.
|
* Callback that will be called when the route configured in $path matches.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* Arreglo con 2 índices:
|
* Array with 3 indices:
|
||||||
* path - Contiene la ruta con las pseudovariables reeplazadas por expresiones regulares.
|
* path - Contains the route with pseudovariables replaced by regular expressions.
|
||||||
* callback - Contiene el callback en formato Namespace\Clase::Método.
|
* callback - Contains the callback in Namespace\Class::Method format.
|
||||||
|
* paramNames - An array of parameter names found in the path.
|
||||||
*/
|
*/
|
||||||
private static function parse(string $path, callable $callback): array
|
private static function parse(string $path, callable $callback): array
|
||||||
{
|
{
|
||||||
@@ -62,72 +143,75 @@ class Router {
|
|||||||
$path = preg_replace(
|
$path = preg_replace(
|
||||||
['/\\\{\w+\\\}/s'],
|
['/\\\{\w+\\\}/s'],
|
||||||
['([^\/]+)'],
|
['([^\/]+)'],
|
||||||
$path);
|
$path
|
||||||
|
);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'path' => $path,
|
'path' => $path,
|
||||||
'callback' => [$callback],
|
'callback' => [$callback],
|
||||||
'paramNames' => $paramNames
|
'paramNames' => $paramNames,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Devuelve el ruta base o raiz del proyecto sobre la que trabajará el router.
|
* Returns the base or root path of the project on which the router will work.
|
||||||
*
|
*
|
||||||
* Ej: Si la url del sistema está en "https://ejemplo.com/duckbrain"
|
* Ex: If the system URL is "https://example.com/duckbrain"
|
||||||
* entonces la ruta base sería "/duckbrain"
|
* then the base path would be "/duckbrain"
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function basePath(): string
|
public static function basePath(): string
|
||||||
{
|
{
|
||||||
if (defined('SITE_URL') && !empty(SITE_URL))
|
if (defined('SITE_URL') && !empty(SITE_URL)) {
|
||||||
return rtrim(parse_url(SITE_URL, PHP_URL_PATH), '/').'/';
|
return rtrim(parse_url(SITE_URL, PHP_URL_PATH), '/') . '/';
|
||||||
|
}
|
||||||
return str_replace($_SERVER['DOCUMENT_ROOT'], '/', ROOT_DIR);
|
return str_replace($_SERVER['DOCUMENT_ROOT'], '/', ROOT_DIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirije a una ruta relativa interna.
|
* Redirects to an internal relative path.
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* La ruta relativa a la ruta base.
|
* The path relative to the base path.
|
||||||
*
|
*
|
||||||
* Ej: Si nuesto sistema está en "https://ejemplo.com/duckbrain"
|
* Ex: If our system is at "https://example.com/duckbrain"
|
||||||
* llamamos a Router::redirect('/docs'), entonces seremos
|
* and we call Router::redirect('/docs'), we will be
|
||||||
* redirigidos a "https://ejemplo.com/duckbrain/docs".
|
* redirected to "https://example.com/duckbrain/docs".
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function redirect(string $path): void
|
public static function redirect(string $path): void
|
||||||
{
|
{
|
||||||
header('Location: '.static::basePath().ltrim($path, '/'));
|
header('Location: ' . static::basePath() . ltrim($path, '/'));
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Añade un middleware a la última ruta usada.
|
* Adds a middleware to the last used route.
|
||||||
* Solo se puede usar un middleware a la vez.
|
* Only one middleware can be added at a time.
|
||||||
*
|
*
|
||||||
* @param callable $callback
|
* @param callable $callback
|
||||||
* @param int $prioriry
|
* @param int|null $priority Optional priority for the middleware execution order.
|
||||||
*
|
*
|
||||||
* @return static
|
* @return static
|
||||||
* Devuelve la instancia actual.
|
* Returns the current instance.
|
||||||
*/
|
*/
|
||||||
public static function middleware(callable $callback, int $priority = null): static
|
public static function middleware(callable $callback, ?int $priority = null): static
|
||||||
{
|
{
|
||||||
if (!isset(static::$last))
|
if (!isset(static::$last)) {
|
||||||
return new static();
|
return new static();
|
||||||
|
}
|
||||||
|
|
||||||
$method = static::$last[0];
|
$method = static::$last[0];
|
||||||
$index = static::$last[1];
|
$index = static::$last[1];
|
||||||
|
|
||||||
if (isset($priority) && $priority <= 0)
|
if (isset($priority) && $priority <= 0) {
|
||||||
$priority = 1;
|
$priority = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_null($priority) || $priority >= count(static::$$method[$index]['callback']))
|
if (is_null($priority) || $priority >= count(static::$$method[$index]['callback'])) {
|
||||||
static::$$method[$index]['callback'][] = $callback;
|
static::$$method[$index]['callback'][] = $callback;
|
||||||
else {
|
} else {
|
||||||
static::$$method[$index]['callback'] = array_merge(
|
static::$$method[$index]['callback'] = array_merge(
|
||||||
array_slice(static::$$method[$index]['callback'], 0, $priority),
|
array_slice(static::$$method[$index]['callback'], 0, $priority),
|
||||||
[$callback],
|
[$callback],
|
||||||
@@ -139,7 +223,29 @@ class Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reconfigura el callback final de la última ruta.
|
* Temporarily applies a set of middlewares to routes defined within a given callback.
|
||||||
|
* The middlewares are only active for the duration of the callback execution
|
||||||
|
* and are reset afterwards.
|
||||||
|
*
|
||||||
|
* @param callable $middleware
|
||||||
|
* @param callable $callback
|
||||||
|
*
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public static function withMiddleware(callable $middleware, callable $callback): static
|
||||||
|
{
|
||||||
|
$currentMiddlewares = static::$withMiddlewares;
|
||||||
|
array_unshift(static::$withMiddlewares, $middleware);
|
||||||
|
|
||||||
|
$callback();
|
||||||
|
|
||||||
|
static::$withMiddlewares = $currentMiddlewares; // Restore withMiddleware
|
||||||
|
|
||||||
|
return new static();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reconfigures the final callback of the last route.
|
||||||
*
|
*
|
||||||
* @param callable $callback
|
* @param callable $callback
|
||||||
*
|
*
|
||||||
@@ -147,8 +253,9 @@ class Router {
|
|||||||
*/
|
*/
|
||||||
public static function reconfigure(callable $callback): static
|
public static function reconfigure(callable $callback): static
|
||||||
{
|
{
|
||||||
if (empty(static::$last))
|
if (empty(static::$last)) {
|
||||||
return new static();
|
return new static();
|
||||||
|
}
|
||||||
|
|
||||||
$method = static::$last[0];
|
$method = static::$last[0];
|
||||||
$index = static::$last[1];
|
$index = static::$last[1];
|
||||||
@@ -159,20 +266,20 @@ class Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configura calquier método para todas las rutas.
|
* Configures any method for all routes.
|
||||||
*
|
*
|
||||||
* En caso de no recibir un callback, busca la ruta actual
|
* If no callback is received, it searches for the current route
|
||||||
* solo configura la ruta como la última configurada
|
* and only sets the route as the last configured one
|
||||||
* siempre y cuando la misma haya sido configurada previamente.
|
* provided it has been configured previously.
|
||||||
*
|
*
|
||||||
* @param string $method
|
* @param string $method
|
||||||
* Método http.
|
* HTTP method.
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* Ruta con pseudovariables.
|
* Route with pseudovariables.
|
||||||
* @param callable|null $callback
|
* @param callable|null $callback
|
||||||
*
|
*
|
||||||
* @return
|
* @return static
|
||||||
* Devuelve la instancia actual.
|
* Returns the current instance.
|
||||||
*/
|
*/
|
||||||
public static function configure(string $method, string $path, ?callable $callback = null): static
|
public static function configure(string $method, string $path, ?callable $callback = null): static
|
||||||
{
|
{
|
||||||
@@ -181,125 +288,143 @@ class Router {
|
|||||||
$path = preg_replace(
|
$path = preg_replace(
|
||||||
['/\\\{\w+\\\}/s'],
|
['/\\\{\w+\\\}/s'],
|
||||||
['([^\/]+)'],
|
['([^\/]+)'],
|
||||||
$path);
|
$path
|
||||||
|
);
|
||||||
|
|
||||||
foreach(static::$$method as $index => $router)
|
foreach (static::$$method as $index => $router) {
|
||||||
if ($router['path'] == $path) {
|
if ($router['path'] == $path) {
|
||||||
static::$last = [$method, $index];
|
static::$last = [$method, $index];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new static();
|
return new static();
|
||||||
}
|
}
|
||||||
|
|
||||||
static::$$method[] = static::parse($path, $callback);
|
static::$$method[] = static::parse($path, $callback);
|
||||||
static::$last = [$method, count(static::$$method)-1];
|
static::$last = [$method, count(static::$$method) - 1];
|
||||||
|
|
||||||
|
foreach (static::$withMiddlewares as $middleware) {
|
||||||
|
static::middleware($middleware);
|
||||||
|
}
|
||||||
|
|
||||||
return new static();
|
return new static();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define los routers para el método GET.
|
* Defines routers for the GET method.
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* Ruta con pseudovariables.
|
* Route with pseudovariables.
|
||||||
* @param callable $callback
|
* @param callable|null $callback
|
||||||
* Callback que será llamado cuando la ruta configurada en $path coincida.
|
* Callback that will be called when the route configured in $path matches.
|
||||||
*
|
*
|
||||||
* @return static
|
* @return static
|
||||||
* Devuelve la instancia actual.
|
* Returns the current instance.
|
||||||
*/
|
*/
|
||||||
public static function get(string $path, callable $callback = null): static
|
public static function get(string $path, ?callable $callback = null): static
|
||||||
{
|
{
|
||||||
return static::configure('get', $path, $callback);
|
return static::configure('get', $path, $callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define los routers para el método POST.
|
* Defines routers for the POST method.
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* Ruta con pseudovariables.
|
* Route with pseudovariables.
|
||||||
* @param callable $callback
|
* @param callable|null $callback
|
||||||
* Callback que será llamado cuando la ruta configurada en $path coincida.
|
* Callback that will be called when the route configured in $path matches.
|
||||||
*
|
*
|
||||||
* @return static
|
* @return static
|
||||||
* Devuelve la instancia actual.
|
* Returns the current instance.
|
||||||
*/
|
*/
|
||||||
public static function post(string $path, callable $callback = null): static
|
public static function post(string $path, ?callable $callback = null): static
|
||||||
{
|
{
|
||||||
return static::configure('post', $path, $callback);
|
return static::configure('post', $path, $callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define los routers para el método PUT.
|
* Defines routers for the PUT method.
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* Ruta con pseudovariables.
|
* Route with pseudovariables.
|
||||||
* @param callable $callback
|
* @param callable|null $callback
|
||||||
* Callback que será llamado cuando la ruta configurada en $path coincida.
|
* Callback that will be called when the route configured in $path matches.
|
||||||
*
|
*
|
||||||
* @return static
|
* @return static
|
||||||
* Devuelve la instancia actual
|
* Returns the current instance
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static function put(string $path, callable $callback = null): static
|
public static function put(string $path, ?callable $callback = null): static
|
||||||
{
|
{
|
||||||
return static::configure('put', $path, $callback);
|
return static::configure('put', $path, $callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define los routers para el método PATCH.
|
* Defines routers for the PATCH method.
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* Ruta con pseudovariables.
|
* Route with pseudovariables.
|
||||||
* @param callable $callback
|
* @param callable|null $callback
|
||||||
* Callback que será llamado cuando la ruta configurada en $path coincida.
|
* Callback that will be called when the route configured in $path matches.
|
||||||
*
|
*
|
||||||
* @return static
|
* @return static
|
||||||
* Devuelve la instancia actual
|
* Returns the current instance
|
||||||
*/
|
*/
|
||||||
public static function patch(string $path, callable $callback = null): static
|
public static function patch(string $path, ?callable $callback = null): static
|
||||||
{
|
{
|
||||||
return static::configure('patch', $path, $callback);
|
return static::configure('patch', $path, $callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define los routers para el método DELETE.
|
* Defines routers for the DELETE method.
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* Ruta con pseudovariables
|
* Route with pseudovariables
|
||||||
* @param callable $callback
|
* @param callable|null $callback
|
||||||
* Callback que será llamado cuando la ruta configurada en $path coincida.
|
* Callback that will be called when the route configured in $path matches.
|
||||||
*
|
*
|
||||||
* @return static
|
* @return static
|
||||||
* Devuelve la instancia actual
|
* Returns the current instance
|
||||||
*/
|
*/
|
||||||
public static function delete(string $path, callable $callback = null): static
|
public static function delete(string $path, ?callable $callback = null): static
|
||||||
{
|
{
|
||||||
return static::configure('delete', $path, $callback);
|
return static::configure('delete', $path, $callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Devuelve la ruta actual tomando como raíz la ruta de instalación de DuckBrain.
|
* Returns the current path, taking the DuckBrain installation path as the root.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function currentPath() : string
|
public static function currentPath(): string
|
||||||
{
|
{
|
||||||
return preg_replace('/'.preg_quote(static::basePath(), '/').'/',
|
return preg_replace(
|
||||||
'/', strtok($_SERVER['REQUEST_URI'], '?'), 1);
|
'/' . preg_quote(static::basePath(), '/') . '/',
|
||||||
|
'/',
|
||||||
|
strtok($_SERVER['REQUEST_URI'], '?'),
|
||||||
|
1
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aplica la configuración de rutas.
|
* Applies the route configuration.
|
||||||
*
|
*
|
||||||
* @param string $path (opcional) Ruta a usar. Si no se define, detecta la ruta actual.
|
* This method is the framework's error boundary: any \Throwable thrown
|
||||||
|
* while running the matched route's callback chain, while printing the
|
||||||
|
* returned data, or while resolving the not-found callback is caught
|
||||||
|
* here and rendered through $exceptionCallback. A failing handler is
|
||||||
|
* deliberately left uncaught (double failure falls back to PHP itself).
|
||||||
|
*
|
||||||
|
* @param string|null $path (optional) Path to use. If not defined, it detects the current path.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function apply(string $path = null): void
|
public static function apply(?string $path = null): void
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
$path = $path ?? static::currentPath();
|
$path = $path ?? static::currentPath();
|
||||||
$routers = match($_SERVER['REQUEST_METHOD']) { // Según el método selecciona un arreglo de routers
|
$routers = match ($_SERVER['REQUEST_METHOD']) { // Selects an array of routers based on the method
|
||||||
'POST' => static::$post,
|
'POST' => static::$post,
|
||||||
'PUT' => static::$put,
|
'PUT' => static::$put,
|
||||||
'PATCH' => static::$patch,
|
'PATCH' => static::$patch,
|
||||||
@@ -307,58 +432,25 @@ class Router {
|
|||||||
default => static::$get
|
default => static::$get
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach ($routers as $router) { // revisa todos los routers para ver si coinciden con la ruta actual
|
foreach ($routers as $router) { // Checks all routers to see if they match the current path
|
||||||
if (preg_match_all('/^'.$router['path'].'\/?$/si',$path, $matches, PREG_PATTERN_ORDER)) {
|
if (preg_match_all('/^' . $router['path'] . '\/?$/si', $path, $matches, PREG_PATTERN_ORDER)) {
|
||||||
unset($matches[0]);
|
unset($matches[0]);
|
||||||
|
|
||||||
// Objtener un reflection del callback
|
// Checking and storing the variable parameters of the route
|
||||||
$lastCallback = $router['callback'][0];
|
|
||||||
if ($lastCallback instanceof \Closure) { // si es función anónima
|
|
||||||
$reflectionCallback = new \ReflectionFunction($lastCallback);
|
|
||||||
} else {
|
|
||||||
if (is_string($lastCallback))
|
|
||||||
$lastCallback = preg_split('/::/', $lastCallback);
|
|
||||||
|
|
||||||
// Revisamos su es un método o solo una función
|
|
||||||
if (count($lastCallback) == 2)
|
|
||||||
$reflectionCallback = new \ReflectionMethod($lastCallback[0], $lastCallback[1]);
|
|
||||||
else
|
|
||||||
$reflectionCallback = new \ReflectionFunction($lastCallback[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtener los parámetros
|
|
||||||
$arguments = $reflectionCallback->getParameters();
|
|
||||||
if (isset($arguments[0])) {
|
|
||||||
// Obtenemos la clase del primer parámetro
|
|
||||||
$argumentClass = strval($arguments[0]->getType());
|
|
||||||
|
|
||||||
// Verificamos si la clase está o no tipada
|
|
||||||
if (empty($argumentClass)) {
|
|
||||||
$request = new Request;
|
|
||||||
} else {
|
|
||||||
$request = new $argumentClass;
|
|
||||||
|
|
||||||
// Verificamos que sea instancia de Request (requerimiento)
|
|
||||||
if (!($request instanceof Request))
|
|
||||||
throw new \Exception('Bad argument type on router callback.');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$request = new Request;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Comprobando y guardando los parámetros variables de la ruta
|
|
||||||
if (isset($matches[1])) {
|
if (isset($matches[1])) {
|
||||||
|
static::$params = new Neuron();
|
||||||
foreach ($matches as $index => $match) {
|
foreach ($matches as $index => $match) {
|
||||||
$paramName = $router['paramNames'][$index-1];
|
$paramName = $router['paramNames'][$index - 1];
|
||||||
$request->params->$paramName = urldecode($match[0]);
|
static::$params->{$paramName} = urldecode($match[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Llama a la validación y luego procesa la cola de callbacks
|
// Processes the callback queue
|
||||||
$request->next = $router['callback'];
|
foreach (array_reverse($router['callback']) as $callback) {
|
||||||
$data = $request->validate();
|
$data = Synapsis::resolve($callback);
|
||||||
|
}
|
||||||
|
|
||||||
// Por defecto imprime como JSON si se retorna algo
|
// By default, prints as JSON if something is returned
|
||||||
if (isset($data)) {
|
if (isset($data)) {
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
print(json_encode($data));
|
print(json_encode($data));
|
||||||
@@ -368,7 +460,10 @@ class Router {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si no hay router que coincida llamamos a $notFoundCallBack
|
// If no router matches, call $notFoundCallBack
|
||||||
call_user_func_array(static::$notFoundCallback, [new Request]);
|
Synapsis::resolve(static::$notFoundCallback);
|
||||||
|
} catch (\Throwable $exception) {
|
||||||
|
Synapsis::resolve(static::$exceptionCallback, ['exception' => $exception]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,179 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Libs;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Exception;
|
||||||
|
use ReflectionClass;
|
||||||
|
use ReflectionFunction;
|
||||||
|
use ReflectionMethod;
|
||||||
|
use ReflectionParameter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synapsis - DuckBrain
|
||||||
|
*
|
||||||
|
* Class responsible for dependency resolution and injection.
|
||||||
|
*
|
||||||
|
* @author KJ
|
||||||
|
* @website https://kj2.me
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
class Synapsis
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var array<class-string, class-string> $bindings
|
||||||
|
*/
|
||||||
|
private static array $bindings = [];
|
||||||
|
/**
|
||||||
|
* @var array<class-string, mixed> $instances
|
||||||
|
*/
|
||||||
|
private static array $instances = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds an interface to a class to instantiate it instead.
|
||||||
|
*
|
||||||
|
* @param class-string $interfaceName
|
||||||
|
* @param class-string $className
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @throws Exception If the interface or class does not exist.
|
||||||
|
*/
|
||||||
|
public static function bind(string $interfaceName, string $className): void
|
||||||
|
{
|
||||||
|
if (interface_exists($interfaceName) && class_exists($className)) {
|
||||||
|
static::$bindings[$interfaceName] = $className;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception('Error at binding non existant Interface or ClassName.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds multiple interfaces to multiple classes in bulk.
|
||||||
|
*
|
||||||
|
* @param array<class-string, class-string> $bindings
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function bulkBind(array $bindings): void
|
||||||
|
{
|
||||||
|
foreach ($bindings as $interfaceName => $className) {
|
||||||
|
static::bind($interfaceName, $className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves and injects dependencies for a callable and returns its result.
|
||||||
|
*
|
||||||
|
* @param callable $action
|
||||||
|
* @param array<string, mixed> $named Associative array of values injected into the callable's
|
||||||
|
* parameters by exact name match. Consumed in resolveParameterValues().
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @throws Exception If an unhandled callable type is provided.
|
||||||
|
*/
|
||||||
|
public static function resolve(callable $action, array $named = []): mixed
|
||||||
|
{
|
||||||
|
if ($action instanceof Closure) { // If it's an anonymous function
|
||||||
|
$reflectionCallback = new ReflectionFunction($action);
|
||||||
|
} else { // Array or string with the method
|
||||||
|
if (is_string($action)) {
|
||||||
|
$action = preg_split('/::/', $action);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's a method or just a function
|
||||||
|
if (count($action) == 2) {
|
||||||
|
$reflectionCallback = new ReflectionMethod($action[0], $action[1]);
|
||||||
|
} else {
|
||||||
|
$reflectionCallback = new ReflectionFunction($action[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the parameters
|
||||||
|
return call_user_func_array(
|
||||||
|
$action,
|
||||||
|
static::resolveParameterValues($reflectionCallback->getParameters(), $named)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves and injects dependencies for a class and returns its result.
|
||||||
|
*
|
||||||
|
* @param class-string $className
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @throws Exception If a binding is missing for an interface or the class does not exist.
|
||||||
|
*/
|
||||||
|
public static function &resolveInstance(string $className): mixed
|
||||||
|
{
|
||||||
|
if (interface_exists($className)) {
|
||||||
|
if (isset(static::$bindings[$className])) {
|
||||||
|
$className = static::$bindings[$className];
|
||||||
|
} else {
|
||||||
|
throw new Exception("Missing binding for interface: {$className}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!class_exists($className)) {
|
||||||
|
throw new Exception("Cannot resolve: {$className}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset(static::$instances[$className])) {
|
||||||
|
// If the instance has not been resolved before, resolve it
|
||||||
|
$reflectionClass = new ReflectionClass($className);
|
||||||
|
$constructor = $reflectionClass->getConstructor();
|
||||||
|
static::$instances[$className] = new $className(
|
||||||
|
...static::resolveParameterValues($constructor?->getParameters() ?? [])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return static::$instances[$className];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves parameter values by injecting dependencies.
|
||||||
|
*
|
||||||
|
* @param array<ReflectionParameter> $parameters
|
||||||
|
* @param array<string, mixed> $named
|
||||||
|
* Values injected into parameters whose name matches the key,
|
||||||
|
* taking precedence over optional defaults and DI resolution.
|
||||||
|
* Keys matching no parameter are ignored.
|
||||||
|
*
|
||||||
|
* @return array<mixed>
|
||||||
|
* @throws Exception If a primitive parameter does not have a default value.
|
||||||
|
*/
|
||||||
|
public static function resolveParameterValues(array $parameters, array $named = []): array
|
||||||
|
{
|
||||||
|
$values = [];
|
||||||
|
foreach ($parameters as $parameter) {
|
||||||
|
if ($parameter->isVariadic()) { // Skip variatic parameters
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists($parameter->getName(), $named)) { // Named values win over defaults and DI
|
||||||
|
$values[] = $named[$parameter->getName()];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($parameter->isOptional()) { // Always use the default value first
|
||||||
|
$values[] = $parameter->getDefaultValue();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$paramType = $parameter->getType();
|
||||||
|
if ($paramType === null) {
|
||||||
|
// If no type is declared, and it's not optional, we cannot resolve it.
|
||||||
|
throw new Exception(
|
||||||
|
"Untyped parameter '{$parameter}' expect at least a default value or must be optional."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($paramType->isBuiltin()) {
|
||||||
|
throw new Exception("Primitive parameter '{$parameter->getName()}' expects at least a default value.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$values[] = static::resolveInstance($paramType->getName());
|
||||||
|
}
|
||||||
|
return $values;
|
||||||
|
}
|
||||||
|
}
|
||||||
+1141
-74
File diff suppressed because it is too large
Load Diff
+62
-62
@@ -1,80 +1,80 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* View - DuckBrain
|
|
||||||
*
|
|
||||||
* Manejador de vistas simplificado.
|
|
||||||
*
|
|
||||||
* @author KJ
|
|
||||||
* @website https://kj2.me
|
|
||||||
* @licence MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Libs;
|
namespace Libs;
|
||||||
|
|
||||||
class View extends Neuron {
|
/**
|
||||||
|
* View - DuckBrain
|
||||||
/**
|
|
||||||
* Incluye el archivo.
|
|
||||||
*
|
*
|
||||||
* @param string $viewName Ruta relativa y el nommbre sin extensión del archivo.
|
* Simplified view handler.
|
||||||
* @param string $viewPath (opcional) Ruta donde se encuentra la vista.
|
*
|
||||||
* @param string $extension (opcional) Extensión del archivo.
|
* @author KJ
|
||||||
|
* @website https://kj2.me
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
class View extends Neuron
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Includes the file.
|
||||||
|
*
|
||||||
|
* @param string $viewName Relative path and filename without extension.
|
||||||
|
* @param string|null $viewPath (Optional) Path where the view file is located.
|
||||||
|
* @param string $extension (Optional) File extension.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function include(
|
protected function include(
|
||||||
string $viewName,
|
string $viewName,
|
||||||
string $viewPath = null,
|
?string $viewPath = null,
|
||||||
string $extension = 'php'
|
string $extension = 'php'
|
||||||
): void
|
): void {
|
||||||
{
|
if (
|
||||||
$view = $this;
|
isset($viewPath) &&
|
||||||
|
file_exists("$viewPath$viewName.$extension")
|
||||||
if (isset($viewPath) &&
|
) {
|
||||||
file_exists("$viewPath$viewName.$extension")) {
|
|
||||||
include("$viewPath$viewName.$extension");
|
include("$viewPath$viewName.$extension");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
include(ROOT_CORE."/Views/$viewName.$extension");
|
include(ROOT_CORE . "/Views/$viewName.$extension");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Función que "renderiza" las vistas
|
* Function that "renders" views.
|
||||||
*
|
*
|
||||||
* @param string $viewName Ruta relativa y el nommbre sin extensión del archivo.
|
* @param string $viewName Relative path and filename without extension.
|
||||||
* @param array|Neuron $params (opcional) Arreglo que podrá ser usado en la vista mediante $view ($param['index'] se usaría así: $view->index)
|
* @param array|Neuron $params (Optional) Array that can be used in the view
|
||||||
* @param string $viewPath (opcional) Ruta donde se encuentra la vista. En caso de que la vista no se encuentre en esa ruta, se usará la ruta por defecto "src/Views/".
|
* via $view ($param['index'] would be used as: $view->index).
|
||||||
* @param string $extension (opcional) Extensión del archivo.
|
* @param string|null $viewPath (Optional) Path where the view is located. If the
|
||||||
|
* view is not found in this path, the default path "src/Views/" will be used.
|
||||||
|
* @param string $extension (Optional) File extension.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function render(
|
public static function render(
|
||||||
string $viewName,
|
string $viewName,
|
||||||
array|Neuron $params = [],
|
array|Neuron $params = [],
|
||||||
string $viewPath = null,
|
?string $viewPath = null,
|
||||||
string $extension = 'php'
|
string $extension = 'php'
|
||||||
): void
|
): void {
|
||||||
{
|
|
||||||
$instance = new View($params);
|
$instance = new View($params);
|
||||||
$instance->html($viewName, $viewPath);
|
$instance->html($viewName, $viewPath, $extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renderiza las vistas HTML
|
* Renders HTML views.
|
||||||
*
|
*
|
||||||
* @param string $viewName Ruta relativa y el nommbre sin extensión del archivo ubicado en src/Views
|
* @param string $viewName Relative path and filename without extension located in src/Views.
|
||||||
* @param string $viewPath (opcional) Ruta donde se encuentra la vista. En caso de que la vista no se encuentre en esa ruta, se usará la ruta por defecto "src/Views/".
|
* @param string|null $viewPath (Optional) Path where the view is located. If the view is not
|
||||||
* @param string $extension (opcional) Extensión del archivo.
|
* found in this path, the default path "src/Views/" will be used.
|
||||||
|
* @param string $extension (Optional) File extension.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function html(
|
public function html(
|
||||||
string $viewName,
|
string $viewName,
|
||||||
string $viewPath = null,
|
?string $viewPath = null,
|
||||||
string $extension = 'php'
|
string $extension = 'php'
|
||||||
): void
|
): void {
|
||||||
{
|
|
||||||
$this->include(
|
$this->include(
|
||||||
$viewName,
|
$viewName,
|
||||||
$viewPath,
|
$viewPath,
|
||||||
@@ -83,47 +83,47 @@ class View extends Neuron {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renderiza código CSS.
|
* Renders CSS code.
|
||||||
*
|
*
|
||||||
* @param string $viewName Ruta relativa y el nommbre sin extensión del archivo ubicado en src/Views
|
* @param string $viewName Relative path and filename without extension located in src/Views.
|
||||||
* @param string $viewPath (opcional) Ruta donde se encuentra la vista. En caso de que la vista no se encuentre en esa ruta, se usará la ruta por defecto "src/Views/".
|
* @param string|null $viewPath (Optional) Path where the view is located. If the view is not
|
||||||
* @param string $extension (opcional) Extensión del archivo.
|
* found in this path, the default path "src/Views/" will be used.
|
||||||
|
* @param string $extension (Optional) File extension.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function css(
|
public function css(
|
||||||
string $viewName,
|
string $viewName,
|
||||||
string $viewPath = null,
|
?string $viewPath = null,
|
||||||
string $extension = 'css'
|
string $extension = 'css'
|
||||||
): void
|
): void {
|
||||||
{
|
|
||||||
header("Content-type: text/css");
|
header("Content-type: text/css");
|
||||||
$this->include($viewName, $viewPath, $extension);
|
$this->include($viewName, $viewPath, $extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renderiza código Javascript.
|
* Renders Javascript code.
|
||||||
*
|
*
|
||||||
* @param string $viewName Ruta relativa y el nommbre sin extensión del archivo ubicado en src/Views
|
* @param string $viewName Relative path and filename without extension located in src/Views.
|
||||||
* @param string $viewPath (opcional) Ruta donde se encuentra la vista. En caso de que la vista no se encuentre en esa ruta, se usará la ruta por defecto "src/Views/".
|
* @param string|null $viewPath (Optional) Path where the view is located. If the view is not
|
||||||
* @param string $extension (opcional) Extensión del archivo.
|
* found in this path, the default path "src/Views/" will be used.
|
||||||
|
* @param string $extension (Optional) File extension.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function js(
|
public function js(
|
||||||
string $viewName,
|
string $viewName,
|
||||||
string $viewPath = null,
|
?string $viewPath = null,
|
||||||
string $extension = 'js'
|
string $extension = 'js'
|
||||||
): void
|
): void {
|
||||||
{
|
|
||||||
header("Content-type: application/javascript");
|
header("Content-type: application/javascript");
|
||||||
$this->include($viewName, $viewPath, $extension);
|
$this->include($viewName, $viewPath, $extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Imprime los datos en Json.
|
* Prints data as JSON.
|
||||||
*
|
*
|
||||||
* @param object|array $data Objeto o array que se imprimirá a JSON.
|
* @param object|array $data Object or array to be printed as JSON.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
@@ -134,9 +134,9 @@ class View extends Neuron {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Imprime los datos en texto plano
|
* Prints data as plain text.
|
||||||
*
|
*
|
||||||
* @param string $txt Contenido de texto.
|
* @param string $txt Text content.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
@@ -147,7 +147,7 @@ class View extends Neuron {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intenta devolver la url absoluta a partir de una ruta relativa.
|
* Attempts to return the absolute URL from a relative path.
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
*
|
*
|
||||||
@@ -155,10 +155,10 @@ class View extends Neuron {
|
|||||||
*/
|
*/
|
||||||
public static function route(string $path = '/'): string
|
public static function route(string $path = '/'): string
|
||||||
{
|
{
|
||||||
if (defined('SITE_URL') && !empty(SITE_URL))
|
if (defined('SITE_URL') && !empty(SITE_URL)) {
|
||||||
return rtrim(SITE_URL, '/').'/'.ltrim($path, '/');
|
return rtrim(SITE_URL, '/') . '/' . ltrim($path, '/');
|
||||||
|
}
|
||||||
|
|
||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|||||||
Reference in New Issue
Block a user