diff --git a/app/Http/Controllers/Admin/QuestionController.php b/app/Http/Controllers/Admin/QuestionController.php index dc6421f..0c07d42 100644 --- a/app/Http/Controllers/Admin/QuestionController.php +++ b/app/Http/Controllers/Admin/QuestionController.php @@ -5,6 +5,7 @@ use App\Models\Question; use App\Models\Subject; use App\Models\AnswerOption; use Illuminate\Http\Request; +use Illuminate\Support\Facades\DB; class QuestionController extends Controller { public function index(Request $r) { $subjects = Subject::all(); @@ -97,4 +98,64 @@ class QuestionController extends Controller { $question->delete(); return redirect()->route('admin.questions.index')->with('success','Frage gelöscht.'); } + + public function export(Request $r) { + $query = Question::with(['subject','answerOptions'])->latest(); + if ($r->filled('subject')) $query->where('subject_id', $r->subject); + $data = $query->get()->map(fn($q) => [ + 'subject' => $q->subject->slug, + 'question_text' => $q->question_text, + 'type' => $q->type, + 'difficulty' => $q->difficulty, + 'points_value' => $q->points_value, + 'active' => (bool)$q->active, + 'options' => $q->answerOptions->map(fn($o) => [ + 'text' => $o->text, + 'is_correct' => (bool)$o->is_correct, + ])->values(), + ]); + $filename = 'fragen-' . now()->format('Y-m-d') . '.json'; + return response()->streamDownload( + fn() => print(json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)), + $filename, + ['Content-Type' => 'application/json'] + ); + } + + public function import(Request $r) { + $r->validate(['file' => 'required|file|mimes:json|max:2048']); + $raw = json_decode(file_get_contents($r->file('file')->getRealPath()), true); + if (!is_array($raw)) { + return back()->with('error', 'Ungültiges JSON-Format.'); + } + $subjects = Subject::pluck('id','slug'); + $imported = 0; + $skipped = 0; + DB::transaction(function() use ($raw, $subjects, &$imported, &$skipped) { + foreach ($raw as $item) { + if (empty($item['subject']) || !isset($subjects[$item['subject']])) { $skipped++; continue; } + if (empty($item['question_text'])) { $skipped++; continue; } + $q = Question::create([ + 'subject_id' => $subjects[$item['subject']], + 'question_text' => $item['question_text'], + 'type' => $item['type'] ?? 'multiple_choice', + 'difficulty' => $item['difficulty'] ?? 1, + 'points_value' => $item['points_value'] ?? 5, + 'active' => $item['active'] ?? true, + ]); + foreach (($item['options'] ?? []) as $i => $opt) { + AnswerOption::create([ + 'question_id' => $q->id, + 'text' => $opt['text'], + 'is_correct' => $opt['is_correct'] ?? false, + 'sort_order' => $i, + ]); + } + $imported++; + } + }); + $msg = "{$imported} Fragen importiert."; + if ($skipped) $msg .= " {$skipped} übersprungen (unbekanntes Fach oder fehlender Text)."; + return back()->with('success', $msg); + } } diff --git a/resources/views/admin/questions/index.blade.php b/resources/views/admin/questions/index.blade.php index e9827ee..23b7aec 100644 --- a/resources/views/admin/questions/index.blade.php +++ b/resources/views/admin/questions/index.blade.php @@ -1,7 +1,7 @@ @extends('layouts.admin') @section('title','Fragen') @section('content') -
JSON-Datei im gleichen Format wie der Export. Bestehende Fragen bleiben erhalten.
+ +