Cambios para la edicion de correos en pasarela
This commit is contained in:
14
.env
14
.env
@@ -17,7 +17,7 @@ DEV_API_KEY = jNJdG9zBY92NSAALgnEdsoEIRycJiAScB6pBgIADsyg=
|
|||||||
#VARIABLES DB
|
#VARIABLES DB
|
||||||
DB_HOST = 192.168.100.127
|
DB_HOST = 192.168.100.127
|
||||||
DB_USER = gateway
|
DB_USER = gateway
|
||||||
DB_PASS = 7Zrs5447JkLReHH
|
DB_PASS =
|
||||||
DB_NAME = gateway
|
DB_NAME = gateway
|
||||||
|
|
||||||
#VARIABLES DB
|
#VARIABLES DB
|
||||||
@@ -27,14 +27,14 @@ DEV_DB_PASS =
|
|||||||
DEV_DB_NAME = gateway
|
DEV_DB_NAME = gateway
|
||||||
|
|
||||||
#SAP PROD
|
#SAP PROD
|
||||||
SAP_URL=122.8.178.132
|
SAP_URL=
|
||||||
SAP_USR=WS-USER
|
SAP_USR=
|
||||||
SAP_PASS=bmas.2024
|
SAP_PASS=
|
||||||
|
|
||||||
#SAP QAS
|
#SAP QAS
|
||||||
DEV_SAP_URL=110.238.82.143
|
DEV_SAP_URL=
|
||||||
DEV_SAP_USR=WS-USER
|
DEV_SAP_USR=
|
||||||
DEV_SAP_PASS=bmas.2024
|
DEV_SAP_PASS=
|
||||||
|
|
||||||
#RUTAS
|
#RUTAS
|
||||||
CFDI_XML_FILE_URL = ../../facturacion/xml
|
CFDI_XML_FILE_URL = ../../facturacion/xml
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var apiKey = "hmngy-TGFNKK1ZDpj7fUe41OOlh9k-CoYss53A";
|
var apiKey = "hmngy-60lXd3pZRePVdSpItDhnC3408GvLDHU4";
|
||||||
|
|
||||||
function stripeTokenHandler(token) {
|
function stripeTokenHandler(token) {
|
||||||
let form = document.getElementById("payment-form");
|
let form = document.getElementById("payment-form");
|
||||||
@@ -11,7 +11,7 @@ function stripeTokenHandler(token) {
|
|||||||
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
fetch("https://gateway.calidadbmasconsulting.com/api/obtLavePublicaStripe", {
|
fetch("http://127.0.0.1:8000/api/obtLavePublicaStripe", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -104,7 +104,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
fetch("https://gateway.calidadbmasconsulting.com/api/createPayment", {
|
fetch("http://127.0.0.1:8000/api/createPayment", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
|||||||
895
editarUsuario.php
Normal file
895
editarUsuario.php
Normal file
@@ -0,0 +1,895 @@
|
|||||||
|
<?php
|
||||||
|
include ("header.php");
|
||||||
|
include (__DIR__."/php/funciones.php");
|
||||||
|
|
||||||
|
$cursos = obtenerCursos();
|
||||||
|
$cupones = obtenerCupones();
|
||||||
|
function obtenerNombreCursoPorId($cursos, $idBuscado) {
|
||||||
|
foreach ($cursos as $curso) {
|
||||||
|
if (isset($curso['id']) && $curso['id'] === $idBuscado) {
|
||||||
|
return $curso['name'] ?? null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null; // Si no se encuentra
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtener ID del usuario a editar
|
||||||
|
$userId = $_GET['id'] ?? null;
|
||||||
|
$userData = null;
|
||||||
|
|
||||||
|
if ($userId) {
|
||||||
|
// Aquí deberíamos obtener los datos del usuario de la API
|
||||||
|
// Como no tengo acceso directo a la BD, voy a simular una llamada o usar la lista de usuarios si es posible
|
||||||
|
// Por ahora, haré una llamada a la API de verUsuarios y filtraré (ineficiente pero funcional con lo que tengo)
|
||||||
|
$url = $ruta.'/api/verUsuarios';
|
||||||
|
$curl = curl_init();
|
||||||
|
curl_setopt_array($curl, array(
|
||||||
|
CURLOPT_URL => $url,
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
CURLOPT_FOLLOWLOCATION => true,
|
||||||
|
CURLOPT_ENCODING => "",
|
||||||
|
CURLOPT_MAXREDIRS => 10,
|
||||||
|
CURLOPT_TIMEOUT => 0,
|
||||||
|
CURLOPT_CONNECTTIMEOUT => 0,
|
||||||
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
||||||
|
CURLOPT_CUSTOMREQUEST => "GET",
|
||||||
|
));
|
||||||
|
$response = curl_exec($curl);
|
||||||
|
curl_close($curl);
|
||||||
|
|
||||||
|
$users = json_decode($response, true);
|
||||||
|
if ($users) {
|
||||||
|
foreach ($users as $user) {
|
||||||
|
if ($user['id'] == $userId) {
|
||||||
|
$userData = $user;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$userData) {
|
||||||
|
echo "<script>alert('Usuario no encontrado'); window.location.href='verUsuarios.php';</script>";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<style>
|
||||||
|
/* Main Content */
|
||||||
|
.api-container {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.black-box {
|
||||||
|
background-color: #000000;
|
||||||
|
color: #00ff00;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 2px solid #333;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-label {
|
||||||
|
color: #ffffff;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-key {
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #444;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #00ff00;
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
word-break: break-all;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-button {
|
||||||
|
background-color: #333;
|
||||||
|
color: #00ff00;
|
||||||
|
border: 1px solid #555;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
font-size: 12px;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-button:hover {
|
||||||
|
background-color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-button:active {
|
||||||
|
background-color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-text {
|
||||||
|
color: #ffff00;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
.form-container {
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
backdrop-filter: blur(15px);
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 3rem;
|
||||||
|
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
width: 100%;
|
||||||
|
max-width: 600px;
|
||||||
|
animation: slideUp 0.6s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideUp {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(30px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-title {
|
||||||
|
text-align: center;
|
||||||
|
color: #2d3748;
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-subtitle {
|
||||||
|
text-align: center;
|
||||||
|
color: #718096;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
color: #4a5568;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.875rem 1rem;
|
||||||
|
border: 2px solid #e2e8f0;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 1rem;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input.color-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input.color-group input[type="color"] {
|
||||||
|
width: 50px;
|
||||||
|
height: 40px;
|
||||||
|
padding: 0;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input.color-group input[type="text"] {
|
||||||
|
flex: 1;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 0.5rem;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #4c51bf;
|
||||||
|
box-shadow: 0 0 0 3px rgba(76, 81, 191, 0.1);
|
||||||
|
background: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-textarea {
|
||||||
|
min-height: 100px;
|
||||||
|
resize: vertical;
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-input-wrapper {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-input {
|
||||||
|
position: absolute;
|
||||||
|
left: -9999px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-input-label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.875rem 1rem;
|
||||||
|
border: 2px dashed #cbd5e0;
|
||||||
|
border-radius: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
background: rgba(247, 250, 252, 0.8);
|
||||||
|
color: #718096;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-input-label:hover {
|
||||||
|
border-color: #4c51bf;
|
||||||
|
background: rgba(76, 81, 191, 0.05);
|
||||||
|
color: #4c51bf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-input-label.has-file {
|
||||||
|
border-color: #48bb78;
|
||||||
|
background: rgba(72, 187, 120, 0.1);
|
||||||
|
color: #48bb78;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn {
|
||||||
|
width: 100%;
|
||||||
|
padding: 1rem;
|
||||||
|
background: linear-gradient(135deg, #4c51bf 0%, #667eea 100%);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 10px 25px rgba(76, 81, 191, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn:active {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
select.form-input {
|
||||||
|
cursor: pointer;
|
||||||
|
background-position: right 0.75rem center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 1.5em 1.5em;
|
||||||
|
padding-right: 2.5rem;
|
||||||
|
appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
}
|
||||||
|
.color-input {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 5px;
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-input input[type="color"] {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
padding: 0;
|
||||||
|
margin-right: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-input input[type="text"] {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
width: 100%;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<main class="app-main">
|
||||||
|
<!--begin::App Content Header-->
|
||||||
|
<div class="main-content">
|
||||||
|
<div class="form-container">
|
||||||
|
<h1 class="form-title">Editar Usuario</h1>
|
||||||
|
<p class="form-subtitle">Modifique los datos del usuario</p>
|
||||||
|
|
||||||
|
<form id="userForm" method="POST">
|
||||||
|
<input type="hidden" name="id" value="<?= htmlspecialchars($userData['id']) ?>">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="empresa" class="form-label">Nombre de la Empresa *</label>
|
||||||
|
<input type="text" id="empresa" name="empresa" class="form-input" required
|
||||||
|
value="<?= htmlspecialchars($userData['empresa'] ?? '') ?>"
|
||||||
|
placeholder="Ej: Mi Empresa S.A.">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="usuario" class="form-label">Nombre de Usuario *</label>
|
||||||
|
<input type="text" id="usuario" name="usuario" class="form-input" required
|
||||||
|
value="<?= htmlspecialchars($userData['usuario'] ?? '') ?>"
|
||||||
|
placeholder="Ej: admin_empresa">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="email" class="form-label">Correo Electrónico *</label>
|
||||||
|
<input type="email" id="email" name="email" class="form-input" required
|
||||||
|
value="<?= htmlspecialchars($userData['email'] ?? '') ?>"
|
||||||
|
placeholder="usuario@empresa.com">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="platf_pago" class="form-label">Plataforma de pago*</label>
|
||||||
|
<select id="platf_pago" name="platf_pago" class="form-input" required>
|
||||||
|
<option value="">Seleccionar una plataforma (default: stripe)</option>
|
||||||
|
<option value="stripe" <?= ($userData['platf_pago'] ?? '') == 'stripe' ? 'selected' : '' ?>>Stripe</option>
|
||||||
|
<option value="openpay" <?= ($userData['platf_pago'] ?? '') == 'openpay' ? 'selected' : '' ?>>OpenPay</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="clavePublica" class="form-label">Clave Pública *</label>
|
||||||
|
<textarea id="clavePublica" name="clavePublica" class="form-input form-textarea" required
|
||||||
|
placeholder="-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA... -----END PUBLIC KEY-----"><?= htmlspecialchars($userData['clave_publica'] ?? '') ?></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="clavePrivada" class="form-label">Clave Privada *</label>
|
||||||
|
<textarea id="clavePrivada" name="clavePrivada" class="form-input form-textarea" required
|
||||||
|
placeholder="-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC... -----END PRIVATE KEY-----"><?= htmlspecialchars($userData['clave_privada'] ?? '') ?></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="logo" class="form-label">Logo (opcional) — JPG, PNG o SVG, max 2MB</label>
|
||||||
|
<div class="file-input-wrapper">
|
||||||
|
<input type="file" id="logo" name="logo" accept="image/png,image/jpeg,image/jpg,image/svg+xml" class="file-input">
|
||||||
|
<label for="logo" id="logoLabel" class="file-input-label">
|
||||||
|
<?php echo !empty($userData['logo']) ? htmlspecialchars($userData['logo']) : 'Seleccione un archivo'; ?>
|
||||||
|
</label>
|
||||||
|
<?php if (!empty($userData['logo'])): ?>
|
||||||
|
<input type="hidden" name="current_logo" value="<?= htmlspecialchars($userData['logo']) ?>">
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
<?php if (!empty($userData['logo'])): ?>
|
||||||
|
<div style="margin-top: 10px;">
|
||||||
|
<small>Logo actual: <a href="<?=$ruta."/img/".htmlspecialchars($userData['logo']) ?>" target="_blank">Ver logo</a></small>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="brand" class="form-label">Selecciona el color del branding <small>(ocupa el selector de color)</small></label>
|
||||||
|
|
||||||
|
<div class="form-input color-group">
|
||||||
|
<input type="color" id="colorPicker" value="<?= htmlspecialchars($userData['colorBrand'] ?? '#0072ff') ?>">
|
||||||
|
<input type="text" id="colorValue" name="colorValue" value="<?= htmlspecialchars($userData['colorBrand'] ?? '#0072ff') ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<button type="submit" class="submit-btn">
|
||||||
|
💾 Guardar Cambios
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--end::App Main-->
|
||||||
|
<div id="toast" class="toast"></div>
|
||||||
|
</main>
|
||||||
|
<script>
|
||||||
|
const picker = document.getElementById('colorPicker');
|
||||||
|
const value = document.getElementById('colorValue');
|
||||||
|
|
||||||
|
picker.addEventListener('input', () => {
|
||||||
|
value.value = picker.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
value.addEventListener('input', () => {
|
||||||
|
if (/^#[0-9A-Fa-f]{6}$/.test(value.value)) {
|
||||||
|
picker.value = value.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
// ============================================================================
|
||||||
|
// JAVASCRIPT PARA ENVÍO DE FORMULARIO A ARCHIVO PHP
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const form = document.getElementById('userForm');
|
||||||
|
const submitBtn = form.querySelector('.submit-btn');
|
||||||
|
|
||||||
|
// Configuración del archivo PHP intermedio
|
||||||
|
const PHP_CONFIG = {
|
||||||
|
endpoint: 'php/process_user_edit.php', // Usamos el mismo endpoint
|
||||||
|
timeout: 30000 // 30 segundos
|
||||||
|
};
|
||||||
|
|
||||||
|
// Manejar envío del formulario
|
||||||
|
form.addEventListener('submit', async function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Deshabilitar botón y cambiar texto
|
||||||
|
const originalText = submitBtn.textContent;
|
||||||
|
submitBtn.disabled = true;
|
||||||
|
submitBtn.textContent = '⏳ Procesando...';
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Crear FormData para manejar archivos si los hay
|
||||||
|
const formData = new FormData(form);
|
||||||
|
|
||||||
|
// Validar datos antes de enviar
|
||||||
|
if (!validateForm(formData)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Establecer valor por defecto para plataforma si está vacío
|
||||||
|
if (!formData.get('platf_pago')) {
|
||||||
|
formData.set('platf_pago', 'stripe');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enviar datos al archivo PHP
|
||||||
|
const response = await sendToPHP(formData);
|
||||||
|
|
||||||
|
// Procesar respuesta
|
||||||
|
if (response.success) {
|
||||||
|
handleSuccess(response);
|
||||||
|
} else {
|
||||||
|
handleError(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
handleNetworkError(error);
|
||||||
|
} finally {
|
||||||
|
// Restaurar botón
|
||||||
|
submitBtn.disabled = false;
|
||||||
|
submitBtn.textContent = originalText;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enviar datos al archivo PHP intermedio
|
||||||
|
*/
|
||||||
|
async function sendToPHP(formData) {
|
||||||
|
const url = PHP_CONFIG.endpoint;
|
||||||
|
|
||||||
|
const requestOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('Enviando datos a archivo PHP:', url);
|
||||||
|
console.log('Datos del formulario:', Object.fromEntries(formData));
|
||||||
|
|
||||||
|
const response = await fetch(url, requestOptions);
|
||||||
|
|
||||||
|
// Verificar si la respuesta es JSON válida
|
||||||
|
const contentType = response.headers.get('content-type');
|
||||||
|
if (!contentType || !contentType.includes('application/json')) {
|
||||||
|
const textResponse = await response.text();
|
||||||
|
throw new Error(`Respuesta no válida del servidor: ${textResponse.substring(0, 200)}...`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
// Agregar código de estado HTTP a la respuesta
|
||||||
|
data.httpStatus = response.status;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validar formato de email
|
||||||
|
*/
|
||||||
|
function isValidEmail(email) {
|
||||||
|
const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||||
|
return re.test(String(email).toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validar formulario antes de enviar
|
||||||
|
*/
|
||||||
|
function validateForm(formData) {
|
||||||
|
const errors = [];
|
||||||
|
|
||||||
|
// Validaciones requeridas
|
||||||
|
const requiredFields = [
|
||||||
|
{ name: 'empresa', label: 'Nombre de la Empresa' },
|
||||||
|
{ name: 'usuario', label: 'Nombre de Usuario' },
|
||||||
|
{ name: 'email', label: 'Correo Electrónico' },
|
||||||
|
{ name: 'clavePublica', label: 'Clave Pública' },
|
||||||
|
{ name: 'clavePrivada', label: 'Clave Privada' }
|
||||||
|
];
|
||||||
|
|
||||||
|
requiredFields.forEach(field => {
|
||||||
|
const value = formData.get(field.name);
|
||||||
|
if (!value || value.trim() === '') {
|
||||||
|
errors.push(`${field.label} es obligatorio`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const id = formData.get('id');
|
||||||
|
if (!id || String(id).trim() === '') {
|
||||||
|
errors.push('ID de Usuario es obligatorio');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validar formato de email
|
||||||
|
const email = formData.get('email');
|
||||||
|
if (email && !isValidEmail(email)) {
|
||||||
|
errors.push('El formato del correo electrónico no es válido');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validar usuario (solo alfanuméricos, guiones y guiones bajos)
|
||||||
|
const usuario = formData.get('usuario');
|
||||||
|
if (usuario && !/^[a-zA-Z0-9_-]+$/.test(usuario)) {
|
||||||
|
errors.push('El usuario solo puede contener letras, números, guiones y guiones bajos');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validar longitud mínima de claves
|
||||||
|
const clavePublica = formData.get('clavePublica');
|
||||||
|
const clavePrivada = formData.get('clavePrivada');
|
||||||
|
|
||||||
|
// Validación de logo (opcional)
|
||||||
|
const logo = formData.get('logo');
|
||||||
|
if (logo && typeof logo === 'object' && logo.size && logo.name) {
|
||||||
|
const allowedTypes = ['image/jpeg', 'image/png', 'image/jpg', 'image/svg+xml'];
|
||||||
|
const maxSize = 2 * 1024 * 1024; // 2MB
|
||||||
|
if (!allowedTypes.includes(logo.type)) {
|
||||||
|
errors.push('El logo debe ser un archivo JPG, PNG o SVG');
|
||||||
|
}
|
||||||
|
if (logo.size > maxSize) {
|
||||||
|
errors.push('El logo no puede ser mayor a 2MB');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Mostrar errores si los hay
|
||||||
|
if (errors.length > 0) {
|
||||||
|
showMessage('error', errors.join('<br>'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mostrar nombre de archivo seleccionado y cambiar estilo
|
||||||
|
const logoInput = document.getElementById('logo');
|
||||||
|
const logoLabel = document.getElementById('logoLabel');
|
||||||
|
if (logoInput) {
|
||||||
|
logoInput.addEventListener('change', (e) => {
|
||||||
|
const file = e.target.files[0];
|
||||||
|
if (file) {
|
||||||
|
logoLabel.textContent = `${file.name} (${Math.round(file.size/1024)} KB)`;
|
||||||
|
logoLabel.classList.add('has-file');
|
||||||
|
} else {
|
||||||
|
logoLabel.textContent = 'Seleccione un archivo';
|
||||||
|
logoLabel.classList.remove('has-file');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manejar respuesta exitosa
|
||||||
|
*/
|
||||||
|
function handleSuccess(response) {
|
||||||
|
console.log('Usuario actualizado exitosamente:', response);
|
||||||
|
|
||||||
|
// Mostrar mensaje de éxito
|
||||||
|
showMessage('success', response.message || 'Usuario actualizado exitosamente');
|
||||||
|
|
||||||
|
// Opcional: Redireccionar después de unos segundos
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = 'verUsuarios.php';
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manejar errores de la API
|
||||||
|
*/
|
||||||
|
function handleError(response) {
|
||||||
|
console.error('Error de la API:', response);
|
||||||
|
|
||||||
|
let errorMessage = 'Error al actualizar usuario';
|
||||||
|
|
||||||
|
// Manejar diferentes tipos de errores
|
||||||
|
if (response.httpStatus === 422 && response.errors) {
|
||||||
|
// Errores de validación
|
||||||
|
const validationErrors = Object.values(response.errors).flat();
|
||||||
|
errorMessage = validationErrors.join('<br>');
|
||||||
|
} else if (response.httpStatus === 409) {
|
||||||
|
// Conflicto (usuario/email ya existe)
|
||||||
|
errorMessage = response.message || 'El usuario o email ya existe';
|
||||||
|
} else if (response.message) {
|
||||||
|
errorMessage = response.message;
|
||||||
|
} else if (response.httpStatus >= 500) {
|
||||||
|
errorMessage = 'Error interno del servidor. Por favor intente nuevamente.';
|
||||||
|
}
|
||||||
|
|
||||||
|
showMessage('error', errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manejar errores de red
|
||||||
|
*/
|
||||||
|
function handleNetworkError(error) {
|
||||||
|
console.error('Error de red:', error);
|
||||||
|
|
||||||
|
let errorMessage = 'Error de conexión';
|
||||||
|
|
||||||
|
if (error.name === 'TypeError' && error.message.includes('fetch')) {
|
||||||
|
errorMessage = 'No se pudo conectar al servidor. Verifique su conexión a internet.';
|
||||||
|
} else if (error.message.includes('JSON')) {
|
||||||
|
errorMessage = 'Error en la respuesta del servidor. Por favor contacte al administrador.';
|
||||||
|
} else {
|
||||||
|
errorMessage = `Error: ${error.message}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
showMessage('error', errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mostrar mensajes al usuario
|
||||||
|
*/
|
||||||
|
function showMessage(type, message) {
|
||||||
|
// Crear modal si no existe
|
||||||
|
let modal = document.getElementById('messageModal');
|
||||||
|
if (!modal) {
|
||||||
|
modal = createMessageModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configurar contenido del modal
|
||||||
|
const modalTitle = modal.querySelector('.modal-title');
|
||||||
|
const modalMessage = modal.querySelector('.modal-message');
|
||||||
|
const modalIcon = modal.querySelector('.modal-icon');
|
||||||
|
const modalContent = modal.querySelector('.modal-content');
|
||||||
|
|
||||||
|
// Configurar según el tipo de mensaje
|
||||||
|
if (type === 'success') {
|
||||||
|
modalTitle.textContent = 'Éxito';
|
||||||
|
modalIcon.textContent = '✅';
|
||||||
|
modalContent.className = 'modal-content success';
|
||||||
|
} else {
|
||||||
|
modalTitle.textContent = 'Error';
|
||||||
|
modalIcon.textContent = '❌';
|
||||||
|
modalContent.className = 'modal-content error';
|
||||||
|
}
|
||||||
|
|
||||||
|
modalMessage.innerHTML = message;
|
||||||
|
|
||||||
|
// Mostrar modal con animación
|
||||||
|
modal.style.display = 'flex';
|
||||||
|
setTimeout(() => {
|
||||||
|
modal.classList.add('show');
|
||||||
|
}, 10);
|
||||||
|
|
||||||
|
// Enfocar el botón de cerrar para accesibilidad
|
||||||
|
const closeBtn = modal.querySelector('.modal-close-btn');
|
||||||
|
closeBtn.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Función auxiliar para crear el modal
|
||||||
|
*/
|
||||||
|
function createMessageModal() {
|
||||||
|
const modal = document.createElement('div');
|
||||||
|
modal.id = 'messageModal';
|
||||||
|
modal.className = 'message-modal';
|
||||||
|
|
||||||
|
modal.innerHTML = `
|
||||||
|
<div class="modal-overlay">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<span class="modal-icon"></span>
|
||||||
|
<h3 class="modal-title"></h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="modal-message"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="modal-close-btn">Cerrar</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Agregar estilos CSS
|
||||||
|
if (!document.getElementById('modalStyles')) {
|
||||||
|
const styles = document.createElement('style');
|
||||||
|
styles.id = 'modalStyles';
|
||||||
|
styles.textContent = `
|
||||||
|
.message-modal {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 10000;
|
||||||
|
display: none;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-modal.show {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
backdrop-filter: blur(4px);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
background: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
|
||||||
|
max-width: 500px;
|
||||||
|
width: 100%;
|
||||||
|
max-height: 80vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
transform: scale(0.9) translateY(20px);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-modal.show .modal-content {
|
||||||
|
transform: scale(1) translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content.success {
|
||||||
|
border-top: 4px solid #48bb78;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content.error {
|
||||||
|
border-top: 4px solid #f56565;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
padding: 1.5rem 1.5rem 1rem 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-icon {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-title {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 0;
|
||||||
|
color: #2d3748;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 0 1.5rem 1rem 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-message {
|
||||||
|
color: #4a5568;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-footer {
|
||||||
|
padding: 1rem 1.5rem 1.5rem 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-close-btn {
|
||||||
|
background: linear-gradient(135deg, #4c51bf 0%, #667eea 100%);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-close-btn:hover {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 4px 12px rgba(76, 81, 191, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-close-btn:active {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-close-btn:focus {
|
||||||
|
outline: none;
|
||||||
|
box-shadow: 0 0 0 3px rgba(76, 81, 191, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.modal-overlay {
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
max-height: 90vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header,
|
||||||
|
.modal-body,
|
||||||
|
.modal-footer {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
document.head.appendChild(styles);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Manejar cierre del modal
|
||||||
|
const closeBtn = modal.querySelector('.modal-close-btn');
|
||||||
|
const overlay = modal.querySelector('.modal-overlay');
|
||||||
|
|
||||||
|
function closeModal() {
|
||||||
|
modal.classList.remove('show');
|
||||||
|
setTimeout(() => {
|
||||||
|
modal.style.display = 'none';
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
closeBtn.onclick = closeModal;
|
||||||
|
overlay.onclick = (e) => {
|
||||||
|
if (e.target === overlay) closeModal();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Cerrar con tecla Escape
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === 'Escape' && modal.style.display === 'flex') {
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body.appendChild(modal);
|
||||||
|
return modal;
|
||||||
|
} // <-- Esta llave cierra createMessageModal()
|
||||||
|
|
||||||
|
}); // <-- Esta llave cierra DOMContentLoaded
|
||||||
|
</script>
|
||||||
|
<?php include("footer.php");?>
|
||||||
@@ -84,3 +84,45 @@
|
|||||||
{"timestamp":"2025-10-28 15:10:37","level":"success","message":"Usuario enviado a API","context":{"usuario":"qwsqws","empresa":"awqsws","ip":"127.0.0.1"}}
|
{"timestamp":"2025-10-28 15:10:37","level":"success","message":"Usuario enviado a API","context":{"usuario":"qwsqws","empresa":"awqsws","ip":"127.0.0.1"}}
|
||||||
{"timestamp":"2025-10-28 15:11:52","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/regUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand"]}}
|
{"timestamp":"2025-10-28 15:11:52","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/regUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand"]}}
|
||||||
{"timestamp":"2025-10-28 15:11:54","level":"success","message":"Usuario enviado a API","context":{"usuario":"wdqdqw","empresa":"Demo","ip":"127.0.0.1"}}
|
{"timestamp":"2025-10-28 15:11:54","level":"success","message":"Usuario enviado a API","context":{"usuario":"wdqdqw","empresa":"Demo","ip":"127.0.0.1"}}
|
||||||
|
{"timestamp":"2025-11-24 15:35:21","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand"]}}
|
||||||
|
{"timestamp":"2025-11-24 15:38:27","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand"]}}
|
||||||
|
{"timestamp":"2025-11-24 15:39:53","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 15:40:37","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 15:43:57","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 15:57:58","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 15:58:00","level":"error","message":"Error general en process_user.php","context":{"error":"Error de conexi\u00f3n con la API: Failed to connect to 127.0.0.1 port 8000: Connection refused","trace":"#0 C:\\laragon\\www\\hmnypasarela\\php\\process_user_edit.php(37): sendToLaravelAPI(Array, Array)\n#1 {main}","ip":"127.0.0.1"}}
|
||||||
|
{"timestamp":"2025-11-24 15:58:17","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 15:58:34","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:01:53","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:02:22","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:02:48","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:02:51","level":"success","message":"Usuario enviado a API","context":{"usuario":"DEMO","empresa":"DEMO PASARELA","ip":"127.0.0.1"}}
|
||||||
|
{"timestamp":"2025-11-24 16:03:17","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:03:17","level":"success","message":"Usuario enviado a API","context":{"usuario":"DEMO","empresa":"DEMO PASARELA","ip":"127.0.0.1"}}
|
||||||
|
{"timestamp":"2025-11-24 16:03:34","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:09:10","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:10:33","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:11:40","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:12:40","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["id","empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:28:21","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["id","empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:29:29","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["id","empresa","usuario","email","platf_pago","clavePublica","clavePrivada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:32:16","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["id","empresa","usuario","email","platf_pago","clave_publica","clave_privada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:32:19","level":"success","message":"Usuario enviado a API","context":{"usuario":"DEMO","empresa":"DEMO PASARELA","ip":"127.0.0.1"}}
|
||||||
|
{"timestamp":"2025-11-24 16:35:15","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["id","empresa","usuario","email","platf_pago","clave_publica","clave_privada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:35:17","level":"success","message":"Usuario enviado a API","context":{"usuario":"DEMO","empresa":"DEMO PASARELA","ip":"127.0.0.1"}}
|
||||||
|
{"timestamp":"2025-11-24 16:38:18","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["id","empresa","usuario","email","platf_pago","clave_publica","clave_privada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:38:18","level":"success","message":"Usuario enviado a API","context":{"usuario":"DEMO","empresa":"DEMO PASARELA","ip":"127.0.0.1"}}
|
||||||
|
{"timestamp":"2025-11-24 16:39:29","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["id","empresa","usuario","email","platf_pago","clave_publica","clave_privada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:39:31","level":"success","message":"Usuario enviado a API","context":{"usuario":"DEMO","empresa":"DEMO PASARELA","ip":"127.0.0.1"}}
|
||||||
|
{"timestamp":"2025-11-24 16:39:57","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["id","empresa","usuario","email","platf_pago","clave_publica","clave_privada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:39:59","level":"success","message":"Usuario enviado a API","context":{"usuario":"DEMO","empresa":"DEMO PASARELA","ip":"127.0.0.1"}}
|
||||||
|
{"timestamp":"2025-11-24 16:45:26","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["id","empresa","usuario","email","platf_pago","clave_publica","clave_privada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:45:28","level":"success","message":"Usuario enviado a API","context":{"usuario":"DEMO","empresa":"DEMO PASARELA","ip":"127.0.0.1"}}
|
||||||
|
{"timestamp":"2025-11-24 16:46:05","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["id","empresa","usuario","email","platf_pago","clave_publica","clave_privada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:46:08","level":"success","message":"Usuario enviado a API","context":{"usuario":"DEMO","empresa":"DEMO PASARELA","ip":"127.0.0.1"}}
|
||||||
|
{"timestamp":"2025-11-24 16:49:23","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["id","empresa","usuario","email","platf_pago","clave_publica","clave_privada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:49:25","level":"success","message":"Usuario enviado a API","context":{"usuario":"DEMO","empresa":"DEMO PASARELA","ip":"127.0.0.1"}}
|
||||||
|
{"timestamp":"2025-11-24 16:49:43","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["id","empresa","usuario","email","platf_pago","clave_publica","clave_privada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:49:45","level":"success","message":"Usuario enviado a API","context":{"usuario":"DEMO","empresa":"DEMO PASARELA","ip":"127.0.0.1"}}
|
||||||
|
{"timestamp":"2025-11-24 16:50:26","level":"debug","message":"Preparando campos para enviar a API","context":{"url":"http:\/\/127.0.0.1:8000\/api\/editUsuario","post_keys":["id","empresa","usuario","email","platf_pago","clave_publica","clave_privada","colorBrand","current_logo"]}}
|
||||||
|
{"timestamp":"2025-11-24 16:50:28","level":"success","message":"Usuario enviado a API","context":{"usuario":"DEMO","empresa":"DEMO PASARELA","ip":"127.0.0.1"}}
|
||||||
|
|||||||
383
php/process_user_edit.php
Normal file
383
php/process_user_edit.php
Normal file
@@ -0,0 +1,383 @@
|
|||||||
|
<?php
|
||||||
|
include(__DIR__."/../rutasApi.php");
|
||||||
|
// ============================================================================
|
||||||
|
// ARCHIVO PHP INTERMEDIO PARA PROCESAR FORMULARIO Y ENVIAR A API LARAVEL
|
||||||
|
// process_user.php
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// Configuración de headers para JSON
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
header('Access-Control-Allow-Origin: *'); // Ajustar según necesidades de CORS
|
||||||
|
header('Access-Control-Allow-Methods: POST');
|
||||||
|
header('Access-Control-Allow-Headers: Content-Type');
|
||||||
|
|
||||||
|
// Solo permitir métodos POST
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
|
http_response_code(405);
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Método no permitido. Solo se acepta POST.'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configuración de la API Laravel
|
||||||
|
$API_CONFIG = [
|
||||||
|
'base_url' => $ruta.'/api', // Cambiar por tu URL de Laravel
|
||||||
|
'endpoint' => '/editUsuario', // Tu endpoint de Laravel
|
||||||
|
'timeout' => 30, // Timeout en segundos
|
||||||
|
'auth_token' => '', // Token de autenticación si es necesario
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Validar y procesar datos del formulario
|
||||||
|
$formData = validateAndProcessForm();
|
||||||
|
|
||||||
|
// Enviar datos a la API Laravel usando cURL
|
||||||
|
$apiResponse = sendToLaravelAPI($formData, $API_CONFIG);
|
||||||
|
|
||||||
|
// Procesar respuesta de la API
|
||||||
|
$response = processAPIResponse($apiResponse);
|
||||||
|
|
||||||
|
// Log de éxito
|
||||||
|
logActivity('success', 'Usuario enviado a API', [
|
||||||
|
'usuario' => $formData['usuario'] ?? 'N/A',
|
||||||
|
'empresa' => $formData['empresa'] ?? 'N/A',
|
||||||
|
'ip' => $_SERVER['REMOTE_ADDR'] ?? 'N/A'
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Retornar respuesta
|
||||||
|
echo json_encode($response);
|
||||||
|
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
// Errores de validación
|
||||||
|
http_response_code(422);
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Error de validación',
|
||||||
|
'errors' => $e->getErrors()
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (APIException $e) {
|
||||||
|
// Errores de la API
|
||||||
|
http_response_code($e->getHttpCode());
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => $e->getMessage(),
|
||||||
|
'api_error' => $e->getApiError()
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// Errores generales
|
||||||
|
logActivity('error', 'Error general en process_user.php', [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'trace' => $e->getTraceAsString(),
|
||||||
|
'ip' => $_SERVER['REMOTE_ADDR'] ?? 'N/A'
|
||||||
|
]);
|
||||||
|
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Error interno del servidor. Por favor intente nuevamente.'.$e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// FUNCIONES PRINCIPALES
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validar y procesar datos del formulario
|
||||||
|
*/
|
||||||
|
function validateAndProcessForm() {
|
||||||
|
$errors = [];
|
||||||
|
|
||||||
|
// Campos requeridos
|
||||||
|
$requiredFields = [
|
||||||
|
'empresa' => 'Nombre de la Empresa',
|
||||||
|
'usuario' => 'Nombre de Usuario',
|
||||||
|
'email' => 'Correo Electrónico',
|
||||||
|
'clavePublica' => 'Clave Pública',
|
||||||
|
'clavePrivada' => 'Clave Privada',
|
||||||
|
'colorValue' => 'Color de Branding'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Validar campos requeridos
|
||||||
|
foreach ($requiredFields as $field => $label) {
|
||||||
|
if (empty($_POST[$field]) || trim($_POST[$field]) === '') {
|
||||||
|
$errors[$field] = ["$label es obligatorio"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validar formato de email
|
||||||
|
if (!empty($_POST['email']) && !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
|
||||||
|
$errors['email'] = ['El formato del correo electrónico no es válido'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validar usuario (solo alfanuméricos, guiones y guiones bajos)
|
||||||
|
if (!empty($_POST['usuario']) && !preg_match('/^[a-zA-Z0-9_-]+$/', $_POST['usuario'])) {
|
||||||
|
$errors['usuario'] = ['El usuario solo puede contener letras, números, guiones y guiones bajos'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Si hay errores, lanzar excepción
|
||||||
|
if (!empty($errors)) {
|
||||||
|
throw new ValidationException($errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Procesar y limpiar datos
|
||||||
|
$formData = [
|
||||||
|
'id' => $_POST['id'] ?? null, // Asegurarse de que el ID se incluya
|
||||||
|
'empresa' => trim($_POST['empresa']),
|
||||||
|
'usuario' => trim($_POST['usuario']),
|
||||||
|
'email' => strtolower(trim($_POST['email'])),
|
||||||
|
'platf_pago' => !empty($_POST['platf_pago']) ? $_POST['platf_pago'] : 'stripe',
|
||||||
|
'clave_publica' => formatKey($_POST['clavePublica']),
|
||||||
|
'clave_privada' => formatKey($_POST['clavePrivada']),
|
||||||
|
'colorBrand' => formatKey($_POST['colorValue']),
|
||||||
|
];
|
||||||
|
|
||||||
|
// Procesar logo si se envió
|
||||||
|
if (isset($_FILES['logo']) && isset($_FILES['logo']['error']) && $_FILES['logo']['error'] !== UPLOAD_ERR_NO_FILE) {
|
||||||
|
// processLogo validará el archivo y devolverá la info necesaria
|
||||||
|
$formData['logo'] = processLogo($_FILES['logo']);
|
||||||
|
} else if (isset($_POST['current_logo']) && !empty($_POST['current_logo'])) {
|
||||||
|
// Si no se subió un nuevo logo, pero hay un logo actual, enviarlo
|
||||||
|
$formData['current_logo'] = $_POST['current_logo'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enviar datos a la API Laravel usando cURL
|
||||||
|
*/
|
||||||
|
function sendToLaravelAPI($formData, $config) {
|
||||||
|
$url = $config['base_url'] . $config['endpoint'];
|
||||||
|
|
||||||
|
// Inicializar cURL
|
||||||
|
$ch = curl_init();
|
||||||
|
// Preparar campos para envío multipart/form-data
|
||||||
|
$postFields = [];
|
||||||
|
foreach ($formData as $key => $value) {
|
||||||
|
if ($key === 'logo' && is_array($value) && isset($value['tmp_name'])) {
|
||||||
|
// Verificar que el archivo existe y es legible
|
||||||
|
if (!is_readable($value['tmp_name'])) {
|
||||||
|
throw new Exception('No se puede leer el archivo de logo');
|
||||||
|
}
|
||||||
|
// Crear CURLFile para enviar el archivo
|
||||||
|
$postFields['logo'] = new CURLFile(
|
||||||
|
$value['tmp_name'],
|
||||||
|
$value['type'],
|
||||||
|
$value['name']
|
||||||
|
);
|
||||||
|
// Agregar información adicional del archivo
|
||||||
|
$postFields['logo_name'] = $value['name'];
|
||||||
|
$postFields['logo_type'] = $value['type'];
|
||||||
|
} else {
|
||||||
|
$postFields[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cabeceras - NO establecer 'Content-Type: multipart/form-data' manualmente
|
||||||
|
// cURL añadirá la cabecera Content-Type con el boundary correcto cuando se use CURLFile
|
||||||
|
$headers = [
|
||||||
|
'Accept: application/json',
|
||||||
|
'X-Requested-With: XMLHttpRequest'
|
||||||
|
];
|
||||||
|
if (!empty($config['auth_token'])) {
|
||||||
|
$headers[] = 'Authorization: Bearer ' . $config['auth_token'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configurar cURL
|
||||||
|
curl_setopt_array($ch, [
|
||||||
|
CURLOPT_URL => $url,
|
||||||
|
CURLOPT_POST => true,
|
||||||
|
CURLOPT_POSTFIELDS => $postFields,
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
CURLOPT_TIMEOUT => $config['timeout'],
|
||||||
|
CURLOPT_CONNECTTIMEOUT => 10,
|
||||||
|
CURLOPT_FOLLOWLOCATION => true,
|
||||||
|
CURLOPT_MAXREDIRS => 3,
|
||||||
|
CURLOPT_SSL_VERIFYPEER => false, // Solo para desarrollo
|
||||||
|
CURLOPT_USERAGENT => 'PHP-FormProcessor/1.0',
|
||||||
|
CURLOPT_HTTPHEADER => $headers
|
||||||
|
]);
|
||||||
|
// Log de depuración: claves y estado del archivo (no logeamos contenido binario)
|
||||||
|
logActivity('debug', 'Preparando campos para enviar a API', [
|
||||||
|
'url' => $url,
|
||||||
|
'post_keys' => array_keys($postFields)
|
||||||
|
]);
|
||||||
|
if (isset($postFields['logo']) && isset($formData['logo'])) {
|
||||||
|
$tmp = $formData['logo']['tmp_name'] ?? null;
|
||||||
|
logActivity('debug', 'Estado logo antes de cURL', [
|
||||||
|
'tmp_name' => $tmp,
|
||||||
|
'exists' => $tmp ? file_exists($tmp) : false,
|
||||||
|
'readable' => $tmp ? is_readable($tmp) : false,
|
||||||
|
'size' => $formData['logo']['size'] ?? null,
|
||||||
|
'error' => $formData['logo']['error'] ?? null
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ejecutar petición
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
$error = curl_error($ch);
|
||||||
|
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
// Verificar errores de cURL
|
||||||
|
if ($response === false || !empty($error)) {
|
||||||
|
throw new Exception("Error de conexión con la API: $error");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Decodificar respuesta JSON
|
||||||
|
$decodedResponse = json_decode($response, true);
|
||||||
|
|
||||||
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||||
|
throw new Exception("Respuesta inválida de la API: " . $response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'http_code' => $httpCode,
|
||||||
|
'data' => $decodedResponse,
|
||||||
|
'raw_response' => $response
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Procesar respuesta de la API
|
||||||
|
*/
|
||||||
|
function processAPIResponse($apiResponse) {
|
||||||
|
$httpCode = $apiResponse['http_code'];
|
||||||
|
$data = $apiResponse['data'];
|
||||||
|
|
||||||
|
// Verificar código de estado HTTP
|
||||||
|
if ($httpCode >= 200 && $httpCode < 300) {
|
||||||
|
// Éxito
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'message' => $data['message'] ?? 'Usuario registrado exitosamente',
|
||||||
|
'data' => $data['data'] ?? null
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
// Error de la API
|
||||||
|
throw new APIException(
|
||||||
|
$data['message'] ?? 'Error en la API',
|
||||||
|
$httpCode,
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formatear claves (limpiar espacios y normalizar)
|
||||||
|
*/
|
||||||
|
function formatKey($key) {
|
||||||
|
// Limpiar espacios extra
|
||||||
|
$cleanKey = trim($key);
|
||||||
|
|
||||||
|
// Normalizar saltos de línea
|
||||||
|
$cleanKey = str_replace(["\r\n", "\r"], "\n", $cleanKey);
|
||||||
|
|
||||||
|
return $cleanKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Procesar archivo de logo
|
||||||
|
*/
|
||||||
|
function processLogo($logoFile) {
|
||||||
|
// Validar archivo
|
||||||
|
$allowedTypes = ['image/jpeg', 'image/png', 'image/jpg', 'image/svg+xml'];
|
||||||
|
$maxSize = 2 * 1024 * 1024; // 2MB
|
||||||
|
|
||||||
|
if (!in_array($logoFile['type'], $allowedTypes)) {
|
||||||
|
throw new ValidationException(['logo' => ['El logo debe ser un archivo JPG, PNG o SVG']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($logoFile['size'] > $maxSize) {
|
||||||
|
throw new ValidationException(['logo' => ['El logo no puede ser mayor a 2MB']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verificar que el archivo se subió correctamente
|
||||||
|
if (!is_uploaded_file($logoFile['tmp_name'])) {
|
||||||
|
throw new ValidationException(['logo' => ['Error al subir el archivo']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verificar que podemos leer el archivo
|
||||||
|
if (!is_readable($logoFile['tmp_name'])) {
|
||||||
|
throw new ValidationException(['logo' => ['No se puede leer el archivo subido']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'name' => $logoFile['name'],
|
||||||
|
'type' => $logoFile['type'],
|
||||||
|
'tmp_name' => $logoFile['tmp_name'],
|
||||||
|
'size' => $logoFile['size'],
|
||||||
|
'error' => $logoFile['error']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registrar actividad en log
|
||||||
|
*/
|
||||||
|
function logActivity($level, $message, $context = []) {
|
||||||
|
$logEntry = [
|
||||||
|
'timestamp' => date('Y-m-d H:i:s'),
|
||||||
|
'level' => $level,
|
||||||
|
'message' => $message,
|
||||||
|
'context' => $context
|
||||||
|
];
|
||||||
|
|
||||||
|
$logFile = 'logs/form_processor.log';
|
||||||
|
|
||||||
|
// Crear directorio de logs si no existe
|
||||||
|
if (!file_exists(dirname($logFile))) {
|
||||||
|
mkdir(dirname($logFile), 0755, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escribir al log
|
||||||
|
file_put_contents($logFile, json_encode($logEntry) . "\n", FILE_APPEND | LOCK_EX);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// CLASES DE EXCEPCIÓN PERSONALIZADAS
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
class ValidationException extends Exception {
|
||||||
|
private $errors;
|
||||||
|
|
||||||
|
public function __construct($errors) {
|
||||||
|
$this->errors = $errors;
|
||||||
|
parent::__construct('Errores de validación');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getErrors() {
|
||||||
|
return $this->errors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class APIException extends Exception {
|
||||||
|
private $httpCode;
|
||||||
|
private $apiError;
|
||||||
|
|
||||||
|
public function __construct($message, $httpCode = 500, $apiError = null) {
|
||||||
|
$this->httpCode = $httpCode;
|
||||||
|
$this->apiError = $apiError;
|
||||||
|
parent::__construct($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHttpCode() {
|
||||||
|
return $this->httpCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApiError() {
|
||||||
|
return $this->apiError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -54,6 +54,7 @@ $url = $ruta.'/api/verUsuarios';
|
|||||||
<th>Empresa</th>
|
<th>Empresa</th>
|
||||||
<th>Plat. Pago</th>
|
<th>Plat. Pago</th>
|
||||||
<th>Llave</th>
|
<th>Llave</th>
|
||||||
|
<th>Acciones</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
@@ -65,6 +66,7 @@ $url = $ruta.'/api/verUsuarios';
|
|||||||
<script>
|
<script>
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
const data = <?= $result ?>;
|
const data = <?= $result ?>;
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
$('#tablaUsuarios').DataTable({
|
$('#tablaUsuarios').DataTable({
|
||||||
data: data,
|
data: data,
|
||||||
@@ -73,7 +75,13 @@ $(document).ready(function() {
|
|||||||
{ data: 'email' },
|
{ data: 'email' },
|
||||||
{ data: 'empresa' },
|
{ data: 'empresa' },
|
||||||
{ data: 'platf_pago'},
|
{ data: 'platf_pago'},
|
||||||
{ data: 'apiKey'}
|
{ data: 'apiKey'},
|
||||||
|
{
|
||||||
|
data: null,
|
||||||
|
render: function (data, type, row) {
|
||||||
|
return '<a href="editarUsuario.php?id=' + row.id + '" class="btn btn-sm btn-primary">Editar</a>';
|
||||||
|
}
|
||||||
|
}
|
||||||
],
|
],
|
||||||
language: {
|
language: {
|
||||||
url: '//cdn.datatables.net/plug-ins/1.13.6/i18n/es-ES.json'
|
url: '//cdn.datatables.net/plug-ins/1.13.6/i18n/es-ES.json'
|
||||||
|
|||||||
Reference in New Issue
Block a user