137 lines
3.7 KiB
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,
|
|
]);
|
|
}
|
|
}
|