pp-planer/app/Http/Controllers/SongPdfController.php
Thorsten Bus af0c72ebcc feat(ui): improve arrangement configurator, song preview, and downloads
Simplify ArrangementConfigurator: replace color pickers with compact
pills, add click-to-add from pool, use watcher-based auto-select for
new/cloned arrangements, remove group_colors from save payload.

Enhance SongsBlock preview: color-coded group headers with tinted
backgrounds, PDF download button inside preview modal, .pro download
link per matched song, show DB ccli_id with fallback to CTS ccli_id.

Fix Modal z-index for nested dialogs. Fix SlideUploader duplicate
upload on watch by adding deep option and upload guard. Expand API
log detail sections by default and increase JSON tree depth. Convert
song download button from emit to direct .pro download link.
2026-03-02 23:02:51 +01:00

78 lines
2.5 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Song;
use App\Models\SongArrangement;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;
class SongPdfController extends Controller
{
public function preview(Song $song, SongArrangement $arrangement): JsonResponse
{
abort_unless($arrangement->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();
}
}