112 lines
4 KiB
PHP
112 lines
4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Classe;
|
|
use App\Models\QuestionQuiz;
|
|
use App\Models\Quiz;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\View\View;
|
|
|
|
/**
|
|
* Chantier « vrai cockpit », étape 2 : Quiz flash. La banque de questions
|
|
* (ce contrôleur) est distincte de son lancement en direct
|
|
* (SessionQuizController) : un quiz se prépare à l'avance, se relance
|
|
* autant de fois qu'on veut.
|
|
*/
|
|
class QuizController extends Controller
|
|
{
|
|
public function index(Classe $classe): View
|
|
{
|
|
$this->verifierProprietaire($classe);
|
|
|
|
return view('quiz.index', ['classe' => $classe, 'quizzes' => $classe->quizzes()->withCount('questions')->get()]);
|
|
}
|
|
|
|
public function store(Request $request, Classe $classe): RedirectResponse
|
|
{
|
|
$this->verifierProprietaire($classe);
|
|
$donnees = $request->validate(['titre' => ['required', 'string', 'max:150']]);
|
|
|
|
$quiz = $classe->quizzes()->create($donnees);
|
|
|
|
return redirect()->route('mes-classes.quiz.show', [$classe, $quiz]);
|
|
}
|
|
|
|
public function show(Classe $classe, Quiz $quiz): View
|
|
{
|
|
$this->verifierProprietaire($classe);
|
|
$this->verifierAppartenance($classe, $quiz);
|
|
|
|
return view('quiz.show', ['classe' => $classe, 'quiz' => $quiz->load('questions.choix')]);
|
|
}
|
|
|
|
public function destroy(Classe $classe, Quiz $quiz): RedirectResponse
|
|
{
|
|
$this->verifierProprietaire($classe);
|
|
$this->verifierAppartenance($classe, $quiz);
|
|
$quiz->delete();
|
|
|
|
return redirect()->route('mes-classes.quiz.index', $classe);
|
|
}
|
|
|
|
/**
|
|
* Une question à la fois (même esprit que « ajouter un élève ») : plus
|
|
* simple à valider et à tester qu'un formulaire unique avec un nombre
|
|
* de lignes variable.
|
|
*/
|
|
public function storeQuestion(Request $request, Classe $classe, Quiz $quiz): RedirectResponse
|
|
{
|
|
$this->verifierProprietaire($classe);
|
|
$this->verifierAppartenance($classe, $quiz);
|
|
|
|
$donnees = $request->validate([
|
|
'enonce' => ['required', 'string', 'max:500'],
|
|
'type' => ['required', 'in:'.QuestionQuiz::QCM.','.QuestionQuiz::VRAI_FAUX],
|
|
'reponse_vrai_faux' => ['required_if:type,'.QuestionQuiz::VRAI_FAUX, 'boolean'],
|
|
'choix' => ['required_if:type,'.QuestionQuiz::QCM, 'array', 'min:2', 'max:5'],
|
|
'choix.*' => ['required_if:type,'.QuestionQuiz::QCM, 'string', 'max:200'],
|
|
'bonne_reponse' => ['required_if:type,'.QuestionQuiz::QCM, 'integer'],
|
|
]);
|
|
|
|
DB::transaction(function () use ($donnees, $quiz) {
|
|
$question = $quiz->questions()->create([
|
|
'enonce' => $donnees['enonce'],
|
|
'type' => $donnees['type'],
|
|
'ordre' => $quiz->questions()->count(),
|
|
'reponse_vrai_faux' => $donnees['type'] === QuestionQuiz::VRAI_FAUX ? $donnees['reponse_vrai_faux'] : null,
|
|
]);
|
|
|
|
if ($donnees['type'] === QuestionQuiz::QCM) {
|
|
foreach ($donnees['choix'] as $i => $texte) {
|
|
$question->choix()->create(['texte' => $texte, 'est_correct' => $i === (int) $donnees['bonne_reponse'], 'ordre' => $i]);
|
|
}
|
|
}
|
|
});
|
|
|
|
return redirect()->route('mes-classes.quiz.show', [$classe, $quiz]);
|
|
}
|
|
|
|
public function destroyQuestion(Classe $classe, Quiz $quiz, QuestionQuiz $question): RedirectResponse
|
|
{
|
|
$this->verifierProprietaire($classe);
|
|
$this->verifierAppartenance($classe, $quiz);
|
|
abort_if($question->quiz_id !== $quiz->id, 404);
|
|
$question->delete();
|
|
|
|
return redirect()->route('mes-classes.quiz.show', [$classe, $quiz]);
|
|
}
|
|
|
|
private function verifierProprietaire(Classe $classe): void
|
|
{
|
|
abort_if($classe->user_id !== Auth::guard('web')->id(), 403);
|
|
}
|
|
|
|
private function verifierAppartenance(Classe $classe, Quiz $quiz): void
|
|
{
|
|
abort_if($quiz->classe_id !== $classe->id, 404);
|
|
}
|
|
}
|