peuple la banque de quiz avec du vrai contenu, rangé par thème

Un quiz.gift par séquence (01 à 07, le 08 existait déjà), lu par un
nouveau service LecteurGift et synchronisé par quiz:synchroniser-banque
(même esprit que labs:synchroniser) vers un propriétaire technique
jamais archivé (BanqueOfficielle), pour ne pas reproduire la dette du
quiz partagé qui disparaît à la purge RGPD. /banque-quiz regroupe
maintenant par thème comme /bibliotheque.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Adam Belkacemi 2026-10-13 16:14:36 +02:00
parent 33531de44d
commit a41951d4e6
21 changed files with 628 additions and 32 deletions

View file

@ -0,0 +1,74 @@
<?php
namespace App\Console\Commands;
use App\Models\Quiz;
use App\Services\Quiz\BanqueOfficielle;
use App\Services\Quiz\LecteurGift;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Symfony\Component\Yaml\Yaml;
/**
* Peuple la banque de quiz officielle depuis les quiz.gift de
* paillasse-contenus/ (demande d'Adam, 2026-10-13) : même esprit que
* labs:synchroniser, jamais de suppression — les questions d'un quiz
* officiel sont remplacées à chaque synchronisation (lui seul les écrit,
* aucun prof ne peut l'éditer), jamais le quiz lui-même.
*/
class SynchroniserBanqueQuiz extends Command
{
protected $signature = 'quiz:synchroniser-banque';
protected $description = 'Crée ou met à jour la banque de quiz officielle depuis les quiz.gift de paillasse-contenus/';
public function handle(): void
{
$dossier = config('contenus.dossier');
$themes = config('contenus.themes');
$classe = BanqueOfficielle::classe();
foreach (File::directories($dossier) as $chemin) {
$identifiant = basename($chemin);
$cheminGift = "{$chemin}/quiz.gift";
$cheminLab = "{$chemin}/lab.yaml";
if (! File::exists($cheminGift) || ! File::exists($cheminLab)) {
continue;
}
$titre = Yaml::parseFile($cheminLab)['titre'];
$lecture = LecteurGift::lire($cheminGift);
$quiz = Quiz::updateOrCreate(
['classe_id' => $classe->id, 'titre' => $titre],
['theme' => $themes[$identifiant] ?? null, 'partage' => true],
);
$quiz->questions()->delete();
foreach ($lecture['questions'] as $ordre => $donnees) {
$question = $quiz->questions()->create([
'enonce' => $donnees['enonce'],
'type' => $donnees['type'],
'ordre' => $ordre,
'reponse_vrai_faux' => $donnees['reponse_vrai_faux'],
]);
foreach ($donnees['choix'] as $ordreChoix => $choix) {
$question->choix()->create([
'texte' => $choix['texte'],
'est_correct' => $choix['est_correct'],
'ordre' => $ordreChoix,
]);
}
}
$this->line(($quiz->wasRecentlyCreated ? 'créé' : 'à jour')." : {$identifiant} ({$titre}), ".count($lecture['questions']).' question(s)');
foreach ($lecture['avertissements'] as $avertissement) {
$this->warn("{$identifiant} : {$avertissement}");
}
}
}
}