169 lines
5.6 KiB
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());
|
|
}
|
|
}
|
|
}
|