MIF_E31230069/spk_kontrakan/app/Http/Controllers/BackupController.php

169 lines
5.6 KiB
PHP

<?php
namespace App\Http\Controllers;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\File;
use ZipArchive;
use Exception;
class BackupController extends Controller
{
private $backupPath;
public function __construct()
{
$this->backupPath = storage_path('backups');
// Create backups directory jika belum ada
if (!File::isDirectory($this->backupPath)) {
File::makeDirectory($this->backupPath, 0755, true);
}
}
public function index(Request $request)
{
$backups = [];
if (File::isDirectory($this->backupPath)) {
$files = File::files($this->backupPath);
foreach ($files as $file) {
$modifiedAt = Carbon::createFromTimestamp($file->getMTime(), config('app.timezone'));
$backups[] = [
'name' => $file->getFilename(),
'size' => $file->getSize(),
'date' => $modifiedAt->timestamp,
'date_display' => $modifiedAt->format('d M Y H:i'),
'path' => $file->getRealPath(),
];
}
}
// Sort by date descending
usort($backups, function($a, $b) {
return $b['date'] <=> $a['date'];
});
return view('admin.backup.index', compact('backups'));
}
public function create(Request $request)
{
try {
$exitCode = Artisan::call('database:backup');
if ($exitCode === 0) {
$output = trim(Artisan::output());
return redirect()->back()->with('success', $output !== '' ? $output : 'Backup berhasil dibuat');
}
$output = trim(Artisan::output());
return redirect()->back()->with('error', $output !== '' ? $output : 'Gagal membuat backup');
} catch (Exception $e) {
return redirect()->back()->with('error', 'Error: ' . $e->getMessage());
}
}
public function download($backup)
{
// Sanitize: prevent path traversal
$backup = basename($backup);
$backupPath = $this->backupPath . '/' . $backup;
if (!File::exists($backupPath)) {
return redirect()->back()->with('error', 'File backup tidak ditemukan');
}
return response()->download($backupPath);
}
public function delete($backup)
{
try {
// Sanitize: prevent path traversal
$backup = basename($backup);
$backupPath = $this->backupPath . '/' . $backup;
if (!File::exists($backupPath)) {
return redirect()->back()->with('error', 'File backup tidak ditemukan');
}
File::delete($backupPath);
return redirect()->back()->with('success', 'Backup berhasil dihapus');
} catch (Exception $e) {
return redirect()->back()->with('error', 'Error: ' . $e->getMessage());
}
}
public function restore(Request $request, $backup)
{
try {
// Sanitize: prevent path traversal
$backup = basename($backup);
$backupPath = $this->backupPath . '/' . $backup;
if (!File::exists($backupPath)) {
return redirect()->back()->with('error', 'File backup tidak ditemukan');
}
// Extract zip jika zip file
if (pathinfo($backupPath, PATHINFO_EXTENSION) === 'zip') {
$extractPath = $this->backupPath . '/temp_' . time();
$zip = new ZipArchive();
if ($zip->open($backupPath) === true) {
$zip->extractTo($extractPath);
$zip->close();
$sqlFile = $extractPath . '/database.sql';
if (!File::exists($sqlFile)) {
File::deleteDirectory($extractPath);
return redirect()->back()->with('error', 'File SQL tidak ditemukan dalam backup');
}
} else {
return redirect()->back()->with('error', 'Gagal membuka file zip');
}
} else {
$sqlFile = $backupPath;
}
// Restore database (use config() instead of env() for config:cache compatibility)
$database = config('database.connections.mysql.database');
$username = config('database.connections.mysql.username');
$password = config('database.connections.mysql.password');
$host = config('database.connections.mysql.host');
$command = sprintf(
'mysql --user=%s --password=%s --host=%s %s < "%s"',
escapeshellarg($username),
escapeshellarg($password),
escapeshellarg($host),
escapeshellarg($database),
$sqlFile
);
$output = null;
$exitCode = null;
exec($command, $output, $exitCode);
// Cleanup temp files
if (isset($extractPath) && File::isDirectory($extractPath)) {
File::deleteDirectory($extractPath);
}
if ($exitCode === 0) {
return redirect()->back()->with('success', 'Database berhasil di-restore');
} else {
return redirect()->back()->with('error', 'Gagal restore database');
}
} catch (Exception $e) {
return redirect()->back()->with('error', 'Error: ' . $e->getMessage());
}
}
}