600, 'best' => 600, 'latest' => 300, ]; public function __construct( private readonly RSSFeedBuilder $builder, private readonly ContentTypeSlugResolver $contentTypeResolver, ) {} /** /rss/explore/{type} — defaults to latest */ public function byType(Request $request, string $type): Response|RedirectResponse { return $this->feed($request, $type, 'latest'); } /** /rss/explore/{type}/{mode} */ public function byTypeMode(Request $request, string $type, string $mode): Response|RedirectResponse { return $this->feed($request, $type, $mode); } // ───────────────────────────────────────────────────────────────────────── private function feed(Request $request, string $type, string $mode): Response|RedirectResponse { $resolution = $this->contentTypeResolver->resolve($type, allowVirtual: true); if (! $resolution->found()) { abort(404); } $mode = in_array($mode, ['trending', 'latest', 'best'], true) ? $mode : 'latest'; $resolvedType = $resolution->isVirtual ? 'artworks' : strtolower((string) $resolution->contentType?->slug); if ($resolution->requiresRedirect()) { return redirect()->to(url('/rss/explore/' . $resolvedType . ($mode !== 'latest' ? '/' . $mode : '')) . ($request->getQueryString() ? ('?' . $request->getQueryString()) : ''), 301); } $ttl = self::SORT_TTL[$mode] ?? 300; $feedUrl = url('/rss/explore/' . $resolvedType . ($mode !== 'latest' ? '/' . $mode : '')); $label = $resolution->isVirtual ? 'All Artworks' : ($resolution->contentType?->name ?? ucfirst(str_replace('-', ' ', $resolvedType))); $artworks = Cache::remember("rss:explore:{$resolvedType}:{$mode}", $ttl, function () use ($resolution, $mode) { $contentType = $resolution->contentType; $query = Artwork::public()->published() ->with(['user:id,username', 'categories:id,name,slug,content_type_id']); if (! $resolution->isVirtual && $contentType) { $query->whereHas('categories', fn ($q) => $q->where('content_type_id', $contentType->id) ); } return match ($mode) { 'trending' => $query ->leftJoin('artwork_stats', 'artwork_stats.artwork_id', '=', 'artworks.id') ->orderByDesc('artwork_stats.trending_score_7d') ->orderByDesc('artworks.published_at') ->select('artworks.*') ->limit(RSSFeedBuilder::FEED_LIMIT) ->get(), 'best' => $query ->leftJoin('artwork_stats', 'artwork_stats.artwork_id', '=', 'artworks.id') ->orderByDesc('artwork_stats.favorites') ->orderByDesc('artwork_stats.downloads') ->select('artworks.*') ->limit(RSSFeedBuilder::FEED_LIMIT) ->get(), default => $query ->latest('artworks.published_at') ->limit(RSSFeedBuilder::FEED_LIMIT) ->get(), }; }); $modeLabel = match ($mode) { 'trending' => 'Trending', 'best' => 'Best', default => 'Latest', }; return $this->builder->buildFromArtworks( "{$modeLabel} {$label}", "{$modeLabel} {$label} artworks on Skinbase.", $feedUrl, $artworks, ); } }