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

247 lines
7.9 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Event;
use App\Models\Location;
use Carbon\Carbon;
use Illuminate\Http\Request;
use OpenApi\Attributes as OA;
#[OA\Info(
title: "Veranstaltungen API",
version: "1.0.0",
description: "API für Event Management mit Location und Occurrence Management",
)]
class EventController extends Controller
{
#[OA\Get(
path: "/api/events",
summary: "Alle Events auflisten",
description: "Listet alle veröffentlichten Events mit optionalen Filtern auf",
tags: ["Events"],
parameters: [
new OA\Parameter(
name: "from",
in: "query",
description: "Startdatum (Format: YYYY-MM-DD)",
schema: new OA\Schema(type: "string", format: "date")
),
new OA\Parameter(
name: "to",
in: "query",
description: "Enddatum (Format: YYYY-MM-DD)",
schema: new OA\Schema(type: "string", format: "date")
),
new OA\Parameter(
name: "category",
in: "query",
description: "Filter nach Kategorie",
schema: new OA\Schema(type: "string")
),
new OA\Parameter(
name: "location",
in: "query",
description: "Filter nach Ort oder Stadt",
schema: new OA\Schema(type: "string")
),
new OA\Parameter(
name: "limit",
in: "query",
description: "Anzahl der Events pro Seite (1-100, Standard: 20)",
schema: new OA\Schema(type: "integer", default: 20)
),
],
responses: [
new OA\Response(
response: 200,
description: "Liste der Events",
content: new OA\JsonContent(type: "object")
),
]
)]
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'] ?? null)
? Carbon::parse($validated['from'])->startOfDay()
: now()->startOfDay();
$to = ($validated['to'] ?? null)
? Carbon::parse($validated['to'])->endOfDay()
: now()->addMonths(3)->endOfDay();
$limit = $validated['limit'] ?? 20;
$query = Event::published()
->with(['source', 'location', '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(),
]
]);
}
#[OA\Get(
path: "/api/events/{event}",
summary: "Einzelnes Event anzeigen",
description: "Zeigt ein einzelnes veröffentlichtes Event mit allen seinen Terminen",
tags: ["Events"],
parameters: [
new OA\Parameter(
name: "event",
in: "path",
required: true,
description: "Event ID",
schema: new OA\Schema(type: "integer")
),
],
responses: [
new OA\Response(
response: 200,
description: "Event Details",
content: new OA\JsonContent(type: "object")
),
new OA\Response(
response: 404,
description: "Event nicht gefunden"
),
]
)]
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,
]);
}
#[OA\Get(
path: "/api/events/categories/list",
summary: "Verfügbare Kategorien",
description: "Listet alle verfügbaren Event-Kategorien auf",
tags: ["Utilities"],
responses: [
new OA\Response(
response: 200,
description: "Liste der Kategorien",
content: new OA\JsonContent(
type: "object",
properties: [
"success" => new OA\Property(type: "boolean"),
"data" => new OA\Property(type: "array", items: new OA\Items(type: "string"))
]
)
),
]
)]
public function categories()
{
$categories = Event::published()
->distinct()
->pluck('category')
->filter()
->sort()
->values();
return response()->json([
'success' => true,
'data' => $categories,
]);
}
#[OA\Get(
path: "/api/events/locations/list",
summary: "Verfügbare Veranstaltungsorte",
description: "Listet alle verfügbaren Veranstaltungsorte mit vollständigen Adressinformationen auf",
tags: ["Utilities"],
responses: [
new OA\Response(
response: 200,
description: "Liste der Veranstaltungsorte",
content: new OA\JsonContent(type: "object")
),
]
)]
public function locations()
{
$locations = Location::orderBy('city')
->orderBy('name')
->get()
->map(function ($location) {
return [
'id' => $location->id,
'name' => $location->name,
'address' => [
'street' => $location->street,
'house_number' => $location->house_number,
'postal_code' => $location->postal_code,
'city' => $location->city,
'state' => $location->state,
'country' => $location->country,
'full_address' => $location->full_address,
'short_address' => $location->short_address,
],
'contact' => [
'phone' => $location->phone,
'email' => $location->email,
'website' => $location->website,
],
'event_count' => $location->events()->published()->count(),
];
});
return response()->json([
'success' => true,
'data' => $locations,
]);
}
}