From 7d94be7a8cdd09b529fde9e38d8883c5c44b8d8f Mon Sep 17 00:00:00 2001 From: jeremy bayse Date: Sat, 28 Mar 2026 07:59:17 +0100 Subject: [PATCH] feat: add app backup functionality for admins --- app/Http/Controllers/BackupController.php | 60 +++++++++++++++++++++++ resources/js/Layouts/AdminLayout.vue | 1 + routes/web.php | 1 + 3 files changed, 62 insertions(+) create mode 100644 app/Http/Controllers/BackupController.php diff --git a/app/Http/Controllers/BackupController.php b/app/Http/Controllers/BackupController.php new file mode 100644 index 0000000..fba343e --- /dev/null +++ b/app/Http/Controllers/BackupController.php @@ -0,0 +1,60 @@ + " . escapeshellarg($sqlDumpFilePath); + if (empty($password)) { + $command = "mysqldump --user={$userName} --host={$host} {$databaseName} > " . escapeshellarg($sqlDumpFilePath); + } + + exec($command); + + $zip = new ZipArchive; + if ($zip->open($backupFilePath, ZipArchive::CREATE) === TRUE) { + // Add DB dump + if (file_exists($sqlDumpFilePath)) { + $zip->addFile($sqlDumpFilePath, 'database.sql'); + } + + // Add documents specifically searching the local disk + $allFiles = Storage::disk('local')->allFiles(); + foreach ($allFiles as $filePath) { + $fullPath = Storage::disk('local')->path($filePath); + // The zip structure will have a folder 'storage_files' containing the relative path + $zip->addFile($fullPath, 'storage_files/' . $filePath); + } + + $zip->close(); + } + + if (file_exists($sqlDumpFilePath)) { + unlink($sqlDumpFilePath); + } + + if (file_exists($backupFilePath)) { + return response()->download($backupFilePath)->deleteFileAfterSend(true); + } + + return back()->with('error', 'Erreur lors de la création de la sauvegarde.'); + } +} diff --git a/resources/js/Layouts/AdminLayout.vue b/resources/js/Layouts/AdminLayout.vue index 76857f7..9c36d5b 100644 --- a/resources/js/Layouts/AdminLayout.vue +++ b/resources/js/Layouts/AdminLayout.vue @@ -115,6 +115,7 @@ const isSidebarOpen = ref(true); diff --git a/routes/web.php b/routes/web.php index 74ccfca..aa20390 100644 --- a/routes/web.php +++ b/routes/web.php @@ -83,6 +83,7 @@ Route::middleware('auth')->group(function () { Route::resource('quizzes', \App\Http\Controllers\QuizController::class)->only(['index', 'store', 'show', 'update', 'destroy']); Route::resource('job-positions', \App\Http\Controllers\JobPositionController::class)->only(['index', 'store', 'update', 'destroy']); Route::resource('quizzes.questions', \App\Http\Controllers\QuestionController::class)->only(['store', 'update', 'destroy']); + Route::get('/backup', [\App\Http\Controllers\BackupController::class, 'download'])->name('backup'); Route::delete('/attempts/{attempt}', [\App\Http\Controllers\AttemptController::class, 'destroy'])->name('attempts.destroy'); Route::patch('/answers/{answer}/score', [\App\Http\Controllers\AttemptController::class, 'updateAnswerScore'])->name('answers.update-score'); });