*/ protected $fillable = [ 'seo_title', 'seo_description', 'title', 'subtitle', 'content', 'slug', 'picture', 'picture_alt', 'picture_title', 'static_page_id', 'order', 'published', 'publish_at', 'unpublish_at', ]; /** * The attributes that should be cast. * * @var array */ protected $casts = [ 'published' => 'boolean', 'publish_at' => 'datetime', 'unpublish_at' => 'datetime', ]; /** * Get model's setting to apply on scout search (meilisearch). * * @var array */ public static $searchSettings = [ 'filterableAttributes' => ['title', 'content', 'published'], 'sortableAttributes' => ['title', 'content'], ]; /** * Perform any actions required after the model boots. */ protected static function booted(): void { static::creating(function (self $model) { self::setOrder($model); self::manageFields($model); }); static::created(function (self $model) { self::resetCache($model->staticpage); }); static::updating(function (self $model) { self::manageFields($model); }); static::updated(function (self $model) { FileStorageHelper::removeOldFile($model, 'picture'); self::resetCache($model->staticpage); }); static::deleted(function (self $model) { FileStorageHelper::removeFile($model, 'picture'); self::resetCache($model->staticpage); }); } // * METHODS /** * Manage model fields. */ private static function manageFields(self $model): void { self::assertTitleIsUnique($model->title, $model->getKey() ?? null); $model->slug = Str::slug($model->title); self::makeStatusSense($model); $model->picture = FileStorageHelper::storeFile($model, $model->picture, true); } /** * Set order after the last element of the list. */ private static function setOrder(self $model): void { $model->order = \intval(self::query()->max('order')) + 1; } /** * Adjusts breedingNews status using current status and publish dates. */ private static function makeStatusSense(self $model): void { /** @var \Carbon\Carbon|null */ $publish_at = $model->publish_at; /** @var \Carbon\Carbon|null */ $unpublish_at = $model->unpublish_at; $wantedStatus = $model->published; if ($publish_at or $unpublish_at) { $model->published = $model->planificated_status; } if ($wantedStatus !== $model->published) { session()->flash('bo.info', \trans( 'La publication est modifiée en concordance avec les dates enregistrées. Pour modifier l\'état de publication, veuillez modifier ou enlever les dates correspondantes.' )); } } /** * Asserts using validation that the title is unique. * * @throws \Illuminate\Validation\ValidationException If an actu title already exists. */ private static function assertTitleIsUnique(?string $title, ?int $id = null): void { $table = (new self())->getTable(); ToolboxHelper::assertFieldIsUnique($table, 'title', $title, $id); ToolboxHelper::assertFieldIsUnique($table, 'slug', Str::slug($title), $id); } /** * Getter the current status following planification dates planificated_status. */ public function getPlanificatedStatusAttribute(): bool { /** @var \Carbon\Carbon|null */ $publish_at = $this->publish_at; /** @var \Carbon\Carbon|null */ $unpublish_at = $this->unpublish_at; if ($publish_at and $unpublish_at) { return $unpublish_at->greaterThanOrEqualTo(now()) and $publish_at->lessThan(now()); } if ($publish_at) { return $publish_at->lessThan(now()); } if ($unpublish_at) { return $unpublish_at->greaterThanOrEqualTo(now()); } return false; } /** * Reset all cache elements related to this model. */ private static function resetCache(StaticPage $staticPageModel): void { Cache::forget(sprintf('%sPublishedNewsBreedingOrderedByOrder', $staticPageModel->type->name)); self::getPublishedOrderedForType($staticPageModel); } /** * Get all published news breeding ordered by order associated to a given static page type. */ public static function getPublishedOrderedForType( StaticPage $staticPageModel ): Collection { return Cache::remember( sprintf('%sPublishedNewsBreedingOrderedByOrder', $staticPageModel->type->name), 86400, fn () => self::query() ->whereHas('staticpage', function (Builder $query) use ($staticPageModel) { $query->where('type', $staticPageModel->type); }) ->where('published', true) ->orderBy('order') ->get() ); } // * REDIRECTIONS. /** * All models it belongs to. * * @return array */ protected function getRouteParentModels(): array { return ['App\Models\StaticPage']; } /** * Get the front url of this model. * Should return the model.show route, with all binded elements if needed. */ public function getFrontUrl(string $modelKey): string { return route('fo.breeding.article.show', [ 'breeding_static_page' => $this->load('staticPage')->staticPage, 'published_news_breeding' => $modelKey, ]); } // * RELATIONSHIPS /** * Get Breeding static page (one-to-many relationship). */ public function staticPage(): BelongsTo { return $this->belongsTo(StaticPage::class); } }