table('featured_works as fw') ->leftJoin('wallz as w', 'fw.artwork_id', '=', 'w.id') ->leftJoin('users as u', 'w.user_id', '=', 'u.user_id') ->select('w.id', 'w.name', 'w.picture', 'u.uname', 'fw.post_date') ->orderByDesc('fw.post_date') ->first(); $memberFeatured = DB::connection('legacy')->table('users_opinions as o') ->leftJoin('wallz as w', 'o.artwork_id', '=', 'w.id') ->leftJoin('users as u', 'w.user_id', '=', 'u.user_id') ->select(DB::raw('COUNT(*) AS votes'), 'w.id', 'w.name', 'w.picture', 'u.uname') ->whereRaw('o.post_date > SUBDATE(CURRENT_DATE(), INTERVAL 30 DAY)') ->where('o.score', 4) ->groupBy('o.artwork_id', 'w.id', 'w.name', 'w.picture', 'u.uname') ->orderByDesc('votes') ->limit(1) ->first(); } catch (\Throwable $e) { // fail soft } if (!$featured) { $featured = (object) [ 'id' => 0, 'name' => 'Featured Artwork', 'picture' => '/gfx/sb_join.jpg', 'uname' => 'Skinbase', ]; } if (!$memberFeatured) { $memberFeatured = (object) [ 'id' => 0, 'name' => 'Members Pick', 'picture' => '/gfx/sb_join.jpg', 'uname' => 'Skinbase', 'votes' => 0, ]; } return [$featured, $memberFeatured]; } public function latestUploads(): array { $uploads = []; $cachePath = base_path('oldSite/www/cache/latest_uploads.json'); if (File::exists($cachePath)) { $json = File::get($cachePath); $uploads = json_decode($json, true) ?: []; } if (empty($uploads)) { try { $uploads = DB::connection('legacy')->table('wallz as w') ->leftJoin('users as u', 'w.user_id', '=', 'u.user_id') ->leftJoin('artworks_categories as c', 'w.category', '=', 'c.category_id') ->where('w.approved', 1) ->orderByDesc('w.datum') ->limit(20) ->get() ->map(function ($row) { return [ 'id' => $row->id, 'name' => $row->name, 'picture' => $row->picture, 'uname' => $row->uname, 'category_name' => $row->category_name ?? '', ]; }) ->toArray(); } catch (\Throwable $e) { $uploads = []; } } if (empty($uploads)) { $uploads = [ [ 'id' => 1, 'name' => 'Sample Artwork', 'picture' => 'gfx/sb_join.jpg', 'uname' => 'Skinbase', 'category_name' => 'Photography', ], ]; } return $uploads; } public function forumNews(): array { try { return DB::connection('legacy')->table('forum_topics as t1') ->leftJoin('users as t2', 't1.user_id', '=', 't2.user_id') ->select( 't1.topic_id', 't1.topic', 't1.views', 't1.post_date', 't1.preview', 't2.uname' ) ->where('t1.root_id', 2876) ->where('t1.privilege', '<', 4) ->orderByDesc('t1.post_date') ->limit(8) ->get() ->toArray(); } catch (\Throwable $e) { return []; } } public function ourNews(): array { try { return DB::connection('legacy')->table('news as t1') ->join('news_categories as t2', 't1.category_id', '=', 't2.category_id') ->join('users as t3', 't1.user_id', '=', 't3.user_id') ->select( 't1.news_id', 't1.headline', 't1.picture', 't1.preview', 't1.create_date', 't1.views', 't2.category_name', 't3.uname', DB::raw('(SELECT COUNT(*) FROM news_comment WHERE news_id = t1.news_id) AS num_comments') ) ->orderByDesc('t1.create_date') ->limit(5) ->get() ->toArray(); } catch (\Throwable $e) { return []; } } public function latestForumActivity(): array { try { return DB::connection('legacy')->table('forum_topics as t1') ->select( 't1.topic_id', 't1.topic', DB::raw('(SELECT COUNT(*) FROM forum_posts WHERE topic_id = t1.topic_id) AS numPosts') ) ->where('t1.root_id', '<>', 0) ->where('t1.root_id', '<>', 2876) ->where('t1.privilege', '<', 4) ->orderByDesc('t1.last_update') ->orderByDesc('t1.post_date') ->limit(10) ->get() ->toArray(); } catch (\Throwable $e) { return []; } } public function browseGallery(int $perPage = 50) { try { return DB::connection('legacy')->table('wallz as w') ->leftJoin('artworks_categories as c', 'w.category', '=', 'c.category_id') ->leftJoin('users as u', 'w.user_id', '=', 'u.user_id') ->select('w.id', 'w.name', 'w.picture', 'w.category', 'w.datum', 'c.category_name', 'u.uname') ->where('w.approved', 1) ->where('w.public', 'Y') ->orderByDesc('w.datum') ->paginate($perPage) ->withQueryString(); } catch (\Throwable $e) { return null; } } public function categoryPage(string $group, ?string $slug = null, ?int $id = null) { $group = \Illuminate\Support\Str::title($group); $defaults = [ 'Skins' => 1, 'Wallpapers' => 2, 'Photography' => 3, 'Other' => 4, ]; if (!$id && $slug && ctype_digit($slug)) { $id = (int) $slug; } $id = $id ?: ($defaults[$group] ?? null); if (!$id || $id < 1) { return null; } try { $category = DB::connection('legacy')->table('artworks_categories') ->select('category_id', 'category_name', 'description', 'rootid', 'section_id') ->where('category_id', $id) ->first(); } catch (\Throwable $e) { $category = null; } if (! $category) { return null; } $perPage = 40; try { $base = DB::connection('legacy')->table('wallz as t1') ->select('t1.id', 't1.name', 't1.picture', 't3.uname', 't1.category', 't2.category_name') ->join('artworks_categories as t2', 't1.category', '=', 't2.category_id') ->leftJoin('users as t3', 't1.user_id', '=', 't3.user_id') ->where('t1.approved', 1) ->where(function ($q) use ($id, $category) { $q->where('t1.category', (int) $id); if ($category->rootid > 0) { $q->orWhere('t1.rootid', (int) $id); } }) ->orderByDesc('t1.datum'); $artworks = $base->paginate($perPage)->withQueryString(); if ($artworks && method_exists($artworks, 'getCollection')) { $artworks->getCollection()->transform(function ($row) { $row->gid_num = ((int) ($row->category ?? 0) % 5) * 5; if (!empty($row->picture)) { $ext = self::fileExtension($row->picture); $encoded = self::encode($row->id); $row->ext = $ext; $row->encoded = $encoded; // Prefer new files.skinbase.org when possible try { $art = \App\Models\Artwork::find($row->id); $present = \App\Services\ThumbnailPresenter::present($art ?: (array) $row, 'md'); $row->thumb_url = $present['url']; $row->thumb_srcset = $present['srcset']; } catch (\Throwable $e) { $present = \App\Services\ThumbnailPresenter::present((array) $row, 'md'); $row->thumb_url = $present['url']; $row->thumb_srcset = $present['srcset']; } } else { $row->ext = null; $row->encoded = null; $row->thumb_url = '/gfx/sb_join.jpg'; $row->thumb_srcset = null; } return $row; }); } } catch (\Throwable $e) { $artworks = null; } try { $subcategories = DB::connection('legacy')->table('artworks_categories') ->select('category_id', 'category_name') ->where('rootid', $id) ->orderBy('category_name') ->get(); if ($subcategories->isEmpty() && $category->rootid) { $subcategories = DB::connection('legacy')->table('artworks_categories') ->select('category_id', 'category_name') ->where('rootid', $category->rootid) ->orderBy('category_name') ->get(); } if ($subcategories->isEmpty()) { $subcategories = DB::connection('legacy')->table('skupine') ->select('category_id', 'category_name') ->where('rootid', $id) ->orderBy('category_name') ->get(); } } catch (\Throwable $e) { try { $subcategories = DB::connection('legacy')->table('skupine') ->select('category_id', 'category_name') ->where('rootid', $id) ->orderBy('category_name') ->get(); } catch (\Throwable $e2) { $subcategories = collect(); } } $page_title = $group; $page_meta_description = $group . ' artworks on Skinbase'; $page_meta_keywords = strtolower($group) . ', skinbase, artworks, wallpapers, skins'; return [ 'group' => $group, 'category' => $category, 'artworks' => $artworks, 'subcategories' => $subcategories, 'page_title' => $page_title, 'page_meta_description' => $page_meta_description, 'page_meta_keywords' => $page_meta_keywords, ]; } public function browseCategories() { try { $categories = DB::connection('legacy')->table('artworks_categories') ->select('category_id', 'category_name', 'description') ->where('section_id', 0) ->where('rootid', 0) ->orderBy('category_id') ->get(); if ($categories->isEmpty()) { $categories = DB::connection('legacy')->table('skupine') ->select('category_id', 'category_name', 'description') ->where('section_id', 0) ->where('rootid', 0) ->orderBy('category_id') ->get(); } } catch (\Throwable $e) { try { $categories = DB::connection('legacy')->table('skupine') ->select('category_id', 'category_name', 'description') ->where('section_id', 0) ->where('rootid', 0) ->orderBy('category_id') ->get(); } catch (\Throwable $e2) { $categories = collect(); } } $subgroups = collect(); if ($categories->isNotEmpty()) { $ids = $categories->pluck('category_id')->unique()->values()->all(); try { $subs = DB::connection('legacy')->table('artworks_categories') ->select('category_id', 'category_name', 'picture', 'section_id') ->whereIn('section_id', $ids) ->orderBy('category_name') ->get(); if ($subs->isEmpty()) { $subs = DB::connection('legacy')->table('skupine') ->select('category_id', 'category_name', 'picture', 'section_id') ->whereIn('section_id', $ids) ->orderBy('category_name') ->get(); } $subgroups = $subs->groupBy('section_id'); } catch (\Throwable $e) { $subgroups = collect(); } } return [ 'categories' => $categories, 'subgroups' => $subgroups, 'page_title' => 'Browse Categories', 'page_meta_description' => 'Browse categories across Photography, Wallpapers, Skins and more on Skinbase.', 'page_meta_keywords' => 'categories, photography, wallpapers, skins, browse', ]; } public function forumIndex() { try { $topics = DB::connection('legacy')->table('forum_topics as t') ->select( 't.topic_id', 't.topic', 't.discuss', 't.last_update', 't.privilege', DB::raw('(SELECT COUNT(*) FROM forum_posts p WHERE p.topic_id IN (SELECT topic_id FROM forum_topics st WHERE st.root_id = t.topic_id)) AS num_posts'), DB::raw('(SELECT COUNT(*) FROM forum_topics st WHERE st.root_id = t.topic_id) AS num_subtopics') ) ->where('t.root_id', 0) ->where('t.privilege', '<', 4) ->orderByDesc('t.last_update') ->limit(100) ->get(); } catch (\Throwable $e) { $topics = collect(); } return [ 'topics' => $topics, 'page_title' => 'Forum', 'page_meta_description' => 'Skinbase forum threads.', 'page_meta_keywords' => 'forum, discussions, topics, skinbase', ]; } public function forumTopic(int $topic_id, int $page = 1) { try { $topic = DB::connection('legacy')->table('forum_topics')->where('topic_id', $topic_id)->first(); } catch (\Throwable $e) { $topic = null; } if (! $topic) { return null; } try { $subtopics = DB::connection('legacy')->table('forum_topics as t') ->leftJoin('users as u', 't.user_id', '=', 'u.user_id') ->select( 't.topic_id', 't.topic', 't.discuss', 't.post_date', 't.last_update', 'u.uname', DB::raw('(SELECT COUNT(*) FROM forum_posts p WHERE p.topic_id = t.topic_id) AS num_posts') ) ->where('t.root_id', $topic->topic_id) ->orderByDesc('t.last_update') ->paginate(50) ->withQueryString(); } catch (\Throwable $e) { $subtopics = null; } if ($subtopics && $subtopics->total() > 0) { return [ 'type' => 'subtopics', 'topic' => $topic, 'subtopics' => $subtopics, 'page_title' => $topic->topic, 'page_meta_description' => \Illuminate\Support\Str::limit(strip_tags($topic->discuss ?? 'Forum topic'), 160), 'page_meta_keywords' => 'forum, topic, skinbase', ]; } $sort = strtolower(request()->query('sort', 'desc')) === 'asc' ? 'asc' : 'desc'; try { $posts = DB::connection('legacy')->table('forum_posts as p') ->leftJoin('users as u', 'p.user_id', '=', 'u.user_id') ->select('p.id', 'p.message', 'p.post_date', 'u.uname', 'u.user_id', 'u.icon', 'u.eicon') ->where('p.topic_id', $topic->topic_id) ->orderBy('p.post_date', $sort) ->paginate(50) ->withQueryString(); } catch (\Throwable $e) { $posts = null; } if (! $posts || $posts->total() === 0) { try { $posts = DB::connection('legacy')->table('forum_posts as p') ->leftJoin('users as u', 'p.user_id', '=', 'u.user_id') ->select('p.id', 'p.message', 'p.post_date', 'u.uname', 'u.user_id', 'u.icon', 'u.eicon') ->where('p.tid', $topic->topic_id) ->orderBy('p.post_date', $sort) ->paginate(50) ->withQueryString(); } catch (\Throwable $e) { $posts = null; } } // Ensure $posts is always a LengthAwarePaginator so views can iterate and render pagination safely if (! $posts) { $currentPage = max(1, (int) request()->query('page', $page)); $items = collect(); $posts = new LengthAwarePaginator($items, 0, 50, $currentPage, [ 'path' => Paginator::resolveCurrentPath(), ]); } return [ 'type' => 'posts', 'topic' => $topic, 'posts' => $posts, 'page_title' => $topic->topic, 'page_meta_description' => \Illuminate\Support\Str::limit(strip_tags($topic->discuss ?? 'Forum topic'), 160), 'page_meta_keywords' => 'forum, topic, skinbase', ]; } /** * Fetch a single artwork by id with author and category * Returns null on failure. */ public function getArtwork(int $id) { try { $row = DB::connection('legacy')->table('wallz as w') ->leftJoin('users as u', 'w.user_id', '=', 'u.user_id') ->leftJoin('artworks_categories as c', 'w.category', '=', 'c.category_id') ->select('w.*', 'u.uname', 'c.category_name') ->where('w.id', $id) ->first(); } catch (\Throwable $e) { $row = null; } if (! $row) { return null; } // compute thumbnail/zoom paths similar to legacy code $nid = (int) ($row->id / 100); $nid_new = (int) ($row->id / 1000); $encoded = self::encode($row->id); $ext = self::fileExtension($row->picture ?? 'jpg'); $appUrl = rtrim(config('app.url', ''), '/'); $shot_name = $appUrl . '/files/archive/shots/' . $nid . '/' . ($row->picture ?? ''); $zoom_name = $appUrl . '/files/archive/zoom/' . $nid . '/' . ($row->picture ?? ''); $thumb_600 = $appUrl . '/files/thumb/' . $nid_new . '/600_' . $row->id . '.jpg'; // Prefer new CDN when possible try { $art = \App\Models\Artwork::find($row->id); $present = \App\Services\ThumbnailPresenter::present($art ?: (array) $row, 'md'); $thumb_file = $present['url']; $thumb_file_300 = $present['srcset'] ? explode(' ', explode(',', $present['srcset'])[0])[0] : ($present['url'] ?? null); } catch (\Throwable $e) { $present = \App\Services\ThumbnailPresenter::present((array) $row, 'md'); $thumb_file = $present['url']; $thumb_file_300 = $present['srcset'] ? explode(' ', explode(',', $present['srcset'])[0])[0] : ($present['url'] ?? null); } // additional stats (best-effort) try { $num_downloads = DB::connection('legacy')->table('artworks_downloads') ->where('date', DB::raw('CURRENT_DATE')) ->where('artwork_id', $row->id) ->count(); } catch (\Throwable $e) { $num_downloads = 0; } try { $monthly_downloads = DB::connection('legacy')->table('monthly_downloads') ->where('fname', $row->id) ->count(); } catch (\Throwable $e) { $monthly_downloads = 0; } try { $num_comments = DB::connection('legacy')->table('artworks_comments') ->where('name', $row->id) ->where('author', '<>', '') ->count(); } catch (\Throwable $e) { $num_comments = 0; } try { $num_favourites = DB::connection('legacy')->table('favourites') ->where('artwork_id', $row->id) ->count(); } catch (\Throwable $e) { $num_favourites = 0; } try { $featured = DB::connection('legacy')->table('featured_works') ->where('rootid', $row->rootid ?? 0) ->where('artwork_id', $row->id) ->orderByDesc('type') ->select('type', 'post_date') ->first(); $featured_type = $featured->type ?? 0; $featured_date = $featured->post_date ?? null; } catch (\Throwable $e) { $featured_type = 0; $featured_date = null; } $page_title = $row->name ?? 'Artwork'; $page_meta_description = strip_tags($row->description ?? ($row->preview ?? '')); $page_meta_keywords = trim(($row->category_name ?? '') . ', artwork'); return [ 'artwork' => $row, 'thumb_file' => $thumb_file, 'thumb_file_300' => $thumb_file_300, 'thumb_600' => $thumb_600, 'shot_name' => $shot_name, 'zoom_name' => $zoom_name, 'num_downloads' => $num_downloads, 'monthly_downloads' => $monthly_downloads, 'num_comments' => $num_comments, 'num_favourites' => $num_favourites, 'featured_type' => $featured_type, 'featured_date' => $featured_date, 'page_title' => $page_title, 'page_meta_description' => $page_meta_description, 'page_meta_keywords' => $page_meta_keywords, ]; } public static function encode($val, $base = 62, $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') { $str = ''; if ($val < 0) return $str; do { $i = $val % $base; $str = $chars[$i] . $str; $val = ($val - $i) / $base; } while ($val > 0); return $str; } private static function fileExtension($filename) { $parts = pathinfo($filename); return $parts['extension'] ?? 'jpg'; } }