Veranstaltungen-APP/app/Models/Event.php

149 lines
3.5 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Str;
class Event extends Model
{
use SoftDeletes;
protected $fillable = [
'source_id',
'location_id',
'created_by',
'external_id',
'title',
'description',
'category',
'slug',
'image_url',
'website_url',
'contact_email',
'contact_phone',
'status',
];
protected $casts = [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
];
/**
* Ein Event gehört zu einer Source.
*/
public function source(): BelongsTo
{
return $this->belongsTo(Source::class);
}
/**
* Ein Event gehört zu einem Ort.
*/
public function location(): BelongsTo
{
return $this->belongsTo(Location::class);
}
/**
* Ein Event wurde von einem User erstellt.
*/
public function creator(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
/**
* Ein Event hat viele User die es als Favorit gespeichert haben.
*/
public function favoritedByUsers(): BelongsToMany
{
return $this->belongsToMany(User::class, 'user_event_favorites', 'event_id', 'user_id')
->withTimestamps();
}
/**
* Ein Event hat viele Termine/Vorkommen.
*/
public function occurrences(): HasMany
{
return $this->hasMany(EventOccurrence::class)->orderBy('start_datetime');
}
/**
* Nur kommende/geplante Vorkommen.
*/
public function upcomingOccurrences(): HasMany
{
return $this->occurrences()
->where('start_datetime', '>=', now())
->where('status', 'scheduled');
}
/**
* Nächster Termin.
*/
public function nextOccurrence()
{
return $this->upcomingOccurrences()->first();
}
/**
* Scope für veröffentlichte Events.
*/
public function scopePublished($query)
{
return $query->where('status', 'published');
}
/**
* Scope für Filter nach Kategorie.
*/
public function scopeByCategory($query, $category)
{
return $query->where('category', $category);
}
/**
* Scope für Filter nach Ort.
*/
public function scopeByLocation($query, $location)
{
return $query->whereHas('location', function ($q) use ($location) {
$q->where('name', 'like', '%' . $location . '%')
->orWhere('city', 'like', '%' . $location . '%');
});
}
/**
* Scope für Filter nach Zeitraum (hat ein Vorkommen in diesem Zeitraum).
*/
public function scopeUpcomingBetween($query, $startDate, $endDate)
{
return $query->whereHas('occurrences', function ($q) use ($startDate, $endDate) {
$q->whereBetween('start_datetime', [$startDate, $endDate])
->where('status', 'scheduled');
});
}
/**
* Boot-Methode: Auto-generate slug.
*/
protected static function boot()
{
parent::boot();
static::creating(function ($event) {
if (!$event->slug) {
$event->slug = Str::slug($event->title . '-' . uniqid());
}
});
}
}