f77fc725a8
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
67 lines
2.0 KiB
PHP
67 lines
2.0 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\ActivityLog;
|
|
use Symfony\Component\Process\Process;
|
|
|
|
class BackupController extends Controller
|
|
{
|
|
public function download()
|
|
{
|
|
$db = config('database.connections.mysql');
|
|
|
|
$process = new Process([
|
|
'mysqldump',
|
|
'-h', $db['host'],
|
|
'-P', (string) $db['port'],
|
|
'-u', $db['username'],
|
|
'--single-transaction',
|
|
'--skip-lock-tables',
|
|
'--no-tablespaces',
|
|
$db['database'],
|
|
], null, ['MYSQL_PWD' => $db['password']]);
|
|
|
|
$process->setTimeout(120);
|
|
$process->run();
|
|
|
|
if (!$process->isSuccessful()) {
|
|
ActivityLog::record('backup', 'Gagal membuat backup database');
|
|
return response()->json(['message' => 'Backup gagal: ' . $process->getErrorOutput()], 500);
|
|
}
|
|
|
|
ActivityLog::record('backup', 'Mengunduh backup database');
|
|
|
|
$filename = 'backup-webgis-' . now()->format('Ymd-His') . '.sql';
|
|
return response($process->getOutput(), 200, [
|
|
'Content-Type' => 'application/sql',
|
|
'Content-Disposition' => "attachment; filename=\"{$filename}\"",
|
|
]);
|
|
}
|
|
|
|
public function listBackups()
|
|
{
|
|
$dir = storage_path('app/backups');
|
|
$files = is_dir($dir) ? glob($dir . '/backup-webgis-*.sql') : [];
|
|
usort($files, fn($a, $b) => filemtime($b) - filemtime($a));
|
|
|
|
$list = array_map(fn($f) => [
|
|
'name' => basename($f),
|
|
'size_kb' => round(filesize($f) / 1024, 1),
|
|
'created_at' => date('d/m/Y H:i', filemtime($f)),
|
|
], $files);
|
|
|
|
return response()->json($list);
|
|
}
|
|
|
|
public function downloadStored(string $filename)
|
|
{
|
|
if (!preg_match('/^backup-webgis-[\d-]+\.sql$/', $filename)) {
|
|
abort(400, 'Nama file tidak valid');
|
|
}
|
|
$path = storage_path('app/backups/' . $filename);
|
|
if (!file_exists($path)) abort(404);
|
|
return response()->download($path);
|
|
}
|
|
}
|