Files
2026-06-30 15:01:01 -03:00

276 lines
11 KiB
PHP

<?php
include("../db.php");
if (!isset($_SESSION['rol']) || $_SESSION['rol'] !== 'admin') {
header("Location: ../login.php?error=acceso_denegado");
exit();
}
// Configuración de la carpeta donde se guardan los archivos de respaldo comprimidos
$carpeta_backups = "backups_files/";
// Si no existe la carpeta, la creamos automáticamente con permisos
if (!file_exists($carpeta_backups)) {
mkdir($carpeta_backups, 0777, true);
}
$mensaje = "";
$tipo_mensaje = "";
// --- PROCESO DE GENERACIÓN DE BACKUP INTEGRAL ---
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['crear_backup'])) {
// Nombres de archivos con marcas de tiempo únicas
$timestamp = date("Y-m-d_H-i-s");
$nombre_sql = "backup_la_pecosa_" . $timestamp . ".sql";
$nombre_zip = "backup_sistema_completo_" . $timestamp . ".zip";
$ruta_sql_temporal = $carpeta_backups . $nombre_sql;
$ruta_zip_final = $carpeta_backups . $nombre_zip;
// Parámetros locales para XAMPP
$host = "localhost";
$user = "root";
$bd = "lapecosa";
// 1. Ejecutar comando para extraer el volcado SQL de las tablas
// Buscar mysqldump automáticamente en Laragon
$laragon_mysql = glob("C:/laragon/bin/mysql/*/bin/mysqldump.exe");
$mysqldump_path = !empty($laragon_mysql) ? $laragon_mysql[0] : "mysqldump";
$comando = "\"$mysqldump_path\" --no-defaults --user=$user --host=$host $bd > $ruta_sql_temporal";
system($comando, $resultado_sql);
// 2. Si el SQL se generó correctamente, procedemos a empaquetar archivos de configuración y recursos
if ($resultado_sql === 0 && file_exists($ruta_sql_temporal)) {
$zip = new ZipArchive();
if ($zip->open($ruta_zip_final, ZipArchive::CREATE) === TRUE) {
// A. Añadir el script SQL de la Base de Datos al ZIP
$zip->addFile($ruta_sql_temporal, $nombre_sql);
// B. Añadir el archivo crítico de configuración técnica (db.php)
if (file_exists("../db.php")) {
$zip->addFile("../db.php", "config/db.php");
}
// C. Añadir de forma recursiva la carpeta de imágenes generales de diseño (../imagenes)
$ruta_imagenes = "../imagenes";
if (file_exists($ruta_imagenes)) {
$archivos_imagenes = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($ruta_imagenes, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($archivos_imagenes as $item) {
$ruta_real = $item->getRealPath();
$ruta_relativa_zip = "imagenes_sitio/" . substr($ruta_real, strlen(realpath($ruta_imagenes)) + 1);
if ($item->isDir()) {
$zip->addEmptyDir($ruta_relativa_zip);
} else {
$zip->addFile($ruta_real, $ruta_relativa_zip);
}
}
}
// Añadir de forma recursiva la carpeta de fotos de productos cargados (../img)
$ruta_img_productos = "../img";
if (file_exists($ruta_img_productos)) {
$archivos_productos = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($ruta_img_productos, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($archivos_productos as $item) {
$ruta_real = $item->getRealPath();
// Lo guardamos estructurado bajo una carpeta propia dentro del ZIP
$ruta_relativa_zip = "imagenes_productos/" . substr($ruta_real, strlen(realpath($ruta_img_productos)) + 1);
if ($item->isDir()) {
$zip->addEmptyDir($ruta_relativa_zip);
} else {
$zip->addFile($ruta_real, $ruta_relativa_zip);
}
}
}
// Cerramos y guardamos definitivamente el archivo ZIP
$zip->close();
// Borramos el archivo .sql suelto temporal para no duplicar espacio en el disco duro
unlink($ruta_sql_temporal);
header("Location: backup.php?status=success&file=$nombre_zip");
} else {
header("Location: backup.php?status=error_zip");
}
} else {
header("Location: backup.php?status=error_sql");
}
exit();
}
if (isset($_GET['status'])) {
if ($_GET['status'] === 'success') {
$file = htmlspecialchars($_GET['file']);
$mensaje = "¡Copia de seguridad del sistema completo generada con éxito! Archivo: $file";
$tipo_mensaje = "success";
} elseif ($_GET['status'] === 'error_sql') {
$mensaje = "Error al generar el volcado SQL de la Base de Datos. Verifique la ruta de mysqldump en XAMPP.";
$tipo_mensaje = "error";
} elseif ($_GET['status'] === 'error_zip') {
$mensaje = "Error al comprimir el archivo ZIP. Asegúrese de que PHP tenga extensiones activas y permisos de escritura.";
$tipo_mensaje = "error";
}
}
// Escaneamos la carpeta buscando únicamente los archivos ZIP generados
$archivos_guardados = array_diff(scandir($carpeta_backups), array('.', '..'));
$archivos_guardados = array_filter($archivos_guardados, function($archivo) {
return pathinfo($archivo, PATHINFO_EXTENSION) === 'zip';
});
rsort($archivos_guardados);
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Copia de Seguridad - La Pecosa</title>
<link rel="stylesheet" href="../css/all.min.css">
<link rel="stylesheet" href="admin_style.css">
<style>
.box-backup {
background: white;
padding: 30px;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0,0,0,0.02);
border: 1px solid rgba(0,0,0,0.04);
margin-bottom: 35px;
display: flex;
align-items: center;
justify-content: space-between;
}
.box-backup-info h2 { font-size: 1.2rem; margin-bottom: 8px; color: #222; }
.box-backup-info p { font-size: 0.85rem; color: #666; max-width: 500px; line-height: 1.4; }
.btn-backup {
background-color: #dc2626;
color: white;
border: none;
padding: 14px 28px;
border-radius: 8px;
cursor: pointer;
font-weight: bold;
font-size: 1rem;
box-shadow: 0 4px 10px rgba(220, 38, 38, 0.2);
transition: 0.3s ease;
display: flex;
align-items: center;
gap: 10px;
}
.btn-backup:hover {
background-color: #b91c1c;
transform: translateY(-1px);
box-shadow: 0 6px 15px rgba(220, 38, 38, 0.3);
}
.alert-ui { padding: 15px; border-radius: 8px; margin-bottom: 25px; font-weight: 600; font-size: 0.95rem; }
.alert-ui.success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
.alert-ui.error { background: #fdf2f2; color: #e02828; border: 1px solid #fde2e2; }
.btn-download {
background: #e99535;
color: white;
padding: 8px 14px;
border-radius: 6px;
text-decoration: none;
font-size: 0.85rem;
font-weight: bold;
transition: 0.2s ease;
display: inline-flex;
align-items: center;
gap: 6px;
}
.btn-download:hover {
background: #eb830b;
transform: translateY(-1px);
}
</style>
</head>
<body>
<?php include("sidebar.php"); ?>
<div class="main-content">
<div class="page-header">
<h1><i class="fa-solid fa-database"></i> Copias de seguridad (Backup integral)</h1>
</div>
<?php if(!empty($mensaje)): ?>
<div class="alert-ui <?php echo $tipo_mensaje; ?>">
<i class="fa-solid <?php echo $tipo_mensaje === 'success' ? 'fa-circle-check' : 'fa-circle-exclamation'; ?>"></i>
<?php echo $mensaje; ?>
</div>
<?php endif; ?>
<div class="box-backup">
<div class="box-backup-info">
<h2>Respaldar sistema completo e infraestructura</h2>
<p>
Al hacer clic en el botón se empaquetará un archivo comprimido <strong>.ZIP</strong> conteniendo el volcado SQL de la base de datos (tablas, pedidos, menú), los archivos de conexión y configuración del sistema, junto con la totalidad de imágenes y recursos multimedia subidos por la administración de La Pecosa.
</p>
</div>
<form action="backup.php" method="POST">
<button type="submit" name="crear_backup" class="btn-backup">
<i class="fa-solid fa-cloud-arrow-down"></i> Generar respaldo (.zip)
</button>
</form>
</div>
<div class="table-container">
<h2 style="font-size: 1.1rem; margin-bottom: 15px; color: #222;"><i class="fa-solid fa-folder-open"></i> Respaldos integrales guardados en el servidor</h2>
<table class="admin-table">
<thead>
<tr>
<th>Nombre del Archivo Completo</th>
<th>Tipo de Paquete</th>
<th>Ubicación en Servidor</th>
<th>Acción</th>
</tr>
</thead>
<tbody>
<?php if (empty($archivos_guardados)): ?>
<tr>
<td colspan="4" style="text-align: center; color: #888; padding: 25px;">
<i class="fa-solid fa-box-open" style="font-size: 1.5rem; margin-bottom: 8px;"></i><br>
No se encontraron paquetes comprimidos de seguridad.
</td>
</tr>
<?php else: ?>
<?php foreach ($archivos_guardados as $archivo_zip): ?>
<tr>
<td><strong><i class="fa-solid fa-file-archive" style="color: #f59e0b; margin-right: 5px;"></i> <?php echo $archivo_zip; ?></strong></td>
<td><span style="background: #fffbeb; padding: 3px 8px; border-radius: 4px; font-size: 0.8rem; font-weight: bold; color: #b45309; border: 1px solid #fef3c7;">ZIP (BD + Archivos)</span></td>
<td><code>/admin/backups_files/</code></td>
<td>
<a href="descargar_file.php?file=<?php echo urlencode($archivo_zip); ?>" class="btn-download" style="background-color: #10b981;">
<i class="fa-solid fa-download"></i> Descargar .zip
</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</body>
</html>