blog/app/Models/Post.php

112 lines
2.5 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\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Str;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'category_id',
'title',
'slug',
'excerpt',
'content',
'cover_image',
'gallery',
'status',
'published_at',
'is_featured',
'views_count',
'likes_count',
];
protected $casts = [
'gallery' => 'array',
'published_at' => 'datetime',
'is_featured' => 'boolean',
];
protected static function boot()
{
parent::boot();
static::creating(function ($post) {
if (empty($post->slug)) {
$post->slug = Str::slug($post->title);
}
if (empty($post->user_id)) {
$post->user_id = auth()->id();
}
});
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function category(): BelongsTo
{
return $this->belongsTo(Category::class);
}
public function tags(): BelongsToMany
{
return $this->belongsToMany(Tag::class)->withTimestamps();
}
public function scopePublished($query)
{
return $query->where('status', 'published')
->where('published_at', '<=', now());
}
public function scopeFeatured($query)
{
return $query->where('is_featured', true);
}
public function scopeLatest($query)
{
return $query->orderBy('published_at', 'desc');
}
public function isPublished(): bool
{
return $this->status === 'published' && $this->published_at <= now();
}
public function getReadingTimeAttribute(): int
{
$wordCount = str_word_count(strip_tags($this->content));
return max(1, ceil($wordCount / 200));
}
public function incrementViews(): void
{
$this->increment('views_count');
}
public function getFirstGalleryImageAttribute(): ?string
{
if (!empty($this->gallery) && is_array($this->gallery)) {
return $this->gallery[0] ?? null;
}
return null;
}
public function getDisplayImageAttribute(): ?string
{
return $this->cover_image ?? $this->first_gallery_image;
}
}