Paillasse/portail/app/Http/Controllers/RejoindreClasseController.php

116 lines
4 KiB
PHP
Raw Normal View History

<?php
namespace App\Http\Controllers;
use App\Models\Classe;
use App\Models\DemandeInscription;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Illuminate\View\View;
/**
* Un élève rejoint une classe avec son code (façon n°1 du CLAUDE.md) :
* il donne son prénom, le prof accepte, l'élève voit une fois son
* identifiant et son code secret, et il est connecté. Aucun e-mail.
*/
class RejoindreClasseController extends Controller
{
private const CLE_SESSION = 'demande_inscription_jeton';
public function formulaire(Request $request): View
{
return view('rejoindre.formulaire', ['code' => Str::upper((string) $request->query('code', ''))]);
}
public function demander(Request $request): RedirectResponse
{
$donnees = $request->validate([
'code' => ['required', 'string', 'size:6'],
'prenom' => ['required', 'string', 'max:100'],
'nom' => ['nullable', 'string', 'max:100'],
]);
$classe = Classe::where('code_classe', Str::upper($donnees['code']))->first();
if ($classe === null || $classe->estArchivee()) {
return back()->withInput()->withErrors(['code' => 'Ce code ne correspond à aucune classe ouverte. Vérifie-le auprès de ton prof.']);
}
$jeton = Str::random(40);
DemandeInscription::create([
'classe_id' => $classe->id,
'prenom' => trim($donnees['prenom']),
'nom' => isset($donnees['nom']) ? trim($donnees['nom']) : null,
'jeton_empreinte' => DemandeInscription::empreinte($jeton),
'statut' => DemandeInscription::EN_ATTENTE,
]);
$request->session()->put(self::CLE_SESSION, $jeton);
return redirect()->route('rejoindre.attente');
}
public function attente(Request $request): View|RedirectResponse
{
$demande = $this->demandeDeCeNavigateur($request);
if ($demande === null) {
return redirect()->route('rejoindre');
}
if ($demande->statut === DemandeInscription::ACCEPTEE) {
return redirect()->route('rejoindre.bienvenue');
}
if ($demande->statut === DemandeInscription::REFUSEE) {
$demande->delete();
$request->session()->forget(self::CLE_SESSION);
return view('rejoindre.refusee');
}
return view('rejoindre.attente', ['demande' => $demande->load('classe')]);
}
public function etat(Request $request): JsonResponse
{
return response()->json(['statut' => $this->demandeDeCeNavigateur($request)?->statut]);
}
/**
* Le code secret n'est montré qu'une fois : la demande (et le code en
* clair qu'elle porte) est supprimée dès l'affichage, l'élève est connecté.
*/
public function bienvenue(Request $request): View|RedirectResponse
{
$demande = $this->demandeDeCeNavigateur($request);
if ($demande === null || $demande->statut !== DemandeInscription::ACCEPTEE || $demande->eleve === null) {
return redirect()->route(Auth::guard('eleve')->check() ? 'eleve' : 'rejoindre');
}
$eleve = $demande->eleve;
$codeSecret = $demande->code_secret_chiffre;
$demande->delete();
$request->session()->forget(self::CLE_SESSION);
Auth::guard('eleve')->login($eleve);
$request->session()->regenerate();
$eleve->forceFill(['jeton_qr' => null, 'derniere_connexion_a' => now()])->save();
$request->session()->put('jeton_session_eleve', $eleve->demarreNouvelleSession());
return view('rejoindre.bienvenue', ['eleve' => $eleve, 'codeSecret' => $codeSecret]);
}
private function demandeDeCeNavigateur(Request $request): ?DemandeInscription
{
$jeton = $request->session()->get(self::CLE_SESSION);
return is_string($jeton)
? DemandeInscription::where('jeton_empreinte', DemandeInscription::empreinte($jeton))->first()
: null;
}
}