> */ public function primary(): array { return $this->forLocations(['primary', 'header', 'main'], $this->fallbackPrimary()); } /** @return array> */ public function footer(): array { return $this->forLocations(['footer'], $this->fallbackFooter()); } /** @param array $locations * @param array> $fallback * @return array> */ private function forLocations(array $locations, array $fallback): array { try { if (! Schema::hasTable('menus')) { return $fallback; } $menu = Menu::query() ->where('enabled', true) ->whereIn('location', $locations) ->orderByRaw('CASE location '.collect($locations)->map(fn (string $location, int $index) => "WHEN ? THEN {$index}")->implode(' ').' ELSE 999 END', $locations) ->first(); if (! $menu || ! is_array($menu->items) || $menu->items === []) { return $fallback; } $items = $this->normaliseItems($menu->items); return $items === [] ? $fallback : $items; } catch (Throwable) { return $fallback; } } /** @param array $items * @return array> */ private function normaliseItems(array $items): array { return collect($items) ->filter(fn (mixed $item): bool => is_array($item) && ($item['enabled'] ?? true) !== false) ->map(function (array $item): ?array { $label = trim((string) ($item['label'] ?? $item['title'] ?? $item['name'] ?? '')); if ($label === '') { return null; } $url = $this->resolveUrl($item); if ($url === null) { return null; } return [ 'label' => $label, 'url' => $url, 'target' => ($item['target'] ?? null) === '_blank' ? '_blank' : null, 'children' => $this->normaliseItems((array) ($item['children'] ?? $item['items'] ?? [])), ]; }) ->filter() ->values() ->all(); } /** @param array $item */ private function resolveUrl(array $item): ?string { $routeName = trim((string) ($item['route'] ?? $item['route_name'] ?? '')); if ($routeName !== '' && Route::has($routeName)) { return route($routeName, (array) ($item['parameters'] ?? [])); } $pageSlug = trim((string) ($item['page_slug'] ?? $item['slug'] ?? '')); if ($pageSlug !== '' && Route::has('pages.public.show')) { return route('pages.public.show', $pageSlug); } $url = trim((string) ($item['url'] ?? $item['href'] ?? '')); return $url !== '' ? $url : null; } /** @return array> */ private function fallbackPrimary(): array { $items = [['label' => 'Home', 'url' => url('/'), 'target' => null, 'children' => []]]; if (Route::has('blog.public.index')) { $items[] = ['label' => 'Blog', 'url' => route('blog.public.index'), 'target' => null, 'children' => []]; } if (Route::has('news.public.index')) { $items[] = ['label' => 'News', 'url' => route('news.public.index'), 'target' => null, 'children' => []]; } return $items; } /** @return array> */ private function fallbackFooter(): array { return $this->fallbackPrimary(); } }