validate([ 'name' => ['required', 'string', 'max:255'], ]); DB::transaction(function () use ($song, $data): void { $arrangement = $song->arrangements()->create([ 'name' => $data['name'], 'is_default' => false, ]); $groups = $song->groups()->orderBy('order')->get(); $rows = $groups->map(fn ($group, $index) => [ 'song_arrangement_id' => $arrangement->id, 'song_group_id' => $group->id, 'order' => $index + 1, 'created_at' => now(), 'updated_at' => now(), ])->all(); if ($rows !== []) { $arrangement->arrangementGroups()->insert($rows); } }); return back()->with('success', 'Arrangement wurde hinzugefügt.'); } public function clone(Request $request, SongArrangement $arrangement): RedirectResponse { $data = $request->validate([ 'name' => ['required', 'string', 'max:255'], ]); DB::transaction(function () use ($arrangement, $data): void { $arrangement->loadMissing('arrangementGroups'); $clone = $arrangement->song->arrangements()->create([ 'name' => $data['name'], 'is_default' => false, ]); $this->cloneGroups($arrangement, $clone); }); return back()->with('success', 'Arrangement wurde geklont.'); } public function update(Request $request, SongArrangement $arrangement): RedirectResponse { $data = $request->validate([ 'groups' => ['array'], 'groups.*.song_group_id' => ['required', 'integer', 'exists:song_groups,id'], 'groups.*.order' => ['required', 'integer', 'min:1'], 'group_colors' => ['sometimes', 'array'], 'group_colors.*' => ['required', 'string', 'regex:/^#[0-9A-Fa-f]{6}$/'], ]); $groupIds = collect($data['groups'] ?? [])->pluck('song_group_id')->values(); $uniqueGroupIds = $groupIds->unique()->values(); $validGroupIds = $arrangement->song->groups() ->whereIn('id', $uniqueGroupIds) ->pluck('id'); if ($uniqueGroupIds->count() !== $validGroupIds->count()) { throw ValidationException::withMessages([ 'groups' => 'Du kannst nur Gruppen aus diesem Song verwenden.', ]); } DB::transaction(function () use ($arrangement, $groupIds, $data): void { $arrangement->arrangementGroups()->delete(); $rows = $groupIds ->values() ->map(fn (int $songGroupId, int $index) => [ 'song_arrangement_id' => $arrangement->id, 'song_group_id' => $songGroupId, 'order' => $index + 1, 'created_at' => now(), 'updated_at' => now(), ]) ->all(); if ($rows !== []) { $arrangement->arrangementGroups()->insert($rows); } if (!empty($data['group_colors'])) { foreach ($data['group_colors'] as $groupId => $color) { $arrangement->song->groups() ->whereKey((int) $groupId) ->update(['color' => $color]); } } }); return back()->with('success', 'Arrangement wurde gespeichert.'); } public function destroy(SongArrangement $arrangement): RedirectResponse { $song = $arrangement->song; if ($song->arrangements()->count() <= 1) { return back()->with('error', 'Das letzte Arrangement kann nicht gelöscht werden.'); } DB::transaction(function () use ($arrangement, $song): void { $deletedWasDefault = $arrangement->is_default; $arrangement->delete(); if ($deletedWasDefault) { $song->arrangements() ->orderBy('id') ->limit(1) ->update(['is_default' => true]); } }); return back()->with('success', 'Arrangement wurde gelöscht.'); } private function cloneGroups(?SongArrangement $source, SongArrangement $target): void { if ($source === null) { return; } $groups = $source->arrangementGroups ->sortBy('order') ->values(); $rows = $groups ->map(fn ($arrangementGroup) => [ 'song_arrangement_id' => $target->id, 'song_group_id' => $arrangementGroup->song_group_id, 'order' => $arrangementGroup->order, 'created_at' => now(), 'updated_at' => now(), ]) ->all(); if ($rows !== []) { $target->arrangementGroups()->insert($rows); } } }