L'élève saisit le code de classe et son prénom, le prof accepte, l'élève voit une seule fois son identifiant et son code. Aucun e-mail. Le prof peut aussi régénérer les fiches de plusieurs élèves d'un coup. Procédure pour prouver la copie de la clé des sauvegardes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
115 lines
4 KiB
PHP
115 lines
4 KiB
PHP
<?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;
|
|
}
|
|
}
|