38471-vm/db/BackupService.php
2026-02-18 10:32:06 +00:00

103 lines
3.1 KiB
PHP

<?php
require_once __DIR__ . '/config.php';
class BackupService {
private static $backupDir = __DIR__ . '/../backups/';
public static function createBackup() {
if (!is_dir(self::$backupDir)) {
mkdir(self::$backupDir, 0775, true);
}
$filename = 'backup_' . date('Y-m-d_H-i-s') . '.sql';
$filePath = self::$backupDir . $filename;
// Use mysqldump for reliable export
$command = sprintf(
'mysqldump --no-tablespaces -h %s -u %s -p%s %s > %s',
escapeshellarg(DB_HOST),
escapeshellarg(DB_USER),
escapeshellarg(DB_PASS),
escapeshellarg(DB_NAME),
escapeshellarg($filePath)
);
exec($command, $output, $returnVar);
if ($returnVar === 0) {
// Get limit from settings
$limit = 5;
try {
$stmt = db()->prepare("SELECT `value` FROM settings WHERE `key` = 'backup_limit'");
$stmt->execute();
$val = $stmt->fetchColumn();
if ($val) $limit = (int)$val;
} catch (Exception $e) {}
self::rotateBackups($limit);
return ['success' => true, 'file' => $filename];
}
return ['success' => false, 'error' => 'Failed to create backup.'];
}
public static function restoreBackup($filename) {
$filePath = self::$backupDir . basename($filename);
if (!file_exists($filePath)) {
return ['success' => false, 'error' => 'Backup file not found.'];
}
$command = sprintf(
'mysql -h %s -u %s -p%s %s < %s',
escapeshellarg(DB_HOST),
escapeshellarg(DB_USER),
escapeshellarg(DB_PASS),
escapeshellarg(DB_NAME),
escapeshellarg($filePath)
);
exec($command, $output, $returnVar);
if ($returnVar === 0) {
return ['success' => true];
}
return ['success' => false, 'error' => 'Failed to restore backup.'];
}
public static function rotateBackups($limit = 5) {
$files = glob(self::$backupDir . 'backup_*.sql');
if (count($files) <= $limit) {
return;
}
// Sort by modification time (oldest first)
usort($files, function($a, $b) {
return filemtime($a) - filemtime($b);
});
$toDelete = count($files) - $limit;
for ($i = 0; $i < $toDelete; $i++) {
unlink($files[$i]);
}
}
public static function getBackups() {
if (!is_dir(self::$backupDir)) return [];
$files = glob(self::$backupDir . 'backup_*.sql');
usort($files, function($a, $b) {
return filemtime($b) - filemtime($a);
});
$result = [];
foreach ($files as $file) {
$result[] = [
'name' => basename($file),
'size' => round(filesize($file) / 1024, 2) . ' KB',
'date' => date('Y-m-d H:i:s', filemtime($file))
];
}
return $result;
}
}