102 lines
3.7 KiB
PHP
102 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\QuestionQuiz;
|
|
use App\Models\ReponseQuiz;
|
|
use App\Models\SessionQuiz;
|
|
use Illuminate\Database\QueryException;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
/**
|
|
* Côté élève du quiz flash (chantier « vrai cockpit », étape 2) : pas de
|
|
* code à saisir, pas d'invité — l'élève est déjà un compte réel de la
|
|
* classe, le quiz apparaît directement sur son tableau de bord.
|
|
*/
|
|
class QuizEleveController extends Controller
|
|
{
|
|
public function etat(): JsonResponse
|
|
{
|
|
$eleve = Auth::guard('eleve')->user();
|
|
|
|
$session = SessionQuiz::query()
|
|
->whereIn('statut', [SessionQuiz::EN_ATTENTE, SessionQuiz::EN_COURS])
|
|
->whereHas('quiz', fn ($q) => $q->where('classe_id', $eleve->classe_id))
|
|
->with('questionCourante.choix')
|
|
->latest('demarree_a')
|
|
->first();
|
|
|
|
if (! $session) {
|
|
return response()->json(['session' => null]);
|
|
}
|
|
|
|
$dejaRepondu = $session->question_quiz_courante_id
|
|
? ReponseQuiz::where('session_quiz_id', $session->id)
|
|
->where('question_quiz_id', $session->question_quiz_courante_id)
|
|
->where('eleve_id', $eleve->id)
|
|
->exists()
|
|
: false;
|
|
|
|
$question = $session->questionCourante;
|
|
|
|
return response()->json([
|
|
'session' => [
|
|
'id' => $session->id,
|
|
'statut' => $session->statut,
|
|
'deja_repondu' => $dejaRepondu,
|
|
'question' => $question ? [
|
|
'id' => $question->id,
|
|
'enonce' => $question->enonce,
|
|
'type' => $question->type,
|
|
'choix' => $question->type === QuestionQuiz::QCM
|
|
? $question->choix->map(fn ($c) => ['id' => $c->id, 'texte' => $c->texte])->values()
|
|
: [],
|
|
] : null,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function repondre(Request $request, SessionQuiz $session): JsonResponse
|
|
{
|
|
$eleve = Auth::guard('eleve')->user();
|
|
abort_if($session->quiz->classe_id !== $eleve->classe_id, 403);
|
|
abort_if($session->statut !== SessionQuiz::EN_COURS || ! $session->question_quiz_courante_id, 409, 'Aucune question en cours.');
|
|
|
|
$question = $session->questionCourante;
|
|
abort_if(
|
|
ReponseQuiz::where('session_quiz_id', $session->id)
|
|
->where('question_quiz_id', $question->id)
|
|
->where('eleve_id', $eleve->id)
|
|
->exists(),
|
|
409,
|
|
'Déjà répondu.'
|
|
);
|
|
|
|
$donnees = $request->validate([
|
|
'choix_id' => ['nullable', 'integer'],
|
|
'reponse_vrai_faux' => ['nullable', 'boolean'],
|
|
]);
|
|
|
|
$correcte = $question->estCorrecte($donnees['choix_id'] ?? null, $donnees['reponse_vrai_faux'] ?? null);
|
|
|
|
try {
|
|
ReponseQuiz::create([
|
|
'session_quiz_id' => $session->id,
|
|
'question_quiz_id' => $question->id,
|
|
'eleve_id' => $eleve->id,
|
|
'choix_question_quiz_id' => $donnees['choix_id'] ?? null,
|
|
'reponse_vrai_faux' => $donnees['reponse_vrai_faux'] ?? null,
|
|
'correcte' => $correcte,
|
|
'repondu_a' => now(),
|
|
]);
|
|
} catch (QueryException $e) {
|
|
// Double clic : la contrainte d'unicité (session, question, élève)
|
|
// a bloqué un second envoi arrivé en même temps que le premier.
|
|
abort(409, 'Déjà répondu.');
|
|
}
|
|
|
|
return response()->json(['correcte' => $correcte]);
|
|
}
|
|
}
|