From d7cb6b8636fbfa26b61bcb29807e82fabf72c215 Mon Sep 17 00:00:00 2001 From: stevan Date: Mon, 29 Sep 2025 16:17:09 +0200 Subject: [PATCH] Sync RSS with update status --- app/Console/Commands/Importers/Bremen.php | 15 +- app/Console/Commands/api/GermanTraits.php | 283 +++++++++++------- app/RSSItems/BadenRSSItem.php | 33 ++ app/RSSItems/BayernRSSItem.php | 33 ++ app/RSSItems/BerlinRSSItem.php | 33 ++ app/RSSItems/BonnRSSItem.php | 33 ++ app/RSSItems/BremenRSSItem.php | 33 ++ app/RSSItems/DresdenRSSItem.php | 33 ++ app/RSSItems/HamburgRSSItem.php | 33 ++ app/RSSItems/LeipzigRSSItem.php | 33 ++ app/RSSItems/MuensterlandRSSItem.php | 33 ++ app/RSSItems/NiedersachsenRSSItem.php | 33 ++ app/RSSItems/NordhessenRSSItem.php | 33 ++ app/RSSItems/ThueringenRSSItem.php | 33 ++ ..._160415_add_source_ref_to_events_table.php | 30 ++ 15 files changed, 615 insertions(+), 109 deletions(-) create mode 100644 database/migrations/2025_09_26_160415_add_source_ref_to_events_table.php diff --git a/app/Console/Commands/Importers/Bremen.php b/app/Console/Commands/Importers/Bremen.php index 2c03f56bd..302b503f9 100644 --- a/app/Console/Commands/Importers/Bremen.php +++ b/app/Console/Commands/Importers/Bremen.php @@ -43,16 +43,21 @@ public function handle(): void Log::info('Loading Bremen API Items in Database'); $techicalUser = ImporterHelper::getTechnicalUser('bremen-technical'); - $items = BremenRSSItem::whereNull('imported_at')->get(); foreach ($items as $item) { - $item->createEvent($techicalUser); - $item->imported_at = Carbon::now(); - $item->save(); + try { + $item->createEvent($techicalUser); + $item->imported_at = Carbon::now(); + $item->save(); + + $this->info(sprintf('UID=%s imported_at=%s', $item->uid, $item->imported_at)); + } catch (\Throwable $e) { + Log::error('[import:bremen] item failed', ['uid' => $item->uid, 'error' => $e]); + $this->error('Failed UID='.$item->uid.' -> '.$e->getMessage()); + } } Log::info('Activities created from RSS Feed: '.count($items)); - } } diff --git a/app/Console/Commands/api/GermanTraits.php b/app/Console/Commands/api/GermanTraits.php index 696fc5e27..573001209 100644 --- a/app/Console/Commands/api/GermanTraits.php +++ b/app/Console/Commands/api/GermanTraits.php @@ -23,136 +23,211 @@ private function createRSSItem($json, $city): void { $new = 0; $updated = 0; + foreach ($json as $index => $item) { try { Log::info("Processing item {$index} from {$city}"); - // Validate required data - if (!isset($item['user'])) { - Log::warning("Item {$index} in {$city} has no user data - skipping"); + if (empty($item['uid']) || !isset($item['user'])) { + Log::warning("Item {$index} in {$city} missing uid or user - skipping"); continue; } - $className = '\App\RSSItems\\' . $city . 'RSSItem'; - $RSSitem = new $className; - - $RSSitem->uid = $item['uid'] ?? null; - $RSSitem->title = $item['title'] ?? ''; - $RSSitem->description = $item['description'] ?? ''; - $RSSitem->organizer = $item['organizer'] ?? ''; - $RSSitem->photo = $item['photo'] ?? null; - $RSSitem->eventEndDate = $item['eventEndDate'] ?? null; - $RSSitem->eventStartDate = $item['eventStartDate'] ?? null; - $RSSitem->latitude = $item['latitude'] ?? null; - $RSSitem->longitude = $item['longitude'] ?? null; - $RSSitem->location = $item['location'] ?? ''; - - // Safely get nested user data - $RSSitem->user_company = $item['user']['company'] ?? ''; - $RSSitem->user_email = $item['user']['email'] ?? ''; - $RSSitem->user_publicEmail = $item['user']['publicEmail'] ?? ''; - $RSSitem->user_type = $item['user']['type']['identifier'] ?? - ($item['user']['type'] ?? 'invite-in-person'); - $RSSitem->user_website = $item['user']['www'] ?? ''; - - // Safely get type data - $RSSitem->activity_type = $item['type']['identifier'] ?? 'invite-in-person'; - - // Safely handle arrays - $RSSitem->tags = trim(implode(';', Arr::pluck($item['tags'] ?? [], 'title'))); - $RSSitem->themes = trim(implode(',', Arr::pluck($item['themes'] ?? [], 'identifier'))); - $RSSitem->audience = trim(implode(',', Arr::pluck($item['audience'] ?? [], 'identifier'))); + $className = '\\App\\RSSItems\\' . $city . 'RSSItem'; + if (!class_exists($className)) { + Log::error("RSSItem class not found for city={$city}"); + continue; + } + + $lat = isset($item['latitude']) && is_numeric($item['latitude']) ? (float)$item['latitude'] : null; + $lng = isset($item['longitude']) && is_numeric($item['longitude']) ? (float)$item['longitude'] : null; + + $payload = [ + 'uid' => (int)($item['uid']), + 'title' => (string)($item['title'] ?? ''), + 'description' => (string)($item['description'] ?? ''), + 'organizer' => (string)($item['organizer'] ?? ''), + 'photo' => $item['photo'] ?? null, + 'eventEndDate' => $item['eventEndDate'] ?? null, + 'eventStartDate' => $item['eventStartDate'] ?? null, + 'latitude' => $lat, + 'longitude' => $lng, + 'location' => (string)($item['location'] ?? ''), + + 'user_company' => (string)($item['user']['company'] ?? ''), + 'user_email' => (string)($item['user']['email'] ?? ''), + 'user_publicEmail' => (string)($item['user']['publicEmail'] ?? ''), + 'user_type' => (string)($item['user']['type']['identifier'] ?? ($item['user']['type'] ?? 'invite-in-person')), + 'user_website' => (string)($item['user']['www'] ?? ''), + + 'activity_type' => (string)($item['type']['identifier'] ?? 'invite-in-person'), + + 'tags' => trim(implode(';', \Illuminate\Support\Arr::pluck($item['tags'] ?? [], 'title'))), + 'themes' => trim(implode(',', \Illuminate\Support\Arr::pluck($item['themes'] ?? [], 'identifier'))), + 'audience' => trim(implode(',', \Illuminate\Support\Arr::pluck($item['audience'] ?? [], 'identifier'))), + + 'last_updated_at' => now(), + ]; try { - $RSSitem->save(); - $new++; - Log::info("Successfully saved item {$index} from {$city}"); - } catch (\PDOException $exception) { - if ($exception->getCode() !== '23000') { - Log::error("Database error for item {$index} in {$city}: " . json_encode($exception->errorInfo)); + /** @var \Illuminate\Database\Eloquent\Model $existing */ + $existing = $className::query()->where('uid', $payload['uid'])->first(); + + if ($existing) { + $existing->fill($payload); + + if ($existing->isDirty()) { + $existing->save(); + $updated++; + Log::info("Updated RSS item uid={$payload['uid']} ({$city})"); + } else { + Log::info("No changes for RSS item uid={$payload['uid']} ({$city})"); + } + } else { + $className::query()->create($payload); + $new++; + Log::info("Inserted RSS item uid={$payload['uid']} ({$city})"); + } + } catch (\Throwable $e) { + // 23000 (duplicate) => retry as update (race condition safe) + if (method_exists($e, 'getCode') && (string)$e->getCode() === '23000') { + try { + $className::query()->where('uid', $payload['uid'])->update($payload); + $updated++; + Log::warning("Handled duplicate by updating uid={$payload['uid']} ({$city})"); + } catch (\Throwable $e2) { + Log::error("DB upsert retry failed for uid={$payload['uid']} ({$city}): ".$e2->getMessage()); + } + } else { + Log::error("DB error for item {$index} in {$city}: ".$e->getMessage()); } } - } catch (\Exception $e) { - Log::error("Error processing item {$index} from {$city}: " . $e->getMessage()); - Log::error("Item data: " . json_encode($item)); + } catch (\Throwable $e) { + Log::error("Error processing item {$index} from {$city}: ".$e->getMessage()); + Log::error("Item data: ".json_encode($item)); continue; } } - Log::info("New items imported from $city API: " . $new); + Log::info("{$city}: RSS upsert done. New={$new}, Updated={$updated}"); } - private function createGermanEvent($city): void + /** + * Create/Update an Event from current RSS item (idempotent, minimal fields). + * - Prevents duplicates via `events.source_ref` unique key "{feed}:{uid}". + * - Updates only a safe subset on subsequent syncs (dates & coords, picture if empty). + * - Guards against overwriting valid coords with default/fallback Germany center. + * + * @param string $city Feed key, e.g. "bremen", "baden", ... + * @return void + */ + private function createGermanEvent(string $city): void { - $user = User::where(['email' => $this->user_email])->first(); - - if ($user == null) { + $feedKey = Str::slug($city); + $sourceRef = $feedKey.':'.$this->uid; - //Create user - $user = User::create( - [ - 'email' => $this->user_email, + try { + $user = User::where('email', $this->user_email)->first(); + if (!$user) { + $user = User::create([ + 'email' => $this->user_email, 'firstname' => $this->organizer, - 'lastname' => '', - 'username' => $this->organizer, - 'password' => bcrypt(Str::random()), - ] - ); - } + 'lastname' => '', + 'username' => $this->organizer, + 'password' => bcrypt(Str::random()), + ]); + } + + $event = Event::where('source_ref', $sourceRef)->first(); - $event = new Event([ - 'status' => 'APPROVED', - 'title' => htmlspecialchars_decode($this->title), - 'slug' => Str::slug($this->title), - 'organizer' => $this->organizer, - 'description' => $this->description, - 'organizer_type' => $this->user_type, - 'activity_type' => $this->activity_type, - 'location' => $this->location, - 'event_url' => $this->user_website, - 'contact_person' => $this->user_publicEmail, - 'user_email' => $this->user_email, - 'creator_id' => $user->id, - 'country_iso' => 'DE', - 'picture' => $this->photo, - 'pub_date' => now(), - 'created' => now(), - 'updated' => now(), - 'codeweek_for_all_participation_code' => "cw-$city", - 'mass_added_for' => 'API codeweek_de', - 'start_date' => $this->eventStartDate, - 'end_date' => $this->eventEndDate, - 'longitude' => $this->longitude, - 'latitude' => $this->latitude, - 'geoposition' => $this->latitude . ',' . $this->longitude, - 'language' => 'de', - ]); - - $event->save(); - - //Link Other as theme and audience - if ($this->audience) { - $event->audiences()->attach(explode(',', $this->audience)); - } - if ($this->themes) { - $validThemeIds = $this->validateThemes($this->themes); - if (count($validThemeIds) > 0 ) { - $event->themes()->attach($validThemeIds); + if (!$event) { + $event = new Event([ + 'status' => 'APPROVED', + 'title' => htmlspecialchars_decode((string)$this->title), + 'slug' => Str::slug((string)$this->title), + 'organizer' => (string)$this->organizer, + 'description' => (string)$this->description, + 'organizer_type'=> (string)$this->user_type, + 'activity_type' => (string)$this->activity_type, + 'location' => (string)$this->location, + 'event_url' => (string)$this->user_website, + 'contact_person'=> (string)$this->user_publicEmail, + 'user_email' => (string)$this->user_email, + 'creator_id' => $user->id, + 'country_iso' => 'DE', + 'picture' => $this->photo, + 'pub_date' => now(), + 'created' => now(), + 'updated' => now(), + 'start_date' => $this->eventStartDate, + 'end_date' => $this->eventEndDate, + 'longitude' => $this->longitude, + 'latitude' => $this->latitude, + 'geoposition' => $this->latitude.','.$this->longitude, + 'language' => 'de', + 'codeweek_for_all_participation_code' => "cw-$city", + 'mass_added_for' => 'API codeweek_de', + // minimal linkage + 'source_ref' => $sourceRef, + 'source_synced_at'=> now(), + ]); + $event->save(); + + if (!empty($this->audience)) { + $event->audiences()->sync(explode(',', (string)$this->audience)); + } + if (!empty($this->themes)) { + $validThemeIds = $this->validateThemes((string)$this->themes); + if ($validThemeIds) { + $event->themes()->sync($validThemeIds); + } + } + if (!empty($this->tags)) { + $tagIds = []; + foreach (explode(';', (string)$this->tags) as $name) { + $name = trim($name); + if ($name === '') continue; + $tag = Tag::firstOrCreate(['name' => $name], ['slug' => Str::slug($name)]); + $tagIds[] = $tag->id; + } + if ($tagIds) $event->tags()->sync($tagIds); + } + + Log::info("[GermanTraits] Created event for {$sourceRef}", ['event_id' => $event->id]); + return; } - } - if ($this->tags) { - $tagsArray = []; + $dirty = []; - foreach (explode(';', $this->tags) as $item) { - $tag = Tag::firstOrCreate([ - 'name' => trim($item), - 'slug' => str_slug(trim($item)), - ]); - array_push($tagsArray, $tag->id); + if (!empty($this->eventStartDate)) $dirty['start_date'] = $this->eventStartDate; + if (!empty($this->eventEndDate)) $dirty['end_date'] = $this->eventEndDate; + + $dirty['latitude'] = $this->latitude; + $dirty['longitude'] = $this->longitude; + $dirty['geoposition'] = $this->latitude.','.$this->longitude; + + if (empty($event->picture) && !empty($this->photo)) { + $dirty['picture'] = $this->photo; + } + + if (empty($event->location) && !empty($this->location)) { + $dirty['location'] = (string)$this->location; + } + + if (!empty($dirty)) { + $dirty['updated'] = now(); + $event->fill($dirty); } - $event->tags()->sync($tagsArray); + $event->source_synced_at = now(); + $event->save(); + + Log::info("[GermanTraits] Updated event for {$sourceRef}", ['event_id' => $event->id, 'changed' => array_keys($dirty)]); + } catch (\Throwable $e) { + Log::error('[GermanTraits] createGermanEvent failed', [ + 'source_ref' => $sourceRef ?? null, + 'error' => $e->getMessage(), + ]); } } diff --git a/app/RSSItems/BadenRSSItem.php b/app/RSSItems/BadenRSSItem.php index 9fc15464e..efd004ab8 100644 --- a/app/RSSItems/BadenRSSItem.php +++ b/app/RSSItems/BadenRSSItem.php @@ -7,6 +7,39 @@ class BadenRSSItem extends Model { + protected $fillable = [ + 'uid', + 'title', + 'description', + 'organizer', + 'photo', + 'eventEndDate', + 'eventStartDate', + 'latitude', + 'longitude', + 'location', + 'user_company', + 'user_email', + 'user_publicEmail', + 'user_type', + 'user_website', + 'activity_type', + 'imported_at', + 'audience', + 'themes', + 'tags', + 'last_updated_at', + ]; + + protected $dates = [ + 'eventEndDate', + 'eventStartDate', + 'imported_at', + 'created_at', + 'updated_at', + 'last_updated_at', + ]; + use GermanTraits; public function createEvent($technicalUser) diff --git a/app/RSSItems/BayernRSSItem.php b/app/RSSItems/BayernRSSItem.php index 1089cd492..69ede2c5e 100644 --- a/app/RSSItems/BayernRSSItem.php +++ b/app/RSSItems/BayernRSSItem.php @@ -7,6 +7,39 @@ class BayernRSSItem extends Model { + protected $fillable = [ + 'uid', + 'title', + 'description', + 'organizer', + 'photo', + 'eventEndDate', + 'eventStartDate', + 'latitude', + 'longitude', + 'location', + 'user_company', + 'user_email', + 'user_publicEmail', + 'user_type', + 'user_website', + 'activity_type', + 'imported_at', + 'audience', + 'themes', + 'tags', + 'last_updated_at', + ]; + + protected $dates = [ + 'eventEndDate', + 'eventStartDate', + 'imported_at', + 'created_at', + 'updated_at', + 'last_updated_at', + ]; + use GermanTraits; public function createEvent($technicalUser) diff --git a/app/RSSItems/BerlinRSSItem.php b/app/RSSItems/BerlinRSSItem.php index 55f955fd7..d81269476 100644 --- a/app/RSSItems/BerlinRSSItem.php +++ b/app/RSSItems/BerlinRSSItem.php @@ -7,6 +7,39 @@ class BerlinRSSItem extends Model { + protected $fillable = [ + 'uid', + 'title', + 'description', + 'organizer', + 'photo', + 'eventEndDate', + 'eventStartDate', + 'latitude', + 'longitude', + 'location', + 'user_company', + 'user_email', + 'user_publicEmail', + 'user_type', + 'user_website', + 'activity_type', + 'imported_at', + 'audience', + 'themes', + 'tags', + 'last_updated_at', + ]; + + protected $dates = [ + 'eventEndDate', + 'eventStartDate', + 'imported_at', + 'created_at', + 'updated_at', + 'last_updated_at', + ]; + use GermanTraits; public function createEvent($technicalUser) diff --git a/app/RSSItems/BonnRSSItem.php b/app/RSSItems/BonnRSSItem.php index 92d3ee272..f883cdd06 100644 --- a/app/RSSItems/BonnRSSItem.php +++ b/app/RSSItems/BonnRSSItem.php @@ -7,6 +7,39 @@ class BonnRSSItem extends Model { + protected $fillable = [ + 'uid', + 'title', + 'description', + 'organizer', + 'photo', + 'eventEndDate', + 'eventStartDate', + 'latitude', + 'longitude', + 'location', + 'user_company', + 'user_email', + 'user_publicEmail', + 'user_type', + 'user_website', + 'activity_type', + 'imported_at', + 'audience', + 'themes', + 'tags', + 'last_updated_at', + ]; + + protected $dates = [ + 'eventEndDate', + 'eventStartDate', + 'imported_at', + 'created_at', + 'updated_at', + 'last_updated_at', + ]; + use GermanTraits; public function createEvent($technicalUser) diff --git a/app/RSSItems/BremenRSSItem.php b/app/RSSItems/BremenRSSItem.php index 283f911d4..7232f0bb7 100644 --- a/app/RSSItems/BremenRSSItem.php +++ b/app/RSSItems/BremenRSSItem.php @@ -7,6 +7,39 @@ class BremenRSSItem extends Model { + protected $fillable = [ + 'uid', + 'title', + 'description', + 'organizer', + 'photo', + 'eventEndDate', + 'eventStartDate', + 'latitude', + 'longitude', + 'location', + 'user_company', + 'user_email', + 'user_publicEmail', + 'user_type', + 'user_website', + 'activity_type', + 'imported_at', + 'audience', + 'themes', + 'tags', + 'last_updated_at', + ]; + + protected $dates = [ + 'eventEndDate', + 'eventStartDate', + 'imported_at', + 'created_at', + 'updated_at', + 'last_updated_at', + ]; + use GermanTraits; public function createEvent($technicalUser) diff --git a/app/RSSItems/DresdenRSSItem.php b/app/RSSItems/DresdenRSSItem.php index 72105c4d5..ec4582f29 100644 --- a/app/RSSItems/DresdenRSSItem.php +++ b/app/RSSItems/DresdenRSSItem.php @@ -7,6 +7,39 @@ class DresdenRSSItem extends Model { + protected $fillable = [ + 'uid', + 'title', + 'description', + 'organizer', + 'photo', + 'eventEndDate', + 'eventStartDate', + 'latitude', + 'longitude', + 'location', + 'user_company', + 'user_email', + 'user_publicEmail', + 'user_type', + 'user_website', + 'activity_type', + 'imported_at', + 'audience', + 'themes', + 'tags', + 'last_updated_at', + ]; + + protected $dates = [ + 'eventEndDate', + 'eventStartDate', + 'imported_at', + 'created_at', + 'updated_at', + 'last_updated_at', + ]; + use GermanTraits; public function createEvent($technicalUser) diff --git a/app/RSSItems/HamburgRSSItem.php b/app/RSSItems/HamburgRSSItem.php index 064941f8d..31313d2b3 100644 --- a/app/RSSItems/HamburgRSSItem.php +++ b/app/RSSItems/HamburgRSSItem.php @@ -7,6 +7,39 @@ class HamburgRSSItem extends Model { + protected $fillable = [ + 'uid', + 'title', + 'description', + 'organizer', + 'photo', + 'eventEndDate', + 'eventStartDate', + 'latitude', + 'longitude', + 'location', + 'user_company', + 'user_email', + 'user_publicEmail', + 'user_type', + 'user_website', + 'activity_type', + 'imported_at', + 'audience', + 'themes', + 'tags', + 'last_updated_at', + ]; + + protected $dates = [ + 'eventEndDate', + 'eventStartDate', + 'imported_at', + 'created_at', + 'updated_at', + 'last_updated_at', + ]; + use GermanTraits; public function createEvent($technicalUser) diff --git a/app/RSSItems/LeipzigRSSItem.php b/app/RSSItems/LeipzigRSSItem.php index 515c7df55..25216b283 100644 --- a/app/RSSItems/LeipzigRSSItem.php +++ b/app/RSSItems/LeipzigRSSItem.php @@ -7,6 +7,39 @@ class LeipzigRSSItem extends Model { + protected $fillable = [ + 'uid', + 'title', + 'description', + 'organizer', + 'photo', + 'eventEndDate', + 'eventStartDate', + 'latitude', + 'longitude', + 'location', + 'user_company', + 'user_email', + 'user_publicEmail', + 'user_type', + 'user_website', + 'activity_type', + 'imported_at', + 'audience', + 'themes', + 'tags', + 'last_updated_at', + ]; + + protected $dates = [ + 'eventEndDate', + 'eventStartDate', + 'imported_at', + 'created_at', + 'updated_at', + 'last_updated_at', + ]; + use GermanTraits; public function createEvent($technicalUser) diff --git a/app/RSSItems/MuensterlandRSSItem.php b/app/RSSItems/MuensterlandRSSItem.php index f92abe1f1..461176dd1 100644 --- a/app/RSSItems/MuensterlandRSSItem.php +++ b/app/RSSItems/MuensterlandRSSItem.php @@ -7,6 +7,39 @@ class MuensterlandRSSItem extends Model { + protected $fillable = [ + 'uid', + 'title', + 'description', + 'organizer', + 'photo', + 'eventEndDate', + 'eventStartDate', + 'latitude', + 'longitude', + 'location', + 'user_company', + 'user_email', + 'user_publicEmail', + 'user_type', + 'user_website', + 'activity_type', + 'imported_at', + 'audience', + 'themes', + 'tags', + 'last_updated_at', + ]; + + protected $dates = [ + 'eventEndDate', + 'eventStartDate', + 'imported_at', + 'created_at', + 'updated_at', + 'last_updated_at', + ]; + use GermanTraits; public function createEvent($technicalUser) diff --git a/app/RSSItems/NiedersachsenRSSItem.php b/app/RSSItems/NiedersachsenRSSItem.php index c1e8c579e..c4176adeb 100644 --- a/app/RSSItems/NiedersachsenRSSItem.php +++ b/app/RSSItems/NiedersachsenRSSItem.php @@ -7,6 +7,39 @@ class NiedersachsenRSSItem extends Model { + protected $fillable = [ + 'uid', + 'title', + 'description', + 'organizer', + 'photo', + 'eventEndDate', + 'eventStartDate', + 'latitude', + 'longitude', + 'location', + 'user_company', + 'user_email', + 'user_publicEmail', + 'user_type', + 'user_website', + 'activity_type', + 'imported_at', + 'audience', + 'themes', + 'tags', + 'last_updated_at', + ]; + + protected $dates = [ + 'eventEndDate', + 'eventStartDate', + 'imported_at', + 'created_at', + 'updated_at', + 'last_updated_at', + ]; + use GermanTraits; public function createEvent($technicalUser) diff --git a/app/RSSItems/NordhessenRSSItem.php b/app/RSSItems/NordhessenRSSItem.php index 652ce9ef9..5ba125417 100644 --- a/app/RSSItems/NordhessenRSSItem.php +++ b/app/RSSItems/NordhessenRSSItem.php @@ -7,6 +7,39 @@ class NordhessenRSSItem extends Model { + protected $fillable = [ + 'uid', + 'title', + 'description', + 'organizer', + 'photo', + 'eventEndDate', + 'eventStartDate', + 'latitude', + 'longitude', + 'location', + 'user_company', + 'user_email', + 'user_publicEmail', + 'user_type', + 'user_website', + 'activity_type', + 'imported_at', + 'audience', + 'themes', + 'tags', + 'last_updated_at', + ]; + + protected $dates = [ + 'eventEndDate', + 'eventStartDate', + 'imported_at', + 'created_at', + 'updated_at', + 'last_updated_at', + ]; + use GermanTraits; public function createEvent($technicalUser) diff --git a/app/RSSItems/ThueringenRSSItem.php b/app/RSSItems/ThueringenRSSItem.php index e00e15c1e..7da088641 100644 --- a/app/RSSItems/ThueringenRSSItem.php +++ b/app/RSSItems/ThueringenRSSItem.php @@ -7,6 +7,39 @@ class ThueringenRSSItem extends Model { + protected $fillable = [ + 'uid', + 'title', + 'description', + 'organizer', + 'photo', + 'eventEndDate', + 'eventStartDate', + 'latitude', + 'longitude', + 'location', + 'user_company', + 'user_email', + 'user_publicEmail', + 'user_type', + 'user_website', + 'activity_type', + 'imported_at', + 'audience', + 'themes', + 'tags', + 'last_updated_at', + ]; + + protected $dates = [ + 'eventEndDate', + 'eventStartDate', + 'imported_at', + 'created_at', + 'updated_at', + 'last_updated_at', + ]; + use GermanTraits; public function createEvent($technicalUser) diff --git a/database/migrations/2025_09_26_160415_add_source_ref_to_events_table.php b/database/migrations/2025_09_26_160415_add_source_ref_to_events_table.php new file mode 100644 index 000000000..3aa26d55e --- /dev/null +++ b/database/migrations/2025_09_26_160415_add_source_ref_to_events_table.php @@ -0,0 +1,30 @@ +string('source_ref', 191)->nullable()->unique()->after('language'); + $table->timestamp('source_synced_at')->nullable()->after('source_ref'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('events', function (Blueprint $table) { + $table->dropUnique(['source_ref']); + $table->dropColumn(['source_ref','source_synced_at']); + }); + } +};