96 lines
2.8 KiB
PHP
96 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
|
|
/**
|
|
* Lancement en direct d'un Quiz (chantier « vrai cockpit », étape 2).
|
|
* Indépendant d'une séance de lab : les élèves de la classe la voient
|
|
* apparaître sur leur tableau de bord dès qu'elle passe en_cours.
|
|
*/
|
|
class SessionQuiz extends Model
|
|
{
|
|
public const EN_ATTENTE = 'en_attente';
|
|
|
|
public const EN_COURS = 'en_cours';
|
|
|
|
public const TERMINEE = 'terminee';
|
|
|
|
protected $table = 'sessions_quiz';
|
|
|
|
protected $fillable = ['quiz_id', 'statut', 'question_quiz_courante_id', 'demarree_a', 'terminee_a'];
|
|
|
|
protected $casts = [
|
|
'demarree_a' => 'datetime',
|
|
'terminee_a' => 'datetime',
|
|
];
|
|
|
|
/** @return BelongsTo<Quiz, $this> */
|
|
public function quiz(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Quiz::class);
|
|
}
|
|
|
|
/** @return BelongsTo<QuestionQuiz, $this> */
|
|
public function questionCourante(): BelongsTo
|
|
{
|
|
return $this->belongsTo(QuestionQuiz::class, 'question_quiz_courante_id');
|
|
}
|
|
|
|
/** @return HasMany<ReponseQuiz, $this> */
|
|
public function reponses(): HasMany
|
|
{
|
|
return $this->hasMany(ReponseQuiz::class);
|
|
}
|
|
|
|
/**
|
|
* Passe à la question suivante du quiz (dans l'ordre), ou termine la
|
|
* session s'il n'y en a plus. Idempotent : rejouable sans effet si déjà
|
|
* terminée.
|
|
*/
|
|
public function passerALaQuestionSuivante(): void
|
|
{
|
|
if ($this->statut === self::TERMINEE) {
|
|
return;
|
|
}
|
|
|
|
$questions = $this->quiz->questions;
|
|
$indiceActuel = $this->question_quiz_courante_id
|
|
? $questions->search(fn ($q) => $q->id === $this->question_quiz_courante_id)
|
|
: -1;
|
|
$suivante = $questions->get($indiceActuel + 1);
|
|
|
|
if ($suivante) {
|
|
$this->forceFill(['statut' => self::EN_COURS, 'question_quiz_courante_id' => $suivante->id])->save();
|
|
} else {
|
|
$this->terminer();
|
|
}
|
|
}
|
|
|
|
public function terminer(): void
|
|
{
|
|
if ($this->statut !== self::TERMINEE) {
|
|
$this->forceFill(['statut' => self::TERMINEE, 'terminee_a' => now()])->save();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Décompte des réponses à la question en cours, pour le panneau du
|
|
* prof : combien d'élèves ont déjà répondu, combien ont juste.
|
|
*
|
|
* @return array{repondu: int, correctes: int}
|
|
*/
|
|
public function decompteQuestionCourante(): array
|
|
{
|
|
if (! $this->question_quiz_courante_id) {
|
|
return ['repondu' => 0, 'correctes' => 0];
|
|
}
|
|
|
|
$reponses = $this->reponses->where('question_quiz_id', $this->question_quiz_courante_id);
|
|
|
|
return ['repondu' => $reponses->count(), 'correctes' => $reponses->where('correcte', true)->count()];
|
|
}
|
|
}
|