🧑 Nombre del desarrollador: Isaac Navajas Pozo

👍🏻 Linkedin: https://www.linkedin.com/in/isaac-navajas-pozo/

🐘 Lenguaje: PHP

👨‍🎓 Proyecto: Master de PHP en Universidad Nebrija

⚗️ Utilidad: Framework con core básico para tener 100% del control del código

📜 Documentación: https://php-framework.com


Configuración inicial para el archivo .env:

# Generar un vector de inicialización (IV) y una clave (KEY) para el archivo .env. Se utilizarán para cifrar el helper de tokens y la contraseña de la base de datos en .env.

- Random key [KEY=]: MAD#2xe1cKplWdbkPYbQbvgjfK3PbcVV

- Random IV [IV=]: caTbZoyTR0ceX4zm

# Utilizando el vector de inicialización (IV) y la clave (KEY) del archivo guardado en .env, se procederá a cifrar la contraseña proporcionada a través del controlador.

- Contraseña de la base de datos [DB_PASS=]: pBEXW8qMPWvPbzZl7/vUpQ==



Documentación del framework iSNF:

# Esquema de comandos::
# documentación vf.1.0.7

======[🚀 KERNEL ]============================================================================================
## 🐸 Kernel · requires ($this->helper, $this->modal, $this->view, Url::asset) $:
(-̶●̃益●̶̃ ) controller:
# llama un helper
$this->helper('url.php');
$this->helper('dates.php');
Dates::fechaLarga('2025-06-13');

# llama archivo en modal
private $exampleModel;
$this->modal('example/exampleModel.php');
$this->exampleModel = new ExampleModel();
$user = $this->exampleModel->getUser();

$data = array(
    'titulo' => 'iSNF · Página de inicio',
    'descripcion' => 'iSNF es un framework...',
);
$this->view('datesView.php', $data);

(-̶●̃益●̶̃ ) view :
# imprimir valor del array enviado el controlador
<title><?php echo $data['titulo']; ?></title>
<p><?php echo $data['descripcion']; ?></p>
# llama archivo multimedia de /app/public/src
<link rel="icon" href="<?= Url::asset('iSNF.png');?>" type="image/x-icon">

(-̶●̃益●̶̃ ) router :
# archivo .autoload para rutas 
Http::autoload('.autoload');

# Definir ruta 404
Http::error(['controller' => 'ErrorController', 'method' => 'notFound']);

======[🚀 HELPERS · Shūkaku]==================================================================================
## 🐸 paquete de helpers "Shūkaku", desarrollados por Isaac Navajas Pozo.
# el acceso a los helpers se realiza a través de operadores de resolución de ámbito.

## 🐸 Helpers · dates $:
(-̶●̃益●̶̃ ) controlador :
# Español por defecto
echo FechaHelper::fechaCorta('2025-06-13');             // 13/06/2025
echo FechaHelper::fechaLarga('2025-06-13');             // Viernes 13 de junio de 2025
# Americano
echo FechaHelper::fechaLarga('2025-06-13', 'en_US');    // Friday, June 13, 2025

## 🐸 Helpers · debug $:
(-̶●̃益●̶̃ ) .env :
# defaultPassword => Gythdruop$11
vim .env
-------------------------------------------------------
# db
DB_HOST=localhost
DB_USER=db_u4445
DB_PASS=pBEXW8qMPWvPbzZl7/vUpQ==
DB_NAME=db_u04
KEY=pHtKs!2FNyU5%aNPoTfRcZixVUUahYBu
IV=Vxii6oTg2zDPW7gH

# data
VERSION=1.2.0
ERRORS=true
TRACES = true
LOGS = true
-------------------------------------------------------

(-̶●̃益●̶̃ ) controlador :
$usuario = ['id' => 5, 'nombre' => 'Juan'];
Debug::kill($usuario);

Debug::trace('Mensaje opcional');

# si no existe el archivo nombrado lo crea y escribe el registro
Debug::log('errores.log', 'Usuario no encontrado');
Debug::log('debug.log', 'Consulta SQL ejecutada correctamente');

## 🐸 Helpers · emails $:
(-̶●̃益●̶̃ ) controlador (ejemplo 1 · envío a un correo) :
Email::init('noreply@tuapp.com', 'Tu App');
Email::addRecipient('destino@dominio.com');
Email::addCc('copia@dominio.com');
Email::addBcc('oculto@dominio.com');

