tickets()->latest()->get()->map(function (Ticket $ticket) { $issue = $this->gitea->getIssue($ticket->gitea_number); $ticket->setAttribute('state', $issue['state'] ?? null); $ticket->setAttribute('milestone', $issue['milestone']['title'] ?? null); return $ticket; }); return view('tickets.index', compact('tickets')); } // Formulaire de création public function create() { return view('tickets.create'); } // Création d'un ticket -> issue Gitea + enregistrement local public function store(Request $request) { $data = $request->validate([ 'type' => ['required', Rule::in(['Modification', 'Ajout', 'Correction'])], 'titre' => ['required', 'string', 'min:5', 'max:120'], 'description' => ['required', 'string', 'min:10', 'max:5000'], ]); /** @var User $user */ $user = Auth::user(); $auteur = $user->name ?? 'Utilisateur'; $title = "[{$data['type']}] {$data['titre']}"; $body = "**Type de demande :** {$data['type']}\n" ."**Proposé par :** {$auteur} (via le site CESIZen)\n\n" ."### Description\n" .$data['description']."\n\n" ."---\n" .'_Ticket créé automatiquement depuis CESIZen._'; $issue = $this->gitea->createIssue($title, $body); if (! $issue || ! isset($issue['number'])) { return back()->withInput()->withErrors([ 'gitea' => "L'envoi de votre demande a échoué. Merci de réessayer plus tard.", ]); } // On mémorise le lien utilisateur <-> issue pour le suivi. $user->tickets()->create([ 'gitea_number' => (int) $issue['number'], 'title' => $data['titre'], 'type' => $data['type'], ]); return redirect()->route('tickets.show', $issue['number']) ->with('success', 'Votre demande a bien été transmise à l\'équipe.'); } /** * Détail d'un ticket : état, jalon, labels et fil de discussion. */ public function show(int $number) { $ticket = $this->findOwnedTicket($number); $issue = $this->gitea->getIssue($number); $comments = $this->gitea->getComments($number); return view('tickets.show', compact('ticket', 'issue', 'comments')); } /** * Réponse de l'utilisateur : ajoute un commentaire sur l'issue Gitea. */ public function reply(Request $request, int $number) { $this->findOwnedTicket($number); $data = $request->validate([ 'message' => ['required', 'string', 'min:2', 'max:5000'], ]); /** @var User $user */ $user = Auth::user(); $auteur = $user->name ?? 'Utilisateur'; $body = "**{$auteur}** (via CESIZen) :\n\n".$data['message']; if (! $this->gitea->addComment($number, $body)) { return back()->withErrors(['gitea' => "L'envoi de votre réponse a échoué."]); } return redirect()->route('tickets.show', $number) ->with('success', 'Votre réponse a été ajoutée au ticket.'); } /** * Récupère le ticket s'il appartient bien à l'utilisateur connecté, * sinon renvoie une 404 (empêche de consulter les tickets d'autrui). */ private function findOwnedTicket(int $number): Ticket { /** @var User $user */ $user = Auth::user(); return $user->tickets()->where('gitea_number', $number)->firstOrFail(); } }