*/ use BumpsContentVersion, HasContentViews, HasFactory, HasPublicationWindow, HasReviews, HasRevisions, HasTranslations, RecordsSlugChanges, SoftDeletes; /** @var array */ public array $translatable = [ 'title', 'slug', 'tagline', 'description', 'meta_title', 'meta_description', ]; protected function casts(): array { return [ 'is_published' => 'boolean', 'published_at' => 'datetime', 'unpublish_at' => 'datetime', 'is_featured' => 'boolean', 'position' => 'integer', ]; } /** * Whether the site is showing this right now. */ public function isPublishedNow(): bool { return $this->is_published && ! $this->isScheduled() && ! $this->hasExpired(); } /** * The `site.paths` key this model publishes under, so a slug change knows * which URL it just broke. */ public function publicPathType(): string { return 'service'; } /** * @return BelongsToMany */ public function projects(): BelongsToMany { return $this->belongsToMany(Project::class); } /** * @return BelongsToMany */ public function technologies(): BelongsToMany { return $this->belongsToMany(Technology::class); } /** * @return HasMany */ public function testimonials(): HasMany { return $this->hasMany(Testimonial::class); } /** * @param Builder<$this> $query * @return Builder<$this> */ public function scopePublished(Builder $query): Builder { return $query ->where('is_published', true) // The same window as pages and projects, enforced in one place so // nothing that reads published services has to remember it. ->where(fn (Builder $q) => $q ->whereNull('published_at') ->orWhere('published_at', '<=', now())) ->where(fn (Builder $q) => $q ->whereNull('unpublish_at') ->orWhere('unpublish_at', '>', now())); } /** * @param Builder<$this> $query * @return Builder<$this> */ public function scopeWhereSlug(Builder $query, string $slug, ?string $locale = null): Builder { $locale ??= app()->getLocale(); return $query->where("slug->{$locale}", $slug); } }