mirror of
https://github.com/pacnpal/thrillwiki_laravel.git
synced 2025-12-20 07:51:11 -05:00
Add models, enums, and services for user roles, theme preferences, slug history, and ID generation
This commit is contained in:
182
app/Models/Park.php
Normal file
182
app/Models/Park.php
Normal file
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\ParkStatus;
|
||||
use App\Traits\HasSlugHistory;
|
||||
use App\Traits\HasParkStatistics;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Park extends Model
|
||||
{
|
||||
use HasFactory, HasSlugHistory, HasParkStatistics;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'slug',
|
||||
'description',
|
||||
'status',
|
||||
'opening_date',
|
||||
'closing_date',
|
||||
'operating_season',
|
||||
'size_acres',
|
||||
'website',
|
||||
'operator_id',
|
||||
'total_areas',
|
||||
'operating_areas',
|
||||
'closed_areas',
|
||||
'total_rides',
|
||||
'total_coasters',
|
||||
'total_flat_rides',
|
||||
'total_water_rides',
|
||||
'total_daily_capacity',
|
||||
'average_wait_time',
|
||||
'average_rating',
|
||||
'total_rides_operated',
|
||||
'total_rides_retired',
|
||||
'last_expansion_date',
|
||||
'last_major_update',
|
||||
'utilization_rate',
|
||||
'peak_daily_attendance',
|
||||
'guest_satisfaction',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'status' => ParkStatus::class,
|
||||
'opening_date' => 'date',
|
||||
'closing_date' => 'date',
|
||||
'size_acres' => 'decimal:2',
|
||||
'total_areas' => 'integer',
|
||||
'operating_areas' => 'integer',
|
||||
'closed_areas' => 'integer',
|
||||
'total_rides' => 'integer',
|
||||
'total_coasters' => 'integer',
|
||||
'total_flat_rides' => 'integer',
|
||||
'total_water_rides' => 'integer',
|
||||
'total_daily_capacity' => 'integer',
|
||||
'average_wait_time' => 'integer',
|
||||
'average_rating' => 'decimal:2',
|
||||
'total_rides_operated' => 'integer',
|
||||
'total_rides_retired' => 'integer',
|
||||
'last_expansion_date' => 'date',
|
||||
'last_major_update' => 'date',
|
||||
'utilization_rate' => 'decimal:2',
|
||||
'peak_daily_attendance' => 'integer',
|
||||
'guest_satisfaction' => 'decimal:2',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the operator that owns the park.
|
||||
*/
|
||||
public function operator(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Operator::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the areas in the park.
|
||||
*/
|
||||
public function areas(): HasMany
|
||||
{
|
||||
return $this->hasMany(ParkArea::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get formatted website URL (ensures proper URL format).
|
||||
*/
|
||||
public function getWebsiteUrlAttribute(): string
|
||||
{
|
||||
if (!$this->website) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$website = $this->website;
|
||||
if (!str_starts_with($website, 'http://') && !str_starts_with($website, 'https://')) {
|
||||
$website = 'https://' . $website;
|
||||
}
|
||||
|
||||
return $website;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status display classes for Tailwind CSS.
|
||||
*/
|
||||
public function getStatusClassesAttribute(): string
|
||||
{
|
||||
return $this->status->getStatusClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a formatted display of the park's size.
|
||||
*/
|
||||
public function getSizeDisplayAttribute(): string
|
||||
{
|
||||
return $this->size_acres ? number_format($this->size_acres, 1) . ' acres' : 'Unknown size';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatted opening year.
|
||||
*/
|
||||
public function getOpeningYearAttribute(): ?string
|
||||
{
|
||||
return $this->opening_date?->format('Y');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a brief description suitable for cards and previews.
|
||||
*/
|
||||
public function getBriefDescriptionAttribute(): string
|
||||
{
|
||||
$description = $this->description ?? '';
|
||||
return strlen($description) > 200 ? substr($description, 0, 200) . '...' : $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to only include operating parks.
|
||||
*/
|
||||
public function scopeOperating($query)
|
||||
{
|
||||
return $query->where('status', ParkStatus::OPERATING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to only include closed parks.
|
||||
*/
|
||||
public function scopeClosed($query)
|
||||
{
|
||||
return $query->whereIn('status', [
|
||||
ParkStatus::CLOSED_TEMP,
|
||||
ParkStatus::CLOSED_PERM,
|
||||
ParkStatus::DEMOLISHED,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Boot the model.
|
||||
*/
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::created(function (Park $park) {
|
||||
$park->operator?->updateStatistics();
|
||||
});
|
||||
|
||||
static::deleted(function (Park $park) {
|
||||
$park->operator?->updateStatistics();
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user