ajoute les devoirs maison (chantier vrai cockpit, étape 3) : rendu en texte libre, suivi des rendus, notation

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Adam Belkacemi 2026-10-13 12:44:00 +02:00
parent bd74eaf20f
commit 33531de44d
17 changed files with 582 additions and 2 deletions

View file

@ -0,0 +1,85 @@
<?php
namespace App\Http\Controllers;
use App\Models\Classe;
use App\Models\Devoir;
use App\Models\RenduDevoir;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
/**
* Devoirs maison (chantier « vrai cockpit », étape 3). Côté prof : créer,
* voir qui a rendu, noter. Côté élève : DevoirEleveController.
*/
class DevoirController extends Controller
{
public function index(Classe $classe): View
{
$this->verifierProprietaire($classe);
return view('devoirs.index', ['classe' => $classe, 'devoirs' => $classe->devoirs()->withCount('rendus')->get()]);
}
public function store(Request $request, Classe $classe): RedirectResponse
{
$this->verifierProprietaire($classe);
$donnees = $request->validate([
'titre' => ['required', 'string', 'max:150'],
'consigne' => ['required', 'string', 'max:5000'],
'echeance' => ['required', 'date', 'after:now'],
]);
$devoir = $classe->devoirs()->create($donnees);
return redirect()->route('mes-classes.devoirs.show', [$classe, $devoir]);
}
public function show(Classe $classe, Devoir $devoir): View
{
$this->verifierProprietaire($classe);
$this->verifierAppartenance($classe, $devoir);
$rendus = $devoir->rendus()->with('eleve')->get()->keyBy('eleve_id');
return view('devoirs.show', [
'classe' => $classe,
'devoir' => $devoir,
'eleves' => $classe->eleves,
'rendus' => $rendus,
]);
}
public function noter(Request $request, Classe $classe, Devoir $devoir, RenduDevoir $rendu): RedirectResponse
{
$this->verifierProprietaire($classe);
$this->verifierAppartenance($classe, $devoir);
abort_if($rendu->devoir_id !== $devoir->id, 404);
$donnees = $request->validate(['note' => ['required', 'integer', 'min:0', 'max:20']]);
$rendu->update($donnees);
return redirect()->route('mes-classes.devoirs.show', [$classe, $devoir]);
}
public function destroy(Classe $classe, Devoir $devoir): RedirectResponse
{
$this->verifierProprietaire($classe);
$this->verifierAppartenance($classe, $devoir);
$devoir->delete();
return redirect()->route('mes-classes.devoirs.index', $classe);
}
private function verifierProprietaire(Classe $classe): void
{
abort_if($classe->user_id !== Auth::guard('web')->id(), 403);
}
private function verifierAppartenance(Classe $classe, Devoir $devoir): void
{
abort_if($devoir->classe_id !== $classe->id, 404);
}
}

View file

@ -0,0 +1,51 @@
<?php
namespace App\Http\Controllers;
use App\Models\Devoir;
use App\Models\Eleve;
use App\Models\RenduDevoir;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
/**
* Côté élève des devoirs maison (chantier « vrai cockpit », étape 3) :
* rendu en texte libre, une seule fois par devoir, avant l'échéance.
*/
class DevoirEleveController extends Controller
{
public function show(Devoir $devoir): View
{
$eleve = $this->verifierAppartenance($devoir);
return view('devoirs.eleve', [
'devoir' => $devoir,
'rendu' => RenduDevoir::where('devoir_id', $devoir->id)->where('eleve_id', $eleve->id)->first(),
]);
}
public function rendre(Request $request, Devoir $devoir): RedirectResponse
{
$eleve = $this->verifierAppartenance($devoir);
abort_if($devoir->echeanceDepassee(), 409, 'L’échéance est dépassée.');
$donnees = $request->validate(['reponse' => ['required', 'string', 'max:10000']]);
RenduDevoir::updateOrCreate(
['devoir_id' => $devoir->id, 'eleve_id' => $eleve->id],
['reponse' => $donnees['reponse'], 'rendu_a' => now()]
);
return redirect()->route('devoirs.eleve.show', $devoir)->with('rendu_envoye', true);
}
private function verifierAppartenance(Devoir $devoir): Eleve
{
$eleve = Auth::guard('eleve')->user();
abort_if($devoir->classe_id !== $eleve->classe_id, 403);
return $eleve;
}
}