Carpeta helpers
This commit is contained in:
@@ -0,0 +1,87 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Función necesaria para detectar módulo correspondiente en base a la consulta del usuario
|
||||||
|
|
||||||
|
function detectarModulo($mensaje) {
|
||||||
|
|
||||||
|
$mensaje = strtolower($mensaje);
|
||||||
|
|
||||||
|
$mapa = [
|
||||||
|
|
||||||
|
'clientes' => [
|
||||||
|
'cliente',
|
||||||
|
'clientes'
|
||||||
|
],
|
||||||
|
|
||||||
|
'ventas' => [
|
||||||
|
'venta',
|
||||||
|
'ventas',
|
||||||
|
'factura',
|
||||||
|
'comprobante'
|
||||||
|
],
|
||||||
|
|
||||||
|
'servicios' => [
|
||||||
|
'servicio',
|
||||||
|
'servicios',
|
||||||
|
'reparacion',
|
||||||
|
'tecnico'
|
||||||
|
],
|
||||||
|
|
||||||
|
'productos' => [
|
||||||
|
'producto',
|
||||||
|
'productos',
|
||||||
|
'stock',
|
||||||
|
'categoria'
|
||||||
|
],
|
||||||
|
|
||||||
|
'pedidos' => [
|
||||||
|
'pedido',
|
||||||
|
'pedidos',
|
||||||
|
'remito'
|
||||||
|
],
|
||||||
|
|
||||||
|
'presupuestos' => [
|
||||||
|
'presupuesto',
|
||||||
|
'presupuestos',
|
||||||
|
'cotizacion'
|
||||||
|
],
|
||||||
|
|
||||||
|
'proveedores' => [
|
||||||
|
'proveedor',
|
||||||
|
'proveedores'
|
||||||
|
],
|
||||||
|
|
||||||
|
'usuarios' => [
|
||||||
|
'usuario',
|
||||||
|
'usuarios',
|
||||||
|
'admin',
|
||||||
|
'operador'
|
||||||
|
],
|
||||||
|
|
||||||
|
'informes' => [
|
||||||
|
'informe',
|
||||||
|
'informes',
|
||||||
|
'balance',
|
||||||
|
'grafico'
|
||||||
|
],
|
||||||
|
|
||||||
|
'copias_seguridad' => [
|
||||||
|
'backup',
|
||||||
|
'backups',
|
||||||
|
'copia',
|
||||||
|
'restaurar'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($mapa as $modulo => $palabras) {
|
||||||
|
|
||||||
|
foreach ($palabras as $palabra) {
|
||||||
|
|
||||||
|
if (str_contains($mensaje, $palabra)) {
|
||||||
|
return $modulo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'general';
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function encryptData($data) {
|
||||||
|
|
||||||
|
// Genera una clave de 256 bits a partir de APP_KEY (hash SHA-256)
|
||||||
|
|
||||||
|
$key = hash('sha256', APP_KEY);
|
||||||
|
|
||||||
|
// IV (Initialization Vector):
|
||||||
|
// valor aleatorio necesario para el cifrado CBC
|
||||||
|
// debe ser único por cada encriptación (16 bytes para AES)
|
||||||
|
|
||||||
|
$iv = random_bytes(16);
|
||||||
|
|
||||||
|
// Encripta los datos usando AES-256-CBC
|
||||||
|
|
||||||
|
$encrypted = openssl_encrypt(
|
||||||
|
$data, // dato original
|
||||||
|
'AES-256-CBC', // algoritmo de cifrado
|
||||||
|
$key, // clave derivada
|
||||||
|
0, // opciones (0 = salida base64 por defecto)
|
||||||
|
$iv // vector de inicialización
|
||||||
|
);
|
||||||
|
|
||||||
|
// Se concatena IV + dato encriptado y se codifica en base64 para poder almacenarlo o transportarlo como string
|
||||||
|
|
||||||
|
return base64_encode($iv . $encrypted);
|
||||||
|
}
|
||||||
|
|
||||||
|
function decryptData($data) {
|
||||||
|
|
||||||
|
// Regenera la misma clave usada en el cifrado
|
||||||
|
|
||||||
|
$key = hash('sha256', APP_KEY);
|
||||||
|
|
||||||
|
// Decodifica el string base64
|
||||||
|
|
||||||
|
$data = base64_decode($data);
|
||||||
|
|
||||||
|
// Extrae el IV (primeros 16 bytes)
|
||||||
|
|
||||||
|
$iv = substr($data, 0, 16);
|
||||||
|
|
||||||
|
// Extrae el contenido cifrado
|
||||||
|
|
||||||
|
$encrypted = substr($data, 16);
|
||||||
|
|
||||||
|
// Desencripta el contenido usando los mismos parámetros
|
||||||
|
|
||||||
|
return openssl_decrypt(
|
||||||
|
$encrypted,
|
||||||
|
'AES-256-CBC',
|
||||||
|
$key,
|
||||||
|
0,
|
||||||
|
$iv
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../helpers/crypto.php';
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../libs/phpmailer/src/PHPMailer.php';
|
||||||
|
require_once __DIR__ . '/../libs/phpmailer/src/SMTP.php';
|
||||||
|
require_once __DIR__ . '/../libs/phpmailer/src/Exception.php';
|
||||||
|
require_once __DIR__ . '/../controllers/configuracionController.php';
|
||||||
|
|
||||||
|
use PHPMailer\PHPMailer\PHPMailer;
|
||||||
|
use PHPMailer\PHPMailer\Exception;
|
||||||
|
|
||||||
|
function enviarMailServicioFinalizado($servicio, $insumos, $cliente) {
|
||||||
|
|
||||||
|
// VERIFICAMOS SI LAS NOTIFICACIONES ESTAN ACTIVADAS
|
||||||
|
// OBTENEMOS MAIL Y CONTRASEÑA
|
||||||
|
|
||||||
|
$configuracionmodel = new configuracionModel();
|
||||||
|
$datosConfig = $configuracionmodel->obtenerDatosEnvioMail();
|
||||||
|
|
||||||
|
if (isset($datosConfig['contrasenia_emisor'])) {
|
||||||
|
$datosConfig['contrasenia_emisor'] = decryptData($datosConfig['contrasenia_emisor']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((int) $datosConfig['mail_automatico'] === 1) {
|
||||||
|
|
||||||
|
$mail = new PHPMailer(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// CONFIG SMTP
|
||||||
|
|
||||||
|
$mail->isSMTP();
|
||||||
|
$mail->Host = 'smtp.gmail.com';
|
||||||
|
$mail->SMTPAuth = true;
|
||||||
|
$mail->Username = $datosConfig['email_emisor'];
|
||||||
|
$mail->Password = $datosConfig['contrasenia_emisor'];
|
||||||
|
$mail->SMTPSecure = 'tls';
|
||||||
|
$mail->Port = 587;
|
||||||
|
|
||||||
|
// CODIFICACIÓN (evita problemas con tildes)
|
||||||
|
|
||||||
|
$mail->CharSet = 'UTF-8';
|
||||||
|
|
||||||
|
// REMITENTE
|
||||||
|
|
||||||
|
$mail->setFrom($datosConfig['email_emisor'], 'ByteCenter');
|
||||||
|
|
||||||
|
// DESTINATARIO
|
||||||
|
|
||||||
|
if (empty($cliente['email'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$mail->addAddress($cliente['email'], $cliente['nombre'] . ' ' . $cliente['apellido']);
|
||||||
|
|
||||||
|
// DEFINIMOS ARRAY HTML DE INSUMOS UTILIZADOS
|
||||||
|
|
||||||
|
$productos = "";
|
||||||
|
|
||||||
|
if (!empty($insumos)) {
|
||||||
|
|
||||||
|
foreach ($insumos as $i) {
|
||||||
|
$productos .= "
|
||||||
|
<tr>
|
||||||
|
<td style='text-align: center;'>{$i['marca']} {$i['modelo']}</td>
|
||||||
|
<td style='text-align: right;'>$ {$i['precio_unitario']}</td>
|
||||||
|
<td style='text-align: right;'>{$i['cantidad']}</td>
|
||||||
|
<td style='text-align: right;'>$ {$i['subtotal']}</td>
|
||||||
|
</tr>
|
||||||
|
";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// POR SI LA LISTA VIENE VACIA
|
||||||
|
|
||||||
|
if (empty($insumos)) {
|
||||||
|
$productos = "
|
||||||
|
<tr>
|
||||||
|
<td colspan='4' align='center' style='text-align:center; padding:10px;'>
|
||||||
|
-
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SANEAMIENTO DE HORA (substraer segundos)
|
||||||
|
|
||||||
|
$datosConfig['hora_apertura_maniana'] = substr($datosConfig['hora_apertura_maniana'], 0, 5);
|
||||||
|
$datosConfig['hora_cierre_maniana'] = substr($datosConfig['hora_cierre_maniana'], 0, 5);
|
||||||
|
$datosConfig['hora_apertura_tarde'] = substr($datosConfig['hora_apertura_tarde'], 0, 5);
|
||||||
|
$datosConfig['hora_cierre_tarde'] = substr($datosConfig['hora_cierre_tarde'], 0, 5);
|
||||||
|
|
||||||
|
// CONTENIDO
|
||||||
|
|
||||||
|
$numeroServicio = '0001-' . str_pad($servicio['id'], 8, '0', STR_PAD_LEFT);
|
||||||
|
|
||||||
|
$mail->isHTML(true);
|
||||||
|
$mail->Subject = 'ByteCenter - Servicio a Realizar - N° ' . $numeroServicio;
|
||||||
|
|
||||||
|
$mail->Body = "
|
||||||
|
<h2>Servicio a Realizar</h2>
|
||||||
|
|
||||||
|
<p><strong>Cliente: </strong> ". $cliente['nombre'] . ' ' . $cliente['apellido'] ."</p>
|
||||||
|
<p><strong>Equipo: </strong> ". $servicio['equipo'] ."</p>
|
||||||
|
<p><strong>Problema: </strong> ". $servicio['problema']. "</p>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<h2>Detalles de Servicio</h2>
|
||||||
|
<h3>Trabajo a Relizar</h3>
|
||||||
|
<p>". $servicio['detalle_realizado']. "</p>
|
||||||
|
|
||||||
|
<h3>Insumos a Utilizar</h3>
|
||||||
|
|
||||||
|
<table border='1' cellpadding='6' cellspacing='0' style='border-collapse: collapse; text-align: right;'>
|
||||||
|
<tr>
|
||||||
|
<th>Modelo</th>
|
||||||
|
<th>Precio Unitario</th>
|
||||||
|
<th>Cantidad</th>
|
||||||
|
<th>Subtotal</th>
|
||||||
|
</tr>
|
||||||
|
$productos
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h3>Totales</h3>
|
||||||
|
<p><strong>Mano de obra: </strong> ". "$" . number_format($servicio['mano_obra'], 2, ',', '.'). "</p>
|
||||||
|
<p><strong>Total: </strong> ". "$" . number_format($servicio['total'], 2, ',', '.'). "</p>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<p>Esperamos su confirmación para la realización del servicio, en caso de cancelarlo podrá retirar el equipo en nuestro local ubicado en {$datosConfig['direccion']}, {$datosConfig['ciudad']} y abonar el monto por revisión y desarme: $ {$datosConfig['cargo_cancelacion_servicio']}.</p>
|
||||||
|
<p>Nuestros horarios de atención son: {$datosConfig['hora_apertura_maniana']} - {$datosConfig['hora_cierre_maniana']} y {$datosConfig['hora_apertura_tarde']} - {$datosConfig['hora_cierre_tarde']}.</p>
|
||||||
|
<p>Por cualquier duda o consulta: {$datosConfig['telefono']} - {$datosConfig['email']}.</p>
|
||||||
|
<p>Gracias por confiar en nuestro servicio técnico.</p>
|
||||||
|
<p>ByteCenter</p>
|
||||||
|
";
|
||||||
|
|
||||||
|
// Versión texto plano (por compatibilidad)
|
||||||
|
|
||||||
|
$mail->AltBody = "Servicio finalizado - Total: $ {$servicio['total']}";
|
||||||
|
|
||||||
|
$mail->send();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
|
||||||
|
// Log interno
|
||||||
|
|
||||||
|
error_log($e->getMessage());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../helpers/crypto.php';
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../libs/phpmailer/src/PHPMailer.php';
|
||||||
|
require_once __DIR__ . '/../libs/phpmailer/src/SMTP.php';
|
||||||
|
require_once __DIR__ . '/../libs/phpmailer/src/Exception.php';
|
||||||
|
require_once __DIR__ . '/../controllers/configuracionController.php';
|
||||||
|
|
||||||
|
use PHPMailer\PHPMailer\PHPMailer;
|
||||||
|
use PHPMailer\PHPMailer\Exception;
|
||||||
|
|
||||||
|
function enviarMailServicioFinalizado($servicio, $insumos, $cliente) {
|
||||||
|
|
||||||
|
// VERIFICAMOS SI LAS NOTIFICACIONES ESTAN ACTIVADAS
|
||||||
|
// OBTENEMOS MAIL Y CONTRASEÑA
|
||||||
|
|
||||||
|
$configuracionmodel = new configuracionModel();
|
||||||
|
$datosConfig = $configuracionmodel->obtenerDatosEnvioMail();
|
||||||
|
|
||||||
|
if (isset($datosConfig['contrasenia_emisor'])) {
|
||||||
|
$datosConfig['contrasenia_emisor'] = decryptData($datosConfig['contrasenia_emisor']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((int) $datosConfig['mail_automatico'] === 1) {
|
||||||
|
|
||||||
|
$mail = new PHPMailer(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// CONFIG SMTP
|
||||||
|
|
||||||
|
$mail->isSMTP();
|
||||||
|
$mail->Host = 'smtp.gmail.com';
|
||||||
|
$mail->SMTPAuth = true;
|
||||||
|
$mail->Username = $datosConfig['email_emisor'];
|
||||||
|
$mail->Password = $datosConfig['contrasenia_emisor'];
|
||||||
|
$mail->SMTPSecure = 'tls';
|
||||||
|
$mail->Port = 587;
|
||||||
|
|
||||||
|
// CODIFICACIÓN (evita problemas con tildes)
|
||||||
|
|
||||||
|
$mail->CharSet = 'UTF-8';
|
||||||
|
|
||||||
|
// REMITENTE
|
||||||
|
|
||||||
|
$mail->setFrom($datosConfig['email_emisor'], 'ByteCenter');
|
||||||
|
|
||||||
|
// DESTINATARIO
|
||||||
|
|
||||||
|
if (empty($cliente['email'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$mail->addAddress($cliente['email'], $cliente['nombre'] . ' ' . $cliente['apellido']);
|
||||||
|
|
||||||
|
// DEFINIMOS ARRAY HTML DE INSUMOS UTILIZADOS
|
||||||
|
|
||||||
|
$productos = "";
|
||||||
|
|
||||||
|
if (!empty($insumos)) {
|
||||||
|
|
||||||
|
foreach ($insumos as $i) {
|
||||||
|
$productos .= "
|
||||||
|
<tr>
|
||||||
|
<td style='text-align: center;'>{$i['marca']} {$i['modelo']}</td>
|
||||||
|
<td style='text-align: center;'>$ {$i['precio_unitario']}</td>
|
||||||
|
<td style='text-align: center;'>{$i['cantidad']}</td>
|
||||||
|
<td style='text-align: center;'>$ {$i['subtotal']}</td>
|
||||||
|
</tr>
|
||||||
|
";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// POR SI LA LISTA VIENE VACIA
|
||||||
|
|
||||||
|
if (empty($insumos)) {
|
||||||
|
$productos = "
|
||||||
|
<tr>
|
||||||
|
<td colspan='4' align='center' style='text-align: center; padding: 10px;'>
|
||||||
|
-
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
";
|
||||||
|
}
|
||||||
|
|
||||||
|
// SANEAMIENTO DE HORA (substraer segundos)
|
||||||
|
|
||||||
|
$datosConfig['hora_apertura_maniana'] = substr($datosConfig['hora_apertura_maniana'], 0, 5);
|
||||||
|
$datosConfig['hora_cierre_maniana'] = substr($datosConfig['hora_cierre_maniana'], 0, 5);
|
||||||
|
$datosConfig['hora_apertura_tarde'] = substr($datosConfig['hora_apertura_tarde'], 0, 5);
|
||||||
|
$datosConfig['hora_cierre_tarde'] = substr($datosConfig['hora_cierre_tarde'], 0, 5);
|
||||||
|
|
||||||
|
// CONTENIDO
|
||||||
|
|
||||||
|
$numeroServicio = '0001-' . str_pad($servicio['id'], 8, '0', STR_PAD_LEFT);
|
||||||
|
|
||||||
|
$mail->isHTML(true);
|
||||||
|
$mail->Subject = 'ByteCenter - Servicio Finalizado - N°' . $numeroServicio;
|
||||||
|
|
||||||
|
$mail->Body = "
|
||||||
|
<h2>Servicio Finalizado</h2>
|
||||||
|
|
||||||
|
<p><strong>Cliente: </strong> ". $cliente['nombre'] . ' ' . $cliente['apellido'] ."</p>
|
||||||
|
<p><strong>Equipo: </strong> ". $servicio['equipo'] ."</p>
|
||||||
|
<p><strong>Problema: </strong> ". $servicio['problema']. "</p>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<h2>Detalles de Servicio</h2>
|
||||||
|
<h3>Trabajo Realizado</h3>
|
||||||
|
<p>". $servicio['detalle_realizado']. "</p>
|
||||||
|
|
||||||
|
<h3>Insumos Utilizados</h3>
|
||||||
|
|
||||||
|
<table border='1' cellpadding='6' cellspacing='0' style='border-collapse: collapse; text-align: center;'>
|
||||||
|
<tr>
|
||||||
|
<th>Modelo</th>
|
||||||
|
<th>Precio Unitario</th>
|
||||||
|
<th>Cantidad</th>
|
||||||
|
<th>Subtotal</th>
|
||||||
|
</tr>
|
||||||
|
$productos
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h3>Totales</h3>
|
||||||
|
<p><strong>Mano de obra: </strong> ". "$" . number_format($servicio['mano_obra'], 2, ',', '.'). "</p>
|
||||||
|
<p><strong>Total: </strong> ". "$" . number_format($servicio['total'], 2, ',', '.'). "</p>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<p>Cuando desee puede pasar por nuestro local para retirar su equipo, nos encontramos en {$datosConfig['direccion']}, {$datosConfig['ciudad']}.</p>
|
||||||
|
<p>Nuestros horarios de atención son: {$datosConfig['hora_apertura_maniana']} - {$datosConfig['hora_cierre_maniana']} y {$datosConfig['hora_apertura_tarde']} - {$datosConfig['hora_cierre_tarde']}.</p>
|
||||||
|
<p>Por cualquier duda o consulta: {$datosConfig['telefono']} - {$datosConfig['email']}.</p>
|
||||||
|
<p>Gracias por confiar en nuestro servicio técnico.</p>
|
||||||
|
<p>ByteCenter</p>
|
||||||
|
";
|
||||||
|
|
||||||
|
// Versión texto plano (por compatibilidad)
|
||||||
|
|
||||||
|
$mail->AltBody = "Servicio finalizado - Total: $ {$servicio['total']}";
|
||||||
|
|
||||||
|
$mail->send();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
|
||||||
|
// Log interno
|
||||||
|
|
||||||
|
error_log($e->getMessage());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../helpers/crypto.php';
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../libs/phpmailer/src/PHPMailer.php';
|
||||||
|
require_once __DIR__ . '/../libs/phpmailer/src/SMTP.php';
|
||||||
|
require_once __DIR__ . '/../libs/phpmailer/src/Exception.php';
|
||||||
|
require_once __DIR__ . '/../models/configuracionModel.php';
|
||||||
|
|
||||||
|
use PHPMailer\PHPMailer\PHPMailer;
|
||||||
|
use PHPMailer\PHPMailer\Exception;
|
||||||
|
|
||||||
|
function enviarCodigoRecuperacion($email, $codigo) {
|
||||||
|
|
||||||
|
$mail = new PHPMailer(true);
|
||||||
|
|
||||||
|
$configuracionmodel = new configuracionModel();
|
||||||
|
$datosConfig = $configuracionmodel->obtenerDatosEnvioMail();
|
||||||
|
|
||||||
|
if (isset($datosConfig['contrasenia_emisor'])) {
|
||||||
|
$datosConfig['contrasenia_emisor'] = decryptData($datosConfig['contrasenia_emisor']);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// CONFIG SMTP
|
||||||
|
|
||||||
|
$mail->isSMTP();
|
||||||
|
$mail->Host = 'smtp.gmail.com';
|
||||||
|
$mail->SMTPAuth = true;
|
||||||
|
$mail->Username = $datosConfig['email_emisor'];
|
||||||
|
$mail->Password = $datosConfig['contrasenia_emisor'];
|
||||||
|
$mail->SMTPSecure = 'tls';
|
||||||
|
$mail->Port = 587;
|
||||||
|
|
||||||
|
// CODIFICACIÓN (evita problemas con tildes)
|
||||||
|
|
||||||
|
$mail->CharSet = 'UTF-8';
|
||||||
|
|
||||||
|
// REMITENTE
|
||||||
|
|
||||||
|
$mail->setFrom($datosConfig['email_emisor'], 'ByteCenter');
|
||||||
|
|
||||||
|
// DESTINATARIO
|
||||||
|
|
||||||
|
if (empty($email)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$mail->addAddress($email);
|
||||||
|
|
||||||
|
$mail->isHTML(true);
|
||||||
|
$mail->Subject = 'Recuperación de contraseña';
|
||||||
|
|
||||||
|
$mail->Body = "
|
||||||
|
<h3>Recuperación de contraseña</h3>
|
||||||
|
|
||||||
|
<p>Hemos recibido una solicitud para restablecer su contraseña.</p>
|
||||||
|
|
||||||
|
<p>Para continuar con el proceso, utilice el siguiente código de verificación:</p>
|
||||||
|
|
||||||
|
<h2 style='letter-spacing:2px;'>$codigo</h2>
|
||||||
|
|
||||||
|
<p>Este código es válido por un período de 10 minutos.</p>
|
||||||
|
|
||||||
|
<p>Si usted no realizó esta solicitud, puede ignorar este mensaje de forma segura.</p>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<p>Atentamente,<br>
|
||||||
|
Equipo de ByteCenter</p>
|
||||||
|
";
|
||||||
|
|
||||||
|
$mail->send();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
|
||||||
|
// Log interno
|
||||||
|
|
||||||
|
error_log($e->getMessage());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
Función encargada de comunicarse con la API de Groq
|
||||||
|
|
||||||
|
Recibe:
|
||||||
|
- Un array con todos los mensajes de contexto: system, historial y mensaje actual del usuario
|
||||||
|
|
||||||
|
Devuelve:
|
||||||
|
- success -> true/false
|
||||||
|
- content -> respuesta del modelo
|
||||||
|
- error -> mensaje de error en caso de fallo
|
||||||
|
*/
|
||||||
|
|
||||||
|
function consultarChatbot($mensajes) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
DATA
|
||||||
|
|
||||||
|
Arma el cuerpo JSON que será enviado a la API
|
||||||
|
|
||||||
|
model:
|
||||||
|
- Modelo de IA a utilizar
|
||||||
|
|
||||||
|
messages:
|
||||||
|
- Conversación completa
|
||||||
|
|
||||||
|
temperature:
|
||||||
|
- Nivel de creatividad
|
||||||
|
- Mientras mas bajo, más preciso y menos inventa
|
||||||
|
*/
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'model' => 'llama-3.1-8b-instant',
|
||||||
|
|
||||||
|
'messages' => $mensajes,
|
||||||
|
|
||||||
|
'temperature' => 0.2
|
||||||
|
];
|
||||||
|
|
||||||
|
/*
|
||||||
|
HEADERS HTTP
|
||||||
|
|
||||||
|
Content-Type:
|
||||||
|
- Indicamos que enviamos JSON
|
||||||
|
|
||||||
|
Authorization:
|
||||||
|
- Token Bearer con la API KEY
|
||||||
|
- Se obtiene desde el archivo .env cargado en $_ENV
|
||||||
|
*/
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'Content-Type: application/json',
|
||||||
|
'Authorization: Bearer ' . $_ENV['GROQ_API_KEY']
|
||||||
|
];
|
||||||
|
|
||||||
|
/*
|
||||||
|
INICIALIZAR CURL
|
||||||
|
|
||||||
|
cURL permite realizar solicitudes HTTP desde PHP
|
||||||
|
*/
|
||||||
|
|
||||||
|
$ch = curl_init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
CONFIGURACIÓN CURL
|
||||||
|
|
||||||
|
CURLOPT_URL
|
||||||
|
- Endpoint oficial de Groq
|
||||||
|
|
||||||
|
CURLOPT_RETURNTRANSFER
|
||||||
|
- Hace que la respuesta se devuelva como string
|
||||||
|
- Si no estuviera, la imprimiría directamente
|
||||||
|
|
||||||
|
CURLOPT_POST
|
||||||
|
- Indicamos que la petición será POST
|
||||||
|
|
||||||
|
CURLOPT_HTTPHEADER
|
||||||
|
- Enviamos headers HTTP
|
||||||
|
|
||||||
|
CURLOPT_POSTFIELDS
|
||||||
|
- Enviamos el body JSON
|
||||||
|
*/
|
||||||
|
|
||||||
|
curl_setopt_array($ch, [
|
||||||
|
|
||||||
|
CURLOPT_URL => 'https://api.groq.com/openai/v1/chat/completions',
|
||||||
|
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
|
||||||
|
CURLOPT_POST => true,
|
||||||
|
|
||||||
|
CURLOPT_HTTPHEADER => $headers,
|
||||||
|
|
||||||
|
CURLOPT_POSTFIELDS => json_encode($data)
|
||||||
|
]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
EJECUTAR CONSULTA
|
||||||
|
|
||||||
|
- Se realiza la petición HTTP a Groq
|
||||||
|
*/
|
||||||
|
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
|
||||||
|
/*
|
||||||
|
ERROR CURL
|
||||||
|
|
||||||
|
Detecta errores de conexión reales
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (curl_errno($ch)) {
|
||||||
|
|
||||||
|
$error = curl_error($ch);
|
||||||
|
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'error' => $error
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
HTTP STATUS CODE
|
||||||
|
|
||||||
|
Obtenemos el código HTTP de la respuesta
|
||||||
|
*/
|
||||||
|
|
||||||
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
CERRAR cURL
|
||||||
|
|
||||||
|
Liberamos recursos
|
||||||
|
*/
|
||||||
|
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
/*
|
||||||
|
RATE LIMIT
|
||||||
|
|
||||||
|
Groq limita la cantidad de tokens por minuto
|
||||||
|
|
||||||
|
429 = demasiadas consultas o contexto muy grande
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ($httpCode === 429) {
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'error' => 'Límite temporal alcanzado. Esperá unos segundos.'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
OTROS ERRORES HTTP
|
||||||
|
|
||||||
|
Si la respuesta no fue 200, devolvemos error (200 -> OK)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ($httpCode !== 200) {
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'error' => "HTTP ERROR {$httpCode}: {$response}"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
DECODIFICAR JSON
|
||||||
|
|
||||||
|
Convertimos la respuesta JSON de Groq en array PHP
|
||||||
|
*/
|
||||||
|
|
||||||
|
$resultado = json_decode($response, true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
RESPUESTA FINAL
|
||||||
|
|
||||||
|
choices[0]['message']['content']
|
||||||
|
|
||||||
|
Es donde Groq devuelve el texto generado
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
|
||||||
|
'content' => $resultado['choices'][0]['message']['content'] ?? 'Sin respuesta.'
|
||||||
|
];
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user