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) { // 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 = Artwork::where('slug', $artworkSlug)->first(); } // 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($contentTypeSlug, $combinedPath); if ($resolvedCategory) { return app(BrowseGalleryController::class)->content(request(), $contentTypeSlug, $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(), $contentTypeSlug, $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, ); } }