get('per_page', 24)); $query = Artwork::public()->published(); if ($category) { $query->whereHas('categories', function ($q) use ($category) { $q->where('categories.id', $category->id); }); } if ($request->filled('q')) { $q = $request->get('q'); $query->where(function ($sub) use ($q) { $sub->where('title', 'like', '%' . $q . '%') ->orWhere('description', 'like', '%' . $q . '%'); }); } $sort = $request->get('sort', 'latest'); if ($sort === 'oldest') { $query->orderBy('published_at', 'asc'); } else { $query->orderByDesc('published_at'); } // Important: do NOT eager-load artwork_stats in listings $artworks = $query->cursorPaginate($perPage); return view('artworks.index', [ 'artworks' => $artworks, 'category' => $category, ]); } /** * Show a single artwork by slug. Resolve the slug manually to avoid implicit * route-model binding exceptions when the slug does not correspond to an artwork. */ public function show(Request $request, string $contentTypeSlug, string $categoryPath, $artwork = null) { $resolution = $this->contentTypeResolver->resolve($contentTypeSlug); if (! $resolution->found() || $resolution->contentType === null) { abort(404); } $resolvedContentTypeSlug = strtolower((string) $resolution->contentType->slug); if ($resolution->requiresRedirect()) { return $this->redirectToCanonicalArtworkPath($request, $resolvedContentTypeSlug, $categoryPath, $artwork, 301); } // Manually resolve artwork by slug when provided. The route may bind // the 'artwork' parameter to an Artwork model or pass the slug string. $foundArtwork = null; $artworkSlug = null; if ($artwork instanceof Artwork) { $foundArtwork = $artwork; $artworkSlug = $artwork->slug; } elseif ($artwork) { $artworkSlug = (string) $artwork; $foundArtwork = $this->findArtworkForCategoryPath($resolvedContentTypeSlug, $categoryPath, $artworkSlug); } // When the URL can represent a nested category path (e.g. /skins/audio/winamp), // prefer category rendering over artwork slug collisions so same-level groups // behave consistently. if (! empty($artworkSlug)) { $combinedPath = trim($categoryPath . '/' . $artworkSlug, '/'); $resolvedCategory = Category::findByPath($resolvedContentTypeSlug, $combinedPath); if ($resolvedCategory) { return app(BrowseGalleryController::class)->content(request(), $resolvedContentTypeSlug, $combinedPath); } } // If no artwork was found, treat the request as a category path. // The route places the artwork slug in the last segment, so include it. // Delegate to BrowseGalleryController to render the same modern gallery // layout used by routes like /skins/audio. if (! $foundArtwork) { $combinedPath = $categoryPath; if ($artworkSlug) { $combinedPath = trim($categoryPath . '/' . $artworkSlug, '/'); } return app(BrowseGalleryController::class)->content(request(), $resolvedContentTypeSlug, $combinedPath); } if (! $foundArtwork->is_public || ! $foundArtwork->is_approved || $foundArtwork->trashed()) { abort(404); } // Delegate to the canonical ArtworkPageController which builds all // required view data ($meta, thumbnails, related items, comments, etc.) return app(\App\Http\Controllers\Web\ArtworkPageController::class)->show( $request, (int) $foundArtwork->id, $foundArtwork->slug, ); } private function findArtworkForCategoryPath(string $contentTypeSlug, string $categoryPath, string $artworkSlug): ?Artwork { $segments = array_values(array_filter(explode('/', trim($categoryPath, '/')))); $category = Category::findByPath(strtolower($contentTypeSlug), $segments); $query = Artwork::query()->where('slug', $artworkSlug); if ($category) { $query->whereHas('categories', function ($categoryQuery) use ($category): void { $categoryQuery->where('categories.id', $category->id); }); } return $query ->orderByDesc('published_at') ->orderByDesc('id') ->first(); } private function redirectToCanonicalArtworkPath(Request $request, string $contentTypeSlug, string $categoryPath, Artwork|string|null $artwork, int $status = 301): RedirectResponse { $artworkSlug = $artwork instanceof Artwork ? $artwork->slug : (string) $artwork; $target = url('/' . trim($contentTypeSlug . '/' . trim($categoryPath, '/') . '/' . trim($artworkSlug, '/'), '/')); $queryString = $request->getQueryString(); if ($queryString) { $target .= '?' . $queryString; } return redirect()->to($target, $status); } }