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([ 'arrangementLabels' => fn ($query) => $query->orderBy('order'), 'arrangementLabels.label.songSlides' => fn ($query) => $query->orderBy('order'), ]); return $arrangement->arrangementLabels->map(function ($arrangementLabel) { $label = $arrangementLabel->label; if ($label === null) { return null; } return [ 'name' => $label->name, 'color' => $label->color ?? '#6b7280', 'slides' => $label->songSlides->map(fn ($slide) => [ 'text_content' => $slide->text_content, 'text_content_translated' => $slide->text_content_translated, ])->values()->all(), ]; })->filter()->values()->all(); } }