festivalSections()->ordered()->get(); // For sub-events, also include cross_event sections from the parent festival if ($event->isSubEvent()) { $parentCrossEventSections = $event->parent ->festivalSections() ->where('type', 'cross_event') ->ordered() ->get(); $sections = $parentCrossEventSections->merge($sections)->sortBy('sort_order')->values(); } return FestivalSectionResource::collection($sections); } public function store(StoreFestivalSectionRequest $request, Event $event): JsonResponse { Gate::authorize('create', [FestivalSection::class, $event]); $data = $request->validated(); $redirectedToParent = false; if (($data['type'] ?? 'standard') === 'cross_event') { if ($event->isFlatEvent()) { return $this->error( 'Overkoepelende secties kunnen alleen worden aangemaakt bij festivals met programmaonderdelen.', 422, ); } if ($event->isSubEvent()) { $event = $event->parent; Gate::authorize('create', [FestivalSection::class, $event]); $redirectedToParent = true; } } $section = $event->festivalSections()->create($data); $response = $this->created(new FestivalSectionResource($section)); if ($redirectedToParent) { $original = $response->getData(true); $original['meta'] = [ 'redirected_to_parent' => true, 'parent_event_name' => $event->name, ]; return response()->json($original, 201); } return $response; } public function update(UpdateFestivalSectionRequest $request, Event $event, FestivalSection $section): JsonResponse { Gate::authorize('update', [$section, $event]); $section->update($request->validated()); return $this->success(new FestivalSectionResource($section->fresh())); } public function destroy(Event $event, FestivalSection $section): JsonResponse { Gate::authorize('delete', [$section, $event]); $section->delete(); return response()->json(null, 204); } public function registrationSettings(Event $event): JsonResponse { Gate::authorize('viewAny', [FestivalSection::class, $event]); $sections = $this->getFestivalSections($event); $grouped = $sections->groupBy('name')->map(function ($group) { $first = $group->first(); return [ 'name' => $first->name, 'category' => $first->category, 'icon' => $first->icon, 'show_in_registration' => $group->contains('show_in_registration', true), 'registration_description' => $group->whereNotNull('registration_description')->first()?->registration_description, 'section_count' => $group->count(), 'section_ids' => $group->pluck('id')->values()->toArray(), ]; })->values(); return response()->json(['data' => $grouped]); } public function updateRegistrationSettings(UpdateRegistrationSettingsRequest $request, Event $event): JsonResponse { Gate::authorize('create', [FestivalSection::class, $event]); $validated = $request->validated(); $sections = $this->getFestivalSections($event); $matching = $sections->where('name', $validated['name']); if ($matching->isEmpty()) { return $this->error('Sectie niet gevonden.', 404); } FestivalSection::whereIn('id', $matching->pluck('id')) ->update([ 'show_in_registration' => $validated['show_in_registration'], 'registration_description' => $validated['registration_description'], ]); activity('section_management') ->performedOn($event) ->causedBy(auth()->user()) ->withProperties([ 'section_name' => $validated['name'], 'show_in_registration' => $validated['show_in_registration'], 'sections_updated' => $matching->count(), ]) ->log('section.registration_settings_updated'); // Return updated settings return $this->registrationSettings($event); } /** * Get all sections across the festival context (parent + children). */ private function getFestivalSections(Event $event): \Illuminate\Support\Collection { $eventIds = collect([$event->id]); if ($event->isSubEvent()) { $parentId = $event->parent_event_id; $eventIds = Event::where('parent_event_id', $parentId) ->orWhere('id', $parentId) ->pluck('id'); } elseif ($event->hasChildren()) { $childIds = $event->children()->pluck('id'); $eventIds = $childIds->push($event->id); } return FestivalSection::whereIn('event_id', $eventIds)->ordered()->get(); } public function reorder(ReorderFestivalSectionsRequest $request, Event $event): JsonResponse { Gate::authorize('reorder', [FestivalSection::class, $event]); foreach ($request->validated('sections') as $index => $id) { $event->festivalSections() ->where('id', $id) ->update(['sort_order' => $index]); } $sections = $event->festivalSections()->ordered()->get(); return $this->success(FestivalSectionResource::collection($sections)); } }