*/ private const HUB_PAGES = [ 'faq', 'hilfe', 'api', 'kuendigung', 'impressum', 'datenschutz', 'agb', 'richtlinien', 'melden', ]; /** @var list */ private const PORTAL_PAGES = [ 'preise', 'veroeffentlichen', 'newsrooms', 'faq', 'hilfe', 'api', 'impressum', 'datenschutz', 'agb', 'richtlinien', 'melden', ]; public function __invoke(Request $request): Response { $host = $request->getHost(); $base = rtrim($request->getSchemeAndHttpHost(), '/'); $isHub = str_contains($host, 'pressekonto'); $xml = Cache::remember('web.sitemap.'.$host, 3600, function () use ($base, $isHub): string { $urls = $isHub ? $this->hubUrls($base) : $this->portalUrls($base); return view('web.sitemap', ['urls' => $urls])->render(); }); return response($xml, 200, ['Content-Type' => 'application/xml; charset=UTF-8']); } /** * @return list */ private function hubUrls(string $base): array { $urls = [['loc' => $base.'/', 'lastmod' => null]]; foreach (self::HUB_PAGES as $page) { $urls[] = ['loc' => $base.'/de/'.$page, 'lastmod' => null]; } return $urls; } /** * @return list */ private function portalUrls(string $base): array { $context = WebPortalContext::fromRequest(); $urls = [['loc' => $base.'/de', 'lastmod' => null]]; foreach (self::PORTAL_PAGES as $page) { $urls[] = ['loc' => $base.'/de/'.$page, 'lastmod' => null]; } // Kategorien über die lokalisierten Slugs (CategoryTranslation). $categorySlugs = Category::query() ->where('is_active', true) ->whereIn('portal', $context->portalValues) ->with('translations') ->get() ->map(fn (Category $category) => $category->translations->firstWhere('locale', 'de')?->slug) ->filter() ->unique(); foreach ($categorySlugs as $slug) { $urls[] = ['loc' => $base.'/de/category/'.$slug, 'lastmod' => null]; } // Öffentliche Newsrooms: aktive Firmen mit mindestens einer im Archiv // sichtbaren PM des Portals (gleiche Regel wie NewsroomsPageData). $companies = Company::query() ->where('is_active', true) ->whereHas('pressReleases', fn ($query) => $query ->withoutGlobalScope(PortalScope::class) ->visibleInArchive() ->forPortalValues($context->portalValues)) ->get(['slug', 'updated_at']); foreach ($companies as $company) { $urls[] = [ 'loc' => $base.'/de/newsroom/'.$company->slug, 'lastmod' => $company->updated_at?->toAtomString(), ]; } // Alle im Archiv sichtbaren Pressemitteilungen des Portals. $releases = PressRelease::query() ->withoutGlobalScope(PortalScope::class) ->visibleInArchive() ->forPortalValues($context->portalValues) ->orderByDesc('published_at') ->get(['slug', 'published_at', 'updated_at']); foreach ($releases as $release) { $urls[] = [ 'loc' => $base.'/de/press-release/'.$release->slug, 'lastmod' => ($release->updated_at ?? $release->published_at)?->toAtomString(), ]; } return $urls; } }