*/ public array $translatable = ['title', 'description']; protected function casts(): array { return [ 'gallery' => 'array', 'brand_slugs' => 'array', 'is_published' => 'boolean', 'order' => 'integer', ]; } public function scopePublished(Builder $query): Builder { return $query->where('is_published', true); } public function scopeOrdered(Builder $query): Builder { return $query->orderBy('order')->orderBy('id'); } /** * Galerie in eine feste Form bringen: nur Einträge mit Bild, Bildunterschrift getrimmt. * * @param mixed $gallery * @return list */ public static function normalizeGallery($gallery): array { if (! is_array($gallery)) { return []; } $out = []; foreach ($gallery as $item) { $image = trim((string) (is_array($item) ? ($item['image'] ?? '') : $item)); if ($image === '') { continue; } $out[] = [ 'image' => $image, 'caption' => is_array($item) ? trim((string) ($item['caption'] ?? '')) : '', ]; } return $out; } /** * Beteiligte Marken als Liste mit Name und Link, aufgelöst gegen die veröffentlichten Marken. * * Eine unveröffentlichte oder gelöschte Marke fällt heraus. * * @param array> $brands Ergebnis von CmsBrand::forFrontend() * @return list */ public function resolveBrands(array $brands): array { $out = []; foreach ($this->brand_slugs ?? [] as $slug) { $slug = (string) $slug; if (! isset($brands[$slug])) { continue; } $out[] = [ 'slug' => $slug, 'name' => (string) ($brands[$slug]['name'] ?? $slug), 'link' => ! empty($brands[$slug]['has_detail_page']) ? '/marken/'.$slug : null, ]; } return $out; } }