Veranstaltungen-APP/app/Jobs/ImportEventsJob.php

120 lines
4.5 KiB
PHP

<?php
namespace App\Jobs;
use App\Models\Event;
use App\Models\EventOccurrence;
use App\Models\Source;
use App\Services\EventImportService;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class ImportEventsJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(public Source $source)
{
}
public function handle(EventImportService $importService): void
{
DB::transaction(function () use ($importService) {
$events = $this->fetchExternalEvents($importService);
foreach ($events as $eventData) {
$this->createOrUpdateEvent($eventData);
}
$this->source->update(['last_import_at' => now()]);
});
}
protected function fetchExternalEvents(EventImportService $importService): array
{
if (str_contains($this->source->url, 'stadt-dresden')) {
try {
return $importService->fetchFromDresdenCityAPI(50);
} catch (\Throwable $exception) {
Log::warning('Dresden import failed, falling back to sample data: ' . $exception->getMessage());
}
}
return [
[
'external_id' => "source-{$this->source->id}-sample-1",
'title' => 'Stadtführung durch die historische Altstadt',
'description' => 'Geführte Tour durch die schönsten Sehenswürdigkeiten Dresdens.',
'location' => 'Dresdner Altstadt',
'category' => 'Stadtführung',
'image_url' => 'https://example.com/images/stadtfuehrung.jpg',
'website_url' => $this->source->url,
'contact_email' => 'info@stadt-dresden.de',
'contact_phone' => '+49 351 1234567',
'status' => 'published',
'occurrences' => [
[
'start_datetime' => now()->addDays(3)->setTime(10, 0)->toDateTimeString(),
'end_datetime' => now()->addDays(3)->setTime(12, 0)->toDateTimeString(),
'is_all_day' => false,
'location_details' => 'Treffpunkt: Theaterplatz',
'capacity' => 25,
'available_tickets' => 12,
'price' => 19.90,
'status' => 'scheduled',
],
],
],
];
}
protected function createOrUpdateEvent(array $data): Event
{
$event = Event::updateOrCreate(
[
'source_id' => $this->source->id,
'external_id' => $data['external_id'],
],
[
'title' => $data['title'],
'description' => $data['description'] ?? null,
'location' => $data['location'] ?? null,
'category' => $data['category'] ?? null,
'image_url' => $data['image_url'] ?? null,
'website_url' => $data['website_url'] ?? null,
'contact_email' => $data['contact_email'] ?? null,
'contact_phone' => $data['contact_phone'] ?? null,
'status' => $data['status'] ?? 'published',
'slug' => $data['slug'] ?? null,
]
);
if (!empty($data['occurrences']) && is_array($data['occurrences'])) {
foreach ($data['occurrences'] as $occurrenceData) {
EventOccurrence::updateOrCreate(
[
'event_id' => $event->id,
'start_datetime' => $occurrenceData['start_datetime'],
],
[
'end_datetime' => $occurrenceData['end_datetime'] ?? null,
'is_all_day' => $occurrenceData['is_all_day'] ?? false,
'location_details' => $occurrenceData['location_details'] ?? null,
'capacity' => $occurrenceData['capacity'] ?? null,
'available_tickets' => $occurrenceData['available_tickets'] ?? null,
'price' => $occurrenceData['price'] ?? null,
'status' => $occurrenceData['status'] ?? 'scheduled',
]
);
}
}
return $event;
}
}