'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; } }