mirror of
https://github.com/pacnpal/thrillwiki_laravel.git
synced 2025-12-20 07:51:11 -05:00
Add photo management features, update database configuration, and enhance park model seeding
This commit is contained in:
@@ -6,8 +6,10 @@ use App\Enums\ParkStatus;
|
||||
use App\Traits\HasLocation;
|
||||
use App\Traits\HasSlugHistory;
|
||||
use App\Traits\HasParkStatistics;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
@@ -95,6 +97,95 @@ class Park extends Model
|
||||
return $this->hasMany(ParkArea::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the photos for the park.
|
||||
*/
|
||||
public function photos(): MorphMany
|
||||
{
|
||||
return $this->morphMany(Photo::class, 'photoable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the featured photo for the park.
|
||||
*/
|
||||
public function featuredPhoto()
|
||||
{
|
||||
return $this->photos()->where('is_featured', true)->first()
|
||||
?? $this->photos()->orderBy('position')->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL of the featured photo or a default image.
|
||||
*/
|
||||
public function getFeaturedPhotoUrlAttribute(): string
|
||||
{
|
||||
$photo = $this->featuredPhoto();
|
||||
return $photo ? $photo->url : asset('images/placeholders/default-park.jpg');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a photo to the park.
|
||||
*
|
||||
* @param array<string, mixed> $attributes
|
||||
* @return \App\Models\Photo
|
||||
*/
|
||||
public function addPhoto(array $attributes): Photo
|
||||
{
|
||||
// Set position to be the last in the collection if not specified
|
||||
if (!isset($attributes['position'])) {
|
||||
$lastPosition = $this->photos()->max('position') ?? 0;
|
||||
$attributes['position'] = $lastPosition + 1;
|
||||
}
|
||||
|
||||
// If this is the first photo or is_featured is true, make it featured
|
||||
if ($this->photos()->count() === 0 || ($attributes['is_featured'] ?? false)) {
|
||||
$attributes['is_featured'] = true;
|
||||
} else {
|
||||
$attributes['is_featured'] = false;
|
||||
}
|
||||
|
||||
return $this->photos()->create($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a photo as the featured photo.
|
||||
*
|
||||
* @param \App\Models\Photo|int $photo
|
||||
* @return bool
|
||||
*/
|
||||
public function setFeaturedPhoto($photo): bool
|
||||
{
|
||||
if (is_numeric($photo)) {
|
||||
$photo = $this->photos()->findOrFail($photo);
|
||||
}
|
||||
|
||||
return $photo->setAsFeatured();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reorder photos.
|
||||
*
|
||||
* @param array<int, int> $photoIds Ordered array of photo IDs
|
||||
* @return bool
|
||||
*/
|
||||
public function reorderPhotos(array $photoIds): bool
|
||||
{
|
||||
// Begin transaction
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
foreach ($photoIds as $position => $photoId) {
|
||||
$this->photos()->where('id', $photoId)->update(['position' => $position + 1]);
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get formatted website URL (ensures proper URL format).
|
||||
*/
|
||||
@@ -165,6 +256,50 @@ class Park extends Model
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatted location for the park.
|
||||
*/
|
||||
public function getFormattedLocationAttribute(): string
|
||||
{
|
||||
return $this->formatted_address ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the absolute URL for the park detail page.
|
||||
*/
|
||||
public function getAbsoluteUrl(): string
|
||||
{
|
||||
return route('parks.show', ['slug' => $this->slug]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a park by its current or historical slug.
|
||||
*
|
||||
* @param string $slug
|
||||
* @return array{0: \App\Models\Park|null, 1: bool} Park and whether a historical slug was used
|
||||
*/
|
||||
public static function getBySlug(string $slug): array
|
||||
{
|
||||
// Try current slug
|
||||
$park = static::where('slug', $slug)->first();
|
||||
if ($park) {
|
||||
return [$park, false];
|
||||
}
|
||||
|
||||
// Try historical slug
|
||||
$slugHistory = SlugHistory::where('slug', $slug)
|
||||
->where('sluggable_type', static::class)
|
||||
->latest()
|
||||
->first();
|
||||
|
||||
if ($slugHistory) {
|
||||
$park = static::find($slugHistory->sluggable_id);
|
||||
return [$park, true];
|
||||
}
|
||||
|
||||
return [null, false];
|
||||
}
|
||||
|
||||
/**
|
||||
* Boot the model.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user