103 lines
3.1 KiB
PHP
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;
|
|
}
|
|
}
|