168 lines
4.0 KiB
PHP
168 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
|
|
class Wisata extends Model
|
|
{
|
|
use HasFactory;
|
|
|
|
protected $fillable = [
|
|
'kategori_id',
|
|
'title',
|
|
'slug',
|
|
'location',
|
|
'image',
|
|
'rating',
|
|
'distance',
|
|
'elevation',
|
|
'tiket_parkir',
|
|
'jam_operasional',
|
|
'short_description',
|
|
'overview',
|
|
'model_path',
|
|
'video_path',
|
|
'is_video',
|
|
'latitude',
|
|
'longitude',
|
|
];
|
|
|
|
protected function casts(): array
|
|
{
|
|
return [
|
|
'rating' => 'decimal:1',
|
|
'is_video' => 'boolean',
|
|
'latitude' => 'decimal:7',
|
|
'longitude' => 'decimal:7',
|
|
];
|
|
}
|
|
|
|
public function setImageAttribute(?string $value): void
|
|
{
|
|
$this->attributes['image'] = $this->normalizeStoredFilePath($value);
|
|
}
|
|
|
|
public function setModelPathAttribute(?string $value): void
|
|
{
|
|
$this->attributes['model_path'] = $this->normalizeStoredFilePath($value);
|
|
}
|
|
|
|
public function setVideoPathAttribute(?string $value): void
|
|
{
|
|
$this->attributes['video_path'] = $this->normalizeStoredFilePath($value);
|
|
}
|
|
|
|
public function kategori(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Kategori::class);
|
|
}
|
|
|
|
public function fileUrl(?string $path): ?string
|
|
{
|
|
if (! $path) {
|
|
return null;
|
|
}
|
|
|
|
if (Str::startsWith($path, ['http://', 'https://'])) {
|
|
return $path;
|
|
}
|
|
|
|
$storagePath = $this->publicStoragePath($path);
|
|
|
|
if ($storagePath && Storage::disk('public')->exists($storagePath)) {
|
|
return asset('storage/'.$storagePath);
|
|
}
|
|
|
|
$publicPath = $this->publicAssetPath($path);
|
|
|
|
return $publicPath && file_exists(public_path($publicPath))
|
|
? asset($publicPath)
|
|
: null;
|
|
}
|
|
|
|
public function getImageUrlAttribute(): string
|
|
{
|
|
return $this->fileUrl($this->image) ?? asset('images/placeholders/wisata.svg');
|
|
}
|
|
|
|
public function getRatingLabelAttribute(): string
|
|
{
|
|
return number_format((float) $this->rating, 1).' ⭐';
|
|
}
|
|
|
|
public function publicStoragePath(?string $path): ?string
|
|
{
|
|
if (! $path || Str::startsWith($path, ['http://', 'https://'])) {
|
|
return null;
|
|
}
|
|
|
|
$path = ltrim(str_replace('\\', '/', $path), '/');
|
|
|
|
foreach (['/storage/app/public/', '/public/storage/'] as $needle) {
|
|
if (str_contains($path, $needle)) {
|
|
$path = Str::after($path, $needle);
|
|
break;
|
|
}
|
|
}
|
|
|
|
foreach (['storage/app/public/', 'public/storage/', 'storage/', 'public/'] as $prefix) {
|
|
if (Str::startsWith($path, $prefix)) {
|
|
$path = Str::after($path, $prefix);
|
|
}
|
|
}
|
|
|
|
return $path ?: null;
|
|
}
|
|
|
|
private function normalizeStoredFilePath(?string $path): ?string
|
|
{
|
|
if (! $path) {
|
|
return null;
|
|
}
|
|
|
|
if (Str::startsWith($path, ['http://', 'https://'])) {
|
|
return $path;
|
|
}
|
|
|
|
return $this->publicStoragePath($path);
|
|
}
|
|
|
|
private function publicAssetPath(string $path): ?string
|
|
{
|
|
$path = ltrim(str_replace('\\', '/', $path), '/');
|
|
|
|
if (Str::startsWith($path, 'public/')) {
|
|
$path = Str::after($path, 'public/');
|
|
}
|
|
|
|
return $path ?: null;
|
|
}
|
|
|
|
public function getTypeAttribute(): string
|
|
{
|
|
if ($this->model_path) {
|
|
return 'ar';
|
|
}
|
|
|
|
if ($this->is_video) {
|
|
return 'video';
|
|
}
|
|
|
|
return 'normal';
|
|
}
|
|
|
|
public function getGoogleMapsUrlAttribute(): ?string
|
|
{
|
|
if ($this->latitude === null || $this->longitude === null) {
|
|
return null;
|
|
}
|
|
|
|
return "https://www.google.com/maps?q={$this->latitude},{$this->longitude}";
|
|
}
|
|
}
|