obtenerConfiguracion(); // Desencriptación de contraseña emisor if (isset($configuracion['contrasenia_emisor'])) { $configuracion['contrasenia_emisor_formateada'] = decryptData($configuracion['contrasenia_emisor']); } else { $configuracion['contrasenia_emisor_formateada'] = 'Sin Setear'; } // Saneamiento de email emisor if (isset($configuracion['email_emisor'])) { $configuracion['email_emisor'] = $configuracion['email_emisor']; } else { $configuracion['email_emisor'] = 'Sin Setear'; } // Validaciones if (empty($configuracion)) { $_SESSION['flash_error'] = 'Ocurrió un error al cargar la configuración.'; header("Location: index.php?opt=configuracion"); exit; } // Saneamiento de fecha if (!empty($configuracion['inicio_act'])) { $dt = new DateTime($configuracion['inicio_act']); $configuracion['inicio_act_formateada'] = $dt->format('d/m/Y'); } else { $configuracion['inicio_act_formateada'] = '-'; } ob_start(); require_once __DIR__ . '/../views/configuracion/configuracionView.php'; return ob_get_clean(); } // ACTUALIZAR CONFIGURACIÓN case 'actualizar_config': if ($_SERVER['REQUEST_METHOD'] === 'POST') { $configuracion = [ 'nombre' => trim($_POST['nombre'] ?? ''), 'direccion' => trim($_POST['direccion'] ?? ''), 'ciudad' => trim($_POST['ciudad'] ?? ''), 'codigo_postal' => trim($_POST['codigo_postal'] ?? ''), 'provincia' => trim($_POST['provincia'] ?? ''), 'telefono' => trim($_POST['telefono'] ?? ''), 'email' => trim($_POST['email'] ?? ''), 'cond_iva' => trim($_POST['cond_iva'] ?? 'responsable_inscripto'), 'cuit' => ($_POST['cuit_1'] ?? '') . ($_POST['cuit_2'] ?? '') . ($_POST['cuit_3'] ?? ''), 'iva' => $_POST['iva'] ?? 21, 'hora_apertura_maniana' => trim($_POST['hora_apertura_maniana'] ?? ''), 'hora_cierre_maniana' => trim($_POST['hora_cierre_maniana'] ?? ''), 'hora_apertura_tarde' => trim($_POST['hora_apertura_tarde'] ?? ''), 'hora_cierre_tarde' => trim($_POST['hora_cierre_tarde'] ?? ''), 'mail_automatico' => isset($_POST['mail_automatico']) ? 1 : 0, 'cargo_cancelacion_servicio' => $_POST['cargo_cancelacion_servicio'] ?? 0, 'email_emisor' => trim($_POST['email_emisor'] ?? ''), 'contrasenia_emisor' => trim($_POST['contrasenia_emisor'] ?? ''), ]; $errores = []; // Validaciones // NOMBRE if ($configuracion['nombre'] === '') { $errores[] = "El nombre no puede estar vacío."; } else if (!preg_match('/^[A-Za-zÁÉÍÓÚáéíóú0-9\s\.\-]{2,100}$/', $configuracion['nombre'])) { $errores[] = "El nombre contiene caracteres inválidos."; } else if (strlen($configuracion['nombre']) < 2) { $errores[] = "El nombre debe tener al menos 2 caracteres."; } else if (strlen($configuracion['nombre']) > 50) { $errores[] = "El nombre no puede superar los 50 caracteres."; } // DIRECCIÓN if ($configuracion['direccion'] === '') { $errores[] = "La dirección no puede estar vacía."; } else if (strlen($configuracion['direccion']) < 3) { $errores[] = "La dirección debe tener al menos 3 caracteres."; } else if (strlen($configuracion['direccion']) > 100) { $errores[] = "La dirección no puede superar los 100 caracteres."; } // CIUDAD if ($configuracion['ciudad'] === '') { $errores[] = "La ciudad no puede estar vacía."; } else if (!preg_match('/^[A-Za-zÁÉÍÓÚáéíóúñÑ\s]{2,100}$/', $configuracion['ciudad'])) { $errores[] = "La ciudad solo puede contener letras y espacios."; } // CODIGO POSTAL if ($configuracion['codigo_postal'] === '') { $errores[] = "El código postal no puede estar vacío."; } else if (!preg_match('/^[0-9]{4}$/', $configuracion['codigo_postal'])) { $errores[] = "El código postal debe tener 4 dígitos."; } // PROVINCIA if ($configuracion['provincia'] === '') { $errores[] = "La provincia no puede estar vacía."; } else if (!preg_match('/^[A-Za-zÁÉÍÓÚáéíóúñÑ\s]{2,100}$/', $configuracion['provincia'])) { $errores[] = "La provincia contiene caracteres inválidos."; } // TELÉFONO if ($configuracion['telefono'] === '') { $errores[] = "El teléfono no puede estar vacío."; } else if (!preg_match('/^[0-9]{10}$/', $configuracion['telefono'])) { $errores[] = "El teléfono debe tener 10 dígitos."; } // EMAIL if ($configuracion['email'] === '') { $errores[] = "El email no puede estar vacío."; } else if (!filter_var($configuracion['email'], FILTER_VALIDATE_EMAIL)) { $errores[] = "Formato de email inválido."; } else if (strlen($configuracion['email']) > 100) { $errores[] = "El email no puede superar los 100 caracteres."; } // CONDICIÓN_IVA $condicionesValidas = [ 'consumidor_final', 'responsable_inscripto', 'monotributo' ]; if (!in_array($configuracion['cond_iva'], $condicionesValidas)) { $errores[] = "Condición de IVA inválida."; } // CUIT if (!preg_match('/^\d{10,11}$/', $configuracion['cuit'])) { $errores[] = 'CUIT inválido. Debe contener solo números.'; } // IVA if (!is_numeric($configuracion['iva'])) { $errores[] = "El IVA debe ser numérico."; } // HORA DE APERTURA Y CIERRE if ($configuracion['hora_apertura_maniana'] && $configuracion['hora_cierre_maniana']) { if ($configuracion['hora_apertura_maniana'] >= $configuracion['hora_cierre_maniana']) { $errores[] = "El horario de apertura debe ser menor al de cierre."; } } if ($configuracion['hora_apertura_tarde'] && $configuracion['hora_cierre_tarde']) { if ($configuracion['hora_apertura_tarde'] >= $configuracion['hora_cierre_tarde']) { $errores[] = "El horario de apertura debe ser menor al de cierre."; } } // CARGO POR CANCELACIÓN DE SERVICIO if (!is_numeric($configuracion['cargo_cancelacion_servicio'])) { $errores[] = "El cargo por cancelación debe ser numérico."; } // EMAIL EMISOR if ($configuracion['email_emisor'] === '') { $errores[] = "El email no puede estar vacío."; } else if (!filter_var($configuracion['email_emisor'], FILTER_VALIDATE_EMAIL)) { $errores[] = "Formato de email inválido."; } else if (strlen($configuracion['email_emisor']) > 100) { $errores[] = "El email no puede superar los 100 caracteres."; } // CONTRASEÑA EMISOR if (strlen($configuracion['contrasenia_emisor']) > 100) { $errores[] = "Contraseña demasiado larga."; } if (!empty($errores)) { $_SESSION['flash_error'] = implode('
', $errores); // Se guarda en $_SESSION el error header("Location: index.php?opt=configuracion"); exit; } // ENCRIPTACION DE CONTRASEÑA if ($configuracion['contrasenia_emisor'] !== '') { $passLimpia = str_replace(' ', '', $configuracion['contrasenia_emisor']); $configuracion['contrasenia_emisor'] = encryptData($passLimpia); } // Actualizamos datos de configuración if ($configuracionmodel->actualizarConfiguracion($configuracion)) { $_SESSION['flash_success'] = 'Configuración actualizada correctamente.'; header("Location: index.php?opt=configuracion"); exit; } else { $_SESSION['flash_error'] = 'Error al actualizar la configuración.'; header("Location: index.php?opt=configuracion"); exit; } } // GENERAR BACKUP case 'generar_backup': // Obtenemos desde donde viene la petición (puede ser backup automático) $return = $_GET['from'] ?? 'backups'; $backupDir = $_ENV['BACKUP_PATH'] ?? (__DIR__ . '/../backups/'); $fecha = date('Y-m-d_H-i-s'); $archivo = "backup_$fecha.sql"; // Generación de nombre de archivo con extensión $rutaBackup = $backupDir . $archivo; // Generación de ruta completa de archivo backup // Datos de conexión $rutaBackup = escapeshellarg($rutaBackup); // Permite omitir espacios o caracteres no deseados (puede romper ruta o comando) $host = escapeshellarg($_ENV['DB_HOST']); $usuario = escapeshellarg($_ENV['DB_USER']); $database = escapeshellarg($_ENV['DB_NAME']); $password = escapeshellarg($_ENV['DB_PASSWORD']); // Comando pg_dump $comando = "PGPASSWORD=$password pg_dump --clean --if-exists --no-owner -h $host -U $usuario -d $database > $rutaBackup"; // Guardamos el comando a ejecutar mediante pg_dump exec($comando, $output, $resultado); // Lo ejecutamos if ($resultado === 0) { // Entra al if solo si el (exec) dio como resultado 0 (éxito) en la variable $resultado // Limitar cantidad de backups $maxBackups = 4; $archivos = glob($backupDir . '*.sql'); // Permite obtener todos los archivos ubicados en esa ruta if (count($archivos) > $maxBackups) { // Contamos la cantidad de archivos (comparando con la cantidad máxima definida) usort($archivos, function ($a, $b) { return filemtime($a) - filemtime($b); }); // Se ordenan en base a la fecha de modificación de mas antiguo a mas nuevo while (count($archivos) > $maxBackups) { $archivoEliminar = array_shift($archivos); // Se elimina el archivo del array unlink($archivoEliminar); // Se elimina fisicamente el archivo } } if (isset($_GET['auto'])) { $_SESSION['flash_success'] = "Copia de seguridad automática generada con éxito."; } else { $_SESSION['flash_success'] = "Backup generado correctamente."; } } else { $_SESSION['flash_error'] = "Error al generar el backup."; } header("Location: index.php?opt=$return"); exit; // LISTAR BACKUPS case 'backups': $backupDir = $_ENV['BACKUP_PATH'] ?? (__DIR__ . '/../backups/'); $archivos = glob($backupDir . '*.sql'); $backups = []; $totalSize = 0; $ultimoBackup = null; if ($archivos) { usort($archivos, function ($a, $b) { return filemtime($b) <=> filemtime($a); }); $ultimoBackup = date('d/m/Y H:i', filemtime($archivos[0])); // Guardamos el archivo mas reciente para informar en la vista foreach ($archivos as $archivo) { $size = filesize($archivo); // Obtenemos el tamaño total del archivo $backups[] = [ 'nombre' => basename($archivo), // Obtenemos nombre de archivo 'fecha' => date('d/m/Y H:i', filemtime($archivo)), // Obtenemos la fecha del archivo 'size' => round($size / 1024, 2) . ' KB' // Obtenemos el tamaño del archivo en KB ]; $totalSize += $size; // Acumulamos el tamaño de los archivos para obtener el total } } $totalSize = round($totalSize / 1024 / 1024, 2); // Total utilizado en MB ob_start(); require __DIR__ . '/../views/configuracion/buckupsView.php'; return ob_get_clean(); // DESCARGAR BACKUP case 'descargar_backup': $file = basename($_GET['file']); $backupDir = $_ENV['BACKUP_PATH'] ?? (__DIR__ . '/../backups/'); $ruta = $backupDir . $file; if (!file_exists($ruta)) { header("Location: index.php?opt=backups"); exit; } header('Content-Type: application/sql'); // Indica el tipo de contenido del archivo (SQL en este caso) header('Content-Disposition: attachment; filename="' . $file . '"'); // Fuerza la descarga del archivo en lugar de mostrarlo en el navegador y define el nombre con el que se va a guardar header('Content-Length: ' . filesize($ruta)); // Informa el tamaño del archivo (mejora la descarga/progreso) readfile($ruta); // Envía el contenido del archivo al navegador exit; // ELIMINAR BACKUP case 'eliminar_backup': if ($_SERVER['REQUEST_METHOD'] === 'POST') { $backupDir = $_ENV['BACKUP_PATH'] ?? (__DIR__ . '/../backups/'); $archivo = basename($_POST['file']); // Evita rutas maliciosas $rutaArchivo = $backupDir . $archivo; if (file_exists($rutaArchivo)) { unlink($rutaArchivo); $_SESSION['flash_success'] = "Backup eliminado correctamente."; } else { $_SESSION['flash_error'] = "El archivo no existe."; } header("Location: index.php?opt=backups"); exit; } // RESTAURAR BACKUP case 'restaurar_backup': if ($_SERVER['REQUEST_METHOD'] === 'POST') { $backupDir = $_ENV['BACKUP_PATH'] ?? (__DIR__ . '/../backups/'); $archivo = basename($_POST['file']); $rutaBackup = $backupDir . $archivo; if (!file_exists($rutaBackup)) { $_SESSION['flash_error'] = "El archivo de backup no existe."; header("Location: index.php?opt=backups"); exit; } $host = escapeshellarg($_ENV['DB_HOST']); $usuario = escapeshellarg($_ENV['DB_USER']); $database = escapeshellarg($_ENV['DB_NAME']); $password = escapeshellarg($_ENV['DB_PASSWORD']); // 1. BACKUP AUTOMÁTICO PREVIO $backupSeguridad = $backupDir . 'auto_pre_restore_' . date('Y-m-d_H-i-s') . '.sql'; $backupSeguridadEscaped = escapeshellarg($backupSeguridad); $comandoBackup = "PGPASSWORD=$password pg_dump --clean --if-exists --no-owner -h $host -U $usuario -d $database > $backupSeguridadEscaped"; exec($comandoBackup, $outBackup, $resultadoBackup); if ($resultadoBackup !== 0) { $_SESSION['flash_error'] = "No se pudo crear el backup de seguridad antes de restaurar."; header("Location: index.php?opt=backups"); exit; } // 2. RESTAURAR COPIA DE SEGURIDAD SELECCIONADA $rutaBackupEscaped = escapeshellarg($rutaBackup); $comandoRestore = "PGPASSWORD=$password psql -h $host -U $usuario -d $database < $rutaBackupEscaped"; exec($comandoRestore, $output, $resultadoRestore); if ($resultadoRestore === 0) { $_SESSION['flash_success'] = "Backup restaurado correctamente. Se creó una copia de seguridad previa."; } else { $_SESSION['flash_error'] = "Error al restaurar el backup."; } header("Location: index.php?opt=backups"); exit; } }