Veranstaltungen-APP/app/Http/Controllers/EventController.php

137 lines
3.7 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Event;
use Carbon\Carbon;
use Illuminate\Http\Request;
class EventController extends Controller
{
/**
* GET /events
*
* Filter-Parameter:
* - ?from=2026-04-15 (ab Datum, Standard: heute)
* - ?to=2026-05-31 (bis Datum, Standard: 3 Monate ab jetzt)
* - ?category=Kultur
* - ?location=Dresden
* - ?limit=20 (Standard: 20)
*/
public function index(Request $request)
{
$validated = $request->validate([
'from' => 'nullable|date',
'to' => 'nullable|date',
'category' => 'nullable|string',
'location' => 'nullable|string',
'limit' => 'nullable|integer|min:1|max:100',
]);
$from = $validated['from']
? Carbon::parse($validated['from'])->startOfDay()
: now()->startOfDay();
$to = $validated['to']
? Carbon::parse($validated['to'])->endOfDay()
: now()->addMonths(3)->endOfDay();
$limit = $validated['limit'] ?? 20;
$query = Event::published()
->with(['source', 'occurrences' => function ($q) use ($from, $to) {
$q->whereBetween('start_datetime', [$from, $to])
->where('status', 'scheduled')
->orderBy('start_datetime');
}])
->whereHas('occurrences', function ($q) use ($from, $to) {
$q->whereBetween('start_datetime', [$from, $to])
->where('status', 'scheduled');
})
->orderBy('title');
// Filter nach Kategorie
if (!empty($validated['category'])) {
$query->byCategory($validated['category']);
}
// Filter nach Ort
if (!empty($validated['location'])) {
$query->byLocation($validated['location']);
}
$events = $query->paginate($limit);
return response()->json([
'success' => true,
'data' => $events->items(),
'pagination' => [
'total' => $events->total(),
'per_page' => $events->perPage(),
'current_page' => $events->currentPage(),
'last_page' => $events->lastPage(),
]
]);
}
/**
* GET /events/{id}
*
* Zeigt ein einzelnes Event mit allen seinen Terminen.
*/
public function show(Event $event)
{
// Nur veröffentlichte Events anzeigen
if ($event->status !== 'published') {
return response()->json([
'success' => false,
'message' => 'Event nicht gefunden.',
], 404);
}
$event->load(['source', 'occurrences' => function ($query) {
$query->where('status', 'scheduled')
->orderBy('start_datetime');
}]);
return response()->json([
'success' => true,
'data' => $event,
]);
}
/**
* Hilfsmethode: Verfügbare Kategorien
*/
public function categories()
{
$categories = Event::published()
->distinct()
->pluck('category')
->filter()
->sort()
->values();
return response()->json([
'success' => true,
'data' => $categories,
]);
}
/**
* Hilfsmethode: Verfügbare Orte
*/
public function locations()
{
$locations = Event::published()
->distinct()
->orderBy('location')
->pluck('location');
return response()->json([
'success' => true,
'data' => $locations,
]);
}
}