From f40e88ed6e3700b5b1c5a845a76bd05eb064554b Mon Sep 17 00:00:00 2001 From: imnavajas Date: Thu, 10 Jul 2025 15:02:55 +0200 Subject: [PATCH] Avances --- ci4/app/Controllers/Sistema/Backups.php | 101 +++++++++++++++++------- 1 file changed, 73 insertions(+), 28 deletions(-) diff --git a/ci4/app/Controllers/Sistema/Backups.php b/ci4/app/Controllers/Sistema/Backups.php index 84538b10..37115161 100644 --- a/ci4/app/Controllers/Sistema/Backups.php +++ b/ci4/app/Controllers/Sistema/Backups.php @@ -6,6 +6,12 @@ use App\Models\Sistema\BackupModel; use phpseclib3\Net\SFTP; use ZipArchive; +/* +erp-backup +5#xJ)6nENB!F~x^ +*/ + + class Backups extends BaseController { protected $backupModel; @@ -379,6 +385,7 @@ class Backups extends BaseController public function restoreLocal($file) { $path = WRITEPATH . 'backups/' . $file; + if (!file_exists($path)) { throw new \CodeIgniter\Exceptions\PageNotFoundException("Backup no encontrado."); } @@ -399,21 +406,37 @@ class Backups extends BaseController $sqlFile = $sqlFiles[0]; - $dbConfig = config('Database')->default; - $host = $dbConfig['hostname']; - $username = $dbConfig['username']; - $password = $dbConfig['password']; - $database = $dbConfig['database']; - - $cmd = "mysql -h {$host} -u{$username} -p'{$password}' {$database} < {$sqlFile}"; - system($cmd, $retval); - - if ($retval !== 0) { - throw new \RuntimeException("Error al restaurar la base de datos. Código: $retval"); + // === Verificar que el archivo SQL existe y tiene contenido + if (!file_exists($sqlFile)) { + throw new \RuntimeException("Archivo SQL no encontrado."); } - array_map('unlink', glob($extractPath . '*')); - rmdir($extractPath); + if (filesize($sqlFile) === 0) { + throw new \RuntimeException("El archivo SQL está vacío."); + } + + // === Configuración de base de datos + $dbConfig = config('Database')->default; + $host = escapeshellarg($dbConfig['hostname']); + $username = escapeshellarg($dbConfig['username']); + $password = escapeshellarg($dbConfig['password']); + $database = escapeshellarg($dbConfig['database']); + + // === Construcción del comando con stderr redirigido + $cmd = "mysql -h $host -u $username -p$password $database -e \"source $sqlFile\" 2>&1"; + + // === Ejecutar y capturar la salida + exec($cmd, $output, $retval); + + // === Verificar resultado + if ($retval !== 0) { + throw new \RuntimeException("Error al restaurar la base de datos:\n" . implode("\n", $output)); + } + + // === Limpieza + helper('filesystem'); + delete_files($extractPath, true); // elimina contenido + rmdir($extractPath); // elimina el directorio return redirect()->to(route_to('backupsList'))->with('message', 'Backup restaurado correctamente (vía sistema).'); } else { @@ -424,54 +447,76 @@ class Backups extends BaseController + public function restoreRemote($filename) { helper('filesystem'); - // Buscar el backup en la base de datos + $entorno = getenv('SK_ENVIRONMENT'); + + if ($entorno === 'development') { + // Construir ruta remota directamente + $remotePath = '/users/erp2019/backups_erp/' . $filename; + $localPath = WRITEPATH . 'backups/' . $filename; + + $sftpHost = getenv('HIDRIVE_HOST'); + $sftpUser = getenv('HIDRIVE_USER'); + $sftpPass = getenv('HIDRIVE_PASS'); + + $sftp = new SFTP($sftpHost); + if (!$sftp->login($sftpUser, $sftpPass)) { + return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo autenticar en el servidor SFTP.'); + } + + $fileContents = $sftp->get($remotePath); + if ($fileContents === false) { + return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo descargar el archivo remoto.'); + } + + if (write_file($localPath, $fileContents) === false) { + return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo guardar el archivo localmente.'); + } + + // Restaurar directamente + return $this->restoreLocal($filename); + } + + // Producción: flujo normal con base de datos $backup = $this->backupModel->where('filename', $filename)->first(); if (!$backup || empty($backup['path_remote'])) { return redirect()->to(route_to('backupsList'))->with('error', 'Backup remoto no encontrado en la base de datos.'); } - // Parámetros SFTP - $sftpHost = getenv('HIDRIVE_HOST'); - $sftpUser = getenv('HIDRIVE_USER'); - $sftpPass = getenv('HIDRIVE_PASS'); $remotePath = $backup['path_remote']; $localPath = WRITEPATH . 'backups/' . $filename; - // Conectar al SFTP - $sftp = new SFTP($sftpHost); + $sftpHost = getenv('HIDRIVE_HOST'); + $sftpUser = getenv('HIDRIVE_USER'); + $sftpPass = getenv('HIDRIVE_PASS'); + $sftp = new SFTP($sftpHost); if (!$sftp->login($sftpUser, $sftpPass)) { return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo autenticar en el servidor SFTP.'); } - // Descargar el archivo $fileContents = $sftp->get($remotePath); - if ($fileContents === false) { return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo descargar el archivo remoto.'); } - // Guardar localmente if (write_file($localPath, $fileContents) === false) { return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo guardar el archivo localmente.'); } - // Actualizar la base de datos para marcar el archivo como local - $this->backupModel->update($backup['id'], [ - 'path_local' => $localPath, - ]); + $this->backupModel->update($backup['id'], ['path_local' => $localPath]); - // Restaurar usando el método local return $this->restoreLocal($filename); } + private function sendToSFTP($localPath, $remoteFilename) { $sftpHost = getenv('HIDRIVE_HOST');