song_id === $song->id, 404); $groupsInOrder = $this->buildGroupsInOrder($arrangement); return response()->json([ 'song' => [ 'id' => $song->id, 'title' => $song->title, 'copyright_text' => $song->copyright_text, 'ccli_id' => $song->ccli_id, ], 'arrangement' => [ 'id' => $arrangement->id, 'name' => $arrangement->name, ], 'groups' => $groupsInOrder, ]); } public function download(Song $song, SongArrangement $arrangement): Response|JsonResponse { abort_unless($arrangement->song_id === $song->id, 404); try { $groupsInOrder = $this->buildGroupsInOrder($arrangement); $pdf = Pdf::loadView('pdf.song', [ 'song' => $song, 'arrangement' => $arrangement, 'groupsInOrder' => $groupsInOrder, ])->setPaper('a4', 'portrait'); $filename = str($song->title)->slug().'-'.str($arrangement->name)->slug().'.pdf'; return $pdf->download($filename); } catch (\Throwable $e) { return response()->json([ 'message' => 'PDF-Erzeugung fehlgeschlagen: '.$e->getMessage(), ], 500); } } private function buildGroupsInOrder(SongArrangement $arrangement): array { $arrangement->load([ 'arrangementGroups' => fn ($query) => $query->orderBy('order'), 'arrangementGroups.group.slides' => fn ($query) => $query->orderBy('order'), ]); return $arrangement->arrangementGroups->map(function ($arrangementGroup) { $group = $arrangementGroup->group; return [ 'name' => $group->name, 'color' => $group->color ?? '#6b7280', 'slides' => $group->slides->map(fn ($slide) => [ 'text_content' => $slide->text_content, 'text_content_translated' => $slide->text_content_translated, ])->values()->all(), ]; })->values()->all(); } }