quiz_id); // 1. Cek Retake (Kesempatan mengulang) $retake = $quiz->retake; $submit_count = QuizSubmission::where('quiz_id', $quiz->id) ->where('user_id', auth()->user()->id) ->count(); if ($submit_count >= $retake) { Session::flash('warning', get_phrase('Attempt has been over.')); return redirect()->back(); } // 2. Rapikan Input Jawaban $inputs = $request->except(['_token', 'quiz_id']); $submits = []; // Loop input untuk membersihkan format data (terutama jika dari JS frontend) foreach ($inputs as $question_id => $answer) { if ($answer !== null) { // Jika input berupa string JSON (kecuali 'true'/'false'), decode dulu if (is_string($answer) && !in_array($answer, ['true', 'false'])) { $decoded = json_decode($answer, true); if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) { // Ambil value jika strukturnya array of objects $submits[$question_id] = array_column($decoded, 'value'); } else { $submits[$question_id] = $answer; } } else { $submits[$question_id] = $answer; } } } // 3. Ambil Soal dari Database // Kita ambil soal berdasarkan key dari jawaban yang dikirim $question_ids = array_keys($submits); $questions = Question::whereIn('id', $question_ids)->get(); $right_answers = []; $wrong_answers = []; // 4. Proses Koreksi Jawaban foreach ($questions as $question) { // PENTING: Ambil jawaban user berdasarkan ID Soal, bukan urutan index loop if (!isset($submits[$question->id])) { continue; } $submitted = $submits[$question->id]; $correct_answer = json_decode($question->answer, true); $isCorrect = false; // Logika per tipe soal if ($question->type == 'mcq') { // Cek array diff (bolak-balik) untuk memastikan isi array sama persis $isCorrect = empty(array_diff($correct_answer, $submitted)) && empty(array_diff($submitted, $correct_answer)); } elseif ($question->type == 'fill_blanks') { if (count($correct_answer) === count($submitted)) { $isCorrect = true; foreach ($correct_answer as $i => $ans) { // Trim dan strtolower agar tidak case-sensitive if (trim(strtolower($ans)) !== trim(strtolower($submitted[$i]))) { $isCorrect = false; break; } } } } elseif ($question->type == 'true_false') { $isCorrect = strtolower(json_encode($correct_answer)) === strtolower($submitted); } // Masukkan ke bucket Benar/Salah if ($isCorrect) { $right_answers[] = $question->id; } else { $wrong_answers[] = $question->id; } } // 5. Simpan Hasil Submission QuizSubmission::create([ 'quiz_id' => $quiz->id, 'user_id' => auth()->user()->id, 'correct_answer' => json_encode($right_answers), 'wrong_answer' => json_encode($wrong_answers), 'submits' => json_encode($submits), ]); // 6. Hitung Nilai $total_questions = $questions->count(); $mark_per_question = $total_questions > 0 ? ($quiz->total_mark / $total_questions) : 0; $obtained_mark = count($right_answers) * $mark_per_question; // 7. Cek Kelulusan if ($obtained_mark >= $quiz->pass_mark) { // PANGGIL FUNGSI YANG BERADA DI CLASS YANG SAMA $this->update_watch_history2( $quiz->id, $quiz->course_id, auth()->user()->id ); Session::flash('success', get_phrase('Congratulations, you passed the quiz.')); } else { Session::flash('warning', get_phrase('You did not reach the minimum score.')); } return redirect()->back(); } public function update_watch_history2($lesson_id, $course_id, $student_id) { // Validasi Course $course = Course::where('id', $course_id)->first(); if (!$course) return; // Validasi Enrollment $enrollment = Enrollment::where('course_id', $course->id) ->where('user_id', $student_id) ->exists(); // Cek Role (Jika admin/instruktur boleh bypass enrollment check) $currentUserRole = auth()->check() ? auth()->user()->role : 'student'; if (!$enrollment && ($currentUserRole != 'admin' && !is_course_instructor($course->id))) { return; } // Ambil semua lesson ID untuk hitung progress manual $total_lesson_ids = Lesson::where('course_id', $course_id)->pluck('id')->toArray(); // Ambil data history user $watch_history = Watch_history::where('course_id', $course_id) ->where('student_id', $student_id) ->first(); $completed_lessons = []; // Parse data lama if ($watch_history && $watch_history->completed_lesson) { $decoded = json_decode($watch_history->completed_lesson, true); if (is_array($decoded)) { $completed_lessons = $decoded; } } // Tambahkan lesson_id baru jika belum ada if (!in_array($lesson_id, $completed_lessons)) { $completed_lessons[] = $lesson_id; } // Tentukan apakah course selesai $is_completed = count($total_lesson_ids) <= count($completed_lessons); $data = [ 'course_id' => $course_id, 'student_id' => $student_id, 'watching_lesson_id' => $lesson_id, 'completed_lesson' => json_encode($completed_lessons), 'completed_date' => $is_completed ? time() : null, ]; // Simpan ke DB if ($watch_history) { Watch_history::where('id', $watch_history->id)->update($data); } else { // Gunakan create agar timestamp created_at terisi otomatis Watch_history::create($data); } // --- LOGIKA SERTIFIKAT --- // Hitung progress secara manual agar lebih akurat $progress_percentage = 0; if (count($total_lesson_ids) > 0) { $progress_percentage = (count($completed_lessons) / count($total_lesson_ids)) * 100; } if ($progress_percentage >= 100) { $certificateExists = Certificate::where('user_id', $student_id) ->where('course_id', $course_id) ->exists(); if (!$certificateExists) { Certificate::create([ 'user_id' => $student_id, 'course_id' => $course_id, 'identifier' => substr(md5(uniqid(mt_rand(), true)), 0, 10), // Generate random ID ]); } } return true; } public function load_result(Request $request) { $page_data['quiz'] = Lesson::where('id', $request->quiz_id)->first(); $page_data['questions'] = Question::where('quiz_id', $request->quiz_id)->get(); $page_data['result'] = QuizSubmission::where('id', $request->submit_id) ->where('quiz_id', $request->quiz_id) ->where('user_id', auth()->user()->id) ->first(); return view('course_player.quiz.result', $page_data); } public function load_questions(Request $request) { $page_data['quiz'] = Lesson::where('id', $request->quiz_id)->first(); $page_data['questions'] = Question::where('quiz_id', $request->quiz_id)->get(); $page_data['submits'] = QuizSubmission::where('quiz_id', $request->quiz_id) ->where('user_id', auth()->user()->id) ->get(); $page_data['course_details'] = Course::where('id', $page_data['quiz']->course_id)->first(); return view('course_player.quiz.questions', $page_data); } }