shubraVeil/admin/backup.php
2024-12-25 13:05:50 +02:00

141 lines
4.2 KiB
PHP

<?php
require_once __DIR__ . '/../includes/config.php';
class Backup {
private $backup_path;
private $db_config;
public function __construct() {
$this->backup_path = __DIR__ . '/../backups';
if (!file_exists($this->backup_path)) {
mkdir($this->backup_path, 0755, true);
}
$this->db_config = [
'host' => DB_SERVER,
'user' => DB_USERNAME,
'pass' => DB_PASSWORD,
'name' => DB_NAME
];
}
public function createBackup() {
$timestamp = date('Y-m-d_H-i-s');
$backup_file = $this->backup_path . '/backup_' . $timestamp;
// Backup database
$this->backupDatabase($backup_file . '.sql');
// Backup files
$this->backupFiles($backup_file . '.zip');
// Clean old backups (keep last 5)
$this->cleanOldBackups();
return true;
}
private function backupDatabase($file) {
$command = sprintf(
'mysqldump --host=%s --user=%s --password=%s %s > %s',
escapeshellarg($this->db_config['host']),
escapeshellarg($this->db_config['user']),
escapeshellarg($this->db_config['pass']),
escapeshellarg($this->db_config['name']),
escapeshellarg($file)
);
exec($command, $output, $return_var);
if ($return_var !== 0) {
throw new Exception('Database backup failed');
}
}
private function backupFiles($file) {
$root_path = __DIR__ . '/..';
$exclude_dirs = ['backups', 'cache', 'logs', 'vendor'];
$zip = new ZipArchive();
if ($zip->open($file, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
throw new Exception('Cannot create zip file');
}
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($root_path),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $name => $file) {
if ($file->isDir()) {
continue;
}
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($root_path) + 1);
// Skip excluded directories
$skip = false;
foreach ($exclude_dirs as $exclude) {
if (strpos($relativePath, $exclude . '/') === 0) {
$skip = true;
break;
}
}
if (!$skip) {
$zip->addFile($filePath, $relativePath);
}
}
$zip->close();
}
private function cleanOldBackups($keep = 5) {
$files = glob($this->backup_path . '/*');
usort($files, function($a, $b) {
return filemtime($b) - filemtime($a);
});
if (count($files) > $keep) {
for ($i = $keep; $i < count($files); $i++) {
unlink($files[$i]);
}
}
}
public function restore($backup_date) {
$sql_file = $this->backup_path . '/backup_' . $backup_date . '.sql';
$zip_file = $this->backup_path . '/backup_' . $backup_date . '.zip';
if (!file_exists($sql_file) || !file_exists($zip_file)) {
throw new Exception('Backup files not found');
}
// Restore database
$command = sprintf(
'mysql --host=%s --user=%s --password=%s %s < %s',
escapeshellarg($this->db_config['host']),
escapeshellarg($this->db_config['user']),
escapeshellarg($this->db_config['pass']),
escapeshellarg($this->db_config['name']),
escapeshellarg($sql_file)
);
exec($command, $output, $return_var);
if ($return_var !== 0) {
throw new Exception('Database restore failed');
}
// Restore files
$zip = new ZipArchive();
if ($zip->open($zip_file) !== true) {
throw new Exception('Cannot open backup archive');
}
$zip->extractTo(__DIR__ . '/..');
$zip->close();
return true;
}
}