Email::setSubject('Ejemplo avanzado de email');
# con el segundo parametro en true puedo pasar html directamente
// Email::setBody("Correo en texto plano.");
# paso la dirección de la vista html directamente
Email::setBodyFromView('vista-email.php', ['nombre' => 'Elliot']);
Email::addAttachment('/ruta/absoluta/al/archivo.pdf');

if (Email::send()) {
 echo "Enviado correctamente";
} else {
 echo "Error al enviar";
}

(-̶●̃益●̶̃ ) controlador (ejemplo 2 envío a varios correos)] :
Email::init('noreply@tuapp.com', 'Mi App');
Email::setSubject('Notificación importante');
Email::setBody('Este es un mensaje privado para ti.', false);
Email::addCc('copia@dominio.com');
Email::addBcc('oculto@dominio.com');
Email::addAttachment('/ruta/al/archivo.pdf');

$destinatarios = ['user1@dominio.com', 'user2@dominio.com', 'user3@dominio.com',];
Email::sendToMultiple($destinatarios);

## 🐸 Helpers · image $:
(-̶●̃益●̶̃ ) controlador :
# Pasar imagen a base64
$base64 = Image::toBase64('/ruta/a/imagen.jpg');
if ($base64) { echo $base64; }

# Guardar imagen desde base64
$success = Image::fromBase64($base64, '/ruta/destino/nueva_imagen.jpg');
if ($success) { echo "Guardado OK"; }

## 🐸 Helpers · lang $:
(-̶●̃益●̶̃ ) controlador : :
# cargar idioma español
Lang::init('es');
echo Lang::get('welcome');

# Cambiar idioma a inglés
Lang::setLang('en');
echo Lang::get('welcome');

## 🐸 Helpers · login $:
(-̶●̃益●̶̃ ) controlador  1 :
Login::init($pdo);
$csrf = Login::generateCsrfToken();
$this->view('login.php', $csrf);

(-̶●̃益●̶̃ ) vista 1 :
# agrego un input oculto en el formulario de registro con el CSRF
<input type="hidden" name="csrf_token" value="<*php htmlspecialchars($csrf); ?>">

(-̶●̃益●̶̃ ) controlador 2 :
if (Login::authenticate('user', 'pass', $csrf)) {
    echo "Login OK, ID: " . Login::getUserId();
}

## 🐸 Helpers · session $:
(-̶●̃益●̶̃ ) controlador :
Session::init('MYAPPSESSID', ['secure' => false]);
Session::start();

Session::set('user_id', 123);
echo Session::get('user_id');

Session::delete('user_id');
Session::regenerate();
Session::destroy();

## 🐸 Helpers · tokenEncryption $:
(-̶●̃益●̶̃ ) controlador :
require_once './iSNF/helpers/tokenEncryption.php';
# Generador de tokens 
require_once './iSNF/helpers/tokenEncryption.php';
$mensaje = "texto secreto";
$cifrado = tokenEncryption::encrypt($mensaje, $key, $iv);
$descifrado = tokenEncryption::decrypt($cifrado, $key, $iv);

(-̶●̃益●̶̃ ) generar IV y key aleatorios:
$key = tokenEncryption::randomPseudoKEY();
$iv = tokenEncryption::randomPseudoIV();

## 🐸 Helpers · url $:
(-̶●̃益●̶̃ ) controlador :
Url::redirect();                     // Redirige a "/"
Url::redirect('/dashboard');         // Redirige a https://dominio/dashboard
Url::redirect('https://otra.com');   // Redirige a URL externa

echo Url::base();                    // https://dominio.com
echo Url::current();                 // https://dominio.com/ruta/actual

if (Url::isSecure()) { echo "Conexión segura (HTTPS)"; }

(-̶●̃益●̶̃ ) vista :
echo Url::asset('css/estilo.css');   // https://dominio.com/css/estilo.css

## 🐸 Helpers · internaShel $:
(-̶●̃益●̶̃ ) controlador :
$this->helper('internalShell.php');
# se pueden asignar un rango de direcciones IP privadas como 192.168.1.XX
$shell = new InternalShell(['44.745.334.134', '192.168.1.']);
$shell->run();

(-̶●̃益●̶̃ ) ruta :
Http::get('/terminal', ['controller' => 'exampleController', 'method' => 'Terminal']);

## 🐸 Helpers · sanitizer $:
(-̶●̃益●̶̃ ) controlador :
$this->helper('sanitizer.php');
$data = $_POST;
# controlo el tipado desde los datos que voy a enviar
$limpio = Sanitizer::sanitizeArray($data, array(
    'nombre'    => 'forceString',
    'edad'      => 'forceInt',
    'activo'    => 'forceBool',
    'email'     => 'forceEmail',
    'url'       => 'forceUrl',
    'slug'      => 'forceSlug',
    'uuid'      => 'forceUuid',
    'precio'    => 'forcePrecio',
    'fecha'     => 'forceDateTime',  // Devuelve objeto DateTime
));

## 🐸 Helpers · pdfMiniGenerator $:
# un generador de pdf básico
(-̶●̃益●̶̃ ) controlador :
$this->helper('pdfMiniGenerator.php');
$this->helper('url.php');
$pdf = new PdfMiniGenerator('A4');
$html = $this->view('pdf/prueba.php');
$pdf->outputToBrowser($html, Url::asset('/downloads/reporte_letter.pdf'));

(-̶●̃益●̶̃ ) vista :
'<a href="<?= Url::asset('/downloads/reporte_letter.pdf');?>" download>Descargar PDF</a>';

======[🚀 HELPERS - WRAPPERS · Shūkaku]=======================================================================
## 🐸 Wrapper · dataTableWrapper $:
# $dt = new DataTableWrapper($selectorTable, $Options = [], array $filterCols = [])
# $dt->render($data, $columns);

# [ejemplo1]
(-̶●̃益●̶̃ ) controlador :
session_start();
$data = [
    ['Name' => 'Alice', 'Role' => 'Admin', 'Status' => 'Active'],
    ['Name' => 'Bob', 'Role' => 'User', 'Status' => 'Inactive'],
    ...
];
$columns = ['Name', 'Role', 'Status'];
$filters = [1, 2];                  // índice de columnas con filtros (Role, Status)

(-̶●̃益●̶̃ ) vista :
$dt = new DataTableWrapper('myTable', [], $filters);
$dt->render($data, $columns);

# [ejemplo2]
(-̶●̃益●̶̃ ) vista :
$options = ['paging' => false, 'searching' => false,];
$dt = new DataTableWrapper('table2', $options, [0]);
$dt->render($data, ['Name', 'Role', 'Status']);
# Changelog:: 
# 🚀 iSNF · Desarrollo por Isaac Navajas Pozo

## [vf.1.2.2] - 2025-07-31:
- Corrección en rutas con campos dinámicos.
- Agrego archivo robots.txt.
- Desarrollo avanzado de los helpers (internalShell, sanitizer y pdfMiniGenerator).
- Eliminación de helper validate.

## [vf.1.2.1] - 2025-06-21:
- Modifico el sistema de rutas.
- Agrego el método error en Http, para declarar la página de error de forma dinámica.
- Agrego el método autoload en Http.
- Agrego el método de log en Debug con sus sistemas de carpetas.
- Diseño la página pricipal de instalación con la documentación del framework.
- Genero IV random, key random y password en página principal, para una configuración inicial agíl.

## [vf.1.2.0] - 2025-06-13:
- Cambio de MVC a sistema MMVC (modularizado).
- Agrego archivo ".autoload" para las rutas.
- Cambio las instancias de objetos a operadores de resolución de ámbito para diferenciar los helpers Shūkaku.
- Desarrollo avanzado de los helpers (dates, debug, emails, images, lang, logins, sessions, validate, tokenEncryption y url).
- Implementación de wrappers (dataTableWrapper).

## [vf.1.1.2] - 2025-05-01:
- Mejoras en el rendimiento.
- Actualización de dependencias.
- Desarrollo de rutas.

## [vf.1.1.0] - 2025-03-21:
- Adaptación del framework pnkd a un sistema de trabajo para administradores de sistemas.
- Desarrollo de variables de entorno.
- Desarrollo en depurador de tiempo real.
- Desarrollo el kernel.
- Modifico la arquitectura y el sistema de carpetas.

## [vf.1.1.0] - 2025-03-19:
- Versión final de framework pnkd, proyecto de fin de master de la Universidad de Nebrija.