Current state

This commit is contained in:
2026-02-07 08:23:18 +01:00
commit 0a4372c40d
22479 changed files with 1553543 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Services\LegacyService;
class ArtController extends Controller
{
protected LegacyService $legacy;
public function __construct(LegacyService $legacy)
{
$this->legacy = $legacy;
}
public function show(Request $request, $id, $slug = null)
{
// handle comment POST from legacy form
if ($request->isMethod('post') && $request->input('action') === 'store_comment') {
if (auth()->check()) {
try {
\Illuminate\Support\Facades\DB::connection('legacy')->table('artworks_comments')->insert([
'artwork_id' => (int)$id,
'owner_user_id' => (int)($request->user()->id ?? 0),
'user_id' => (int)$request->user()->id,
'date' => now()->toDateString(),
'time' => now()->toTimeString(),
'description' => (string)$request->input('comment_text'),
]);
} catch (\Throwable $e) {
// ignore DB errors for now
}
}
return redirect()->back();
}
$data = $this->legacy->getArtwork((int) $id);
if (! $data || empty($data['artwork'])) {
return view('legacy.placeholder', ['title' => 'Artwork Not Found']);
}
// load comments for artwork (legacy schema)
try {
$comments = \Illuminate\Support\Facades\DB::connection('legacy')->table('artworks_comments as t1')
->rightJoin('users as t2', 't1.user_id', '=', 't2.user_id')
->select('t1.description', 't1.date', 't1.time', 't2.uname', 't2.signature', 't2.icon', 't2.user_id')
->where('t1.artwork_id', (int)$id)
->where('t1.user_id', '>', 0)
->orderBy('t1.comment_id')
->get();
} catch (\Throwable $e) {
$comments = collect();
}
$data['comments'] = $comments;
return view('legacy.art', $data);
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
class AvatarController extends Controller
{
public function show(Request $request, $id, $name = null)
{
$user_id = (int) $id;
// default avatar in project public gfx
$defaultAvatar = public_path('gfx/avatar.jpg');
try {
$icon = DB::connection('legacy')->table('users')->where('user_id', $user_id)->value('icon');
} catch (\Throwable $e) {
$icon = null;
}
$candidates = [];
if (!empty($icon)) {
// common legacy locations to check
$candidates[] = base_path('oldSite/www/files/usericons/' . $icon);
$candidates[] = base_path('oldSite/www/files/usericons/' . rawurlencode($icon));
$candidates[] = base_path('oldSite/www/files/usericons/' . basename($icon));
$candidates[] = public_path('avatar/' . $user_id . '/' . $icon);
$candidates[] = public_path('avatar/' . $user_id . '/' . basename($icon));
$candidates[] = storage_path('app/public/usericons/' . $icon);
$candidates[] = storage_path('app/public/usericons/' . basename($icon));
}
// find first readable file
$found = null;
foreach ($candidates as $path) {
if ($path && file_exists($path) && is_readable($path)) {
$found = $path;
break;
}
}
if ($found) {
$type = @exif_imagetype($found);
if ($type) {
$mime = image_type_to_mime_type($type);
} else {
$f = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($f, $found) ?: 'application/octet-stream';
finfo_close($f);
}
return response()->file($found, ['Content-Type' => $mime]);
}
// fallback to default
if (file_exists($defaultAvatar) && is_readable($defaultAvatar)) {
return response()->file($defaultAvatar, ['Content-Type' => 'image/jpeg']);
}
// final fallback: 404
abort(404);
}
}

View File

@@ -0,0 +1,85 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use App\Models\Artwork;
use App\Services\ArtworkService;
use Illuminate\Http\Request;
use Illuminate\Pagination\CursorPaginator;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
class BrowseController extends Controller
{
protected ArtworkService $artworks;
public function __construct(ArtworkService $artworks)
{
$this->artworks = $artworks;
}
public function index(Request $request)
{
$page_title = 'Browse Uploaded Artworks - Photography, Wallpapers and Skins at SkinBase';
$page_meta_description = "Browse Uploaded Photography, Wallpapers and Skins to one of the world's oldest online social community for artists and art enthusiasts.";
$page_meta_keywords = 'photography, wallpapers, skins, stock, browse, social, community, artist, picture, photo';
$perPage = (int) $request->get('per_page', 24);
$categoryPath = trim((string) $request->query('category', ''), '/');
try {
if ($categoryPath !== '') {
$slugs = array_values(array_filter(explode('/', $categoryPath)));
/** @var CursorPaginator $artworks */
$artworks = $this->artworks->getArtworksByCategoryPath($slugs, $perPage);
} else {
/** @var CursorPaginator $artworks */
$artworks = $this->artworks->browsePublicArtworks($perPage);
}
} catch (ModelNotFoundException $e) {
abort(404);
}
if (count($artworks) === 0) {
Log::warning('browse.missing_artworks', [
'url' => $request->fullUrl(),
'category_path' => $categoryPath ?: null,
]);
abort(410);
}
// Shape data for the legacy Blade while using authoritative tables only.
$artworks->getCollection()->transform(fn (Artwork $artwork) => $this->mapArtwork($artwork));
return view('legacy.browse', compact('page_title', 'page_meta_description', 'page_meta_keywords', 'artworks'));
}
private function mapArtwork(Artwork $artwork): object
{
$primaryCategory = $artwork->categories->sortBy('sort_order')->first();
$categoryPath = $primaryCategory?->full_slug_path;
$contentTypeSlug = $primaryCategory?->contentType?->slug;
$webUrl = $contentTypeSlug && $categoryPath
? '/' . strtolower($contentTypeSlug) . '/' . strtolower($categoryPath) . '/' . $artwork->slug
: null;
$present = \App\Services\ThumbnailPresenter::present($artwork, 'md');
return (object) [
'id' => $artwork->id,
// Include ordering parameter used by cursor paginator so links can be generated
'published_at' => $artwork->published_at?->toAtomString(),
'slug' => $artwork->slug,
'name' => $artwork->title,
'category_name' => $primaryCategory->name ?? '',
'gid_num' => $primaryCategory ? ((int) $primaryCategory->id % 5) * 5 : 0,
'thumb' => $present['url'],
'thumb_srcset' => $present['srcset'] ?? $present['url'],
'uname' => $artwork->user->name ?? 'Skinbase',
'url' => $webUrl ?? '#',
];
}
}

View File

@@ -0,0 +1,108 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Services\ArtworkService;
use App\Models\Category;
use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\ModelNotFoundException;
class CategoryController extends Controller
{
protected ArtworkService $artworkService;
public function __construct(ArtworkService $artworkService)
{
$this->artworkService = $artworkService;
}
public function show(Request $request, $id, $slug = null, $group = null)
{
// Parse request path after '/category' to support unlimited depth and legacy routes
$path = trim($request->path(), '/');
$segments = array_values(array_filter(explode('/', $path)));
// Expecting segments like ['category', '{contentType}', '{...categorySlugs}']
if (count($segments) < 2 || strtolower($segments[0]) !== 'category') {
return view('legacy.placeholder');
}
$parts = array_slice($segments, 1);
// If first part is numeric, attempt id->category resolution and redirect to canonical slug URL
$first = $parts[0] ?? null;
if ($first !== null && ctype_digit((string) $first)) {
try {
$category = Category::findOrFail((int) $first);
$contentTypeSlug = $category->contentType->slug ?? null;
$canonical = '/' . strtolower($contentTypeSlug) . '/' . $category->full_slug_path;
return redirect($canonical, 301);
} catch (ModelNotFoundException $e) {
abort(404);
}
}
// Build slug list: first element is content type slug, rest are category slugs
$contentTypeSlug = array_shift($parts);
$slugs = array_merge([$contentTypeSlug], $parts);
$perPage = (int) $request->get('per_page', 40);
try {
$artworks = $this->artworkService->getArtworksByCategoryPath($slugs, $perPage);
} catch (ModelNotFoundException $e) {
abort(404);
}
// Resolve Category model for page meta and subcategories
// Use the contentType + path traversal to find the category
try {
$category = Category::whereHas('contentType', function ($q) use ($contentTypeSlug) {
$q->where('slug', strtolower($contentTypeSlug));
})->whereNull('parent_id')->where('slug', strtolower($parts[0] ?? ''))->first();
// If deeper path exists, traverse
if ($category && count($parts) > 1) {
$cur = $category;
foreach (array_slice($parts, 1) as $slugPart) {
$cur = $cur->children()->where('slug', strtolower($slugPart))->first();
if (! $cur) {
abort(404);
}
}
$category = $cur;
}
} catch (\Throwable $e) {
$category = null;
}
if (! $category) {
// Category resolution failed
abort(404);
}
$subcategories = $category->children()->orderBy('sort_order')->orderBy('name')->get();
$page_title = $category->name;
$page_meta_description = $category->description ?? ($category->contentType->name . ' artworks on Skinbase');
$page_meta_keywords = strtolower($category->contentType->slug) . ', skinbase, artworks, wallpapers, skins, photography';
return view('legacy.category', compact(
'page_title',
'page_meta_description',
'page_meta_keywords',
'group',
'category',
'subcategories',
'artworks'
));
}
public function browseCategories()
{
$data = $this->legacy->browseCategories();
return view('legacy.categories', $data);
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class ChatController extends Controller
{
public function index(Request $request)
{
$page_title = 'Online Chat';
// Handle post (store chat)
$store = $request->input('store_chat');
$chat_text = $request->input('chat_txt');
$chat = new \App\Chat();
if (!empty($store) && $store === 'true' && !empty($chat_text)) {
if (!empty($_SESSION['web_login']['status'])) {
$chat->StoreMessage($chat_text);
$chat->UpdateChatFile('cron/chat_log.txt', 10);
}
}
// Capture Banner output
ob_start();
\App\Banner::ShowResponsiveAd();
$adHtml = ob_get_clean();
// Capture Chat HTML
ob_start();
$userID = $_SESSION['web_login']['user_id'] ?? null;
$chat->ShowChat(50, $userID);
$chatHtml = ob_get_clean();
// Load smileys from legacy DB
try {
$smileys = DB::connection('legacy')->table('smileys')->select('code', 'picture', 'emotion')->get();
} catch (\Throwable $e) {
$smileys = collect();
}
return view('legacy.chat', compact('page_title', 'adHtml', 'chatHtml', 'smileys'));
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use App\Models\Artwork;
use App\Services\ArtworkService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class DailyUploadsController extends Controller
{
protected ArtworkService $artworks;
public function __construct(ArtworkService $artworks)
{
$this->artworks = $artworks;
}
public function index(Request $request)
{
$isAjax = $request->boolean('ajax');
$datum = $request->query('datum');
if ($isAjax && $datum) {
// Return partial gallery for the given date
$arts = $this->fetchByDate($datum);
return view('legacy.partials.daily-uploads-grid', ['arts' => $arts])->render();
}
// Build date tabs (today .. -14 days)
$dates = [];
for ($x = 0; $x > -15; $x--) {
$ts = strtotime(sprintf('%+d days', $x));
$dates[] = [
'iso' => date('Y-m-d', $ts),
'label' => date('d. F Y', $ts),
];
}
// initial content: recent (last 7 days)
$recent = $this->fetchRecent();
return view('legacy.daily-uploads', [
'dates' => $dates,
'recent' => $recent,
'page_title' => 'Daily Uploads',
]);
}
private function fetchByDate(string $date)
{
$ars = Artwork::public()
->published()
->whereDate('published_at', $date)
->orderByDesc('published_at')
->with(['user:id,name', 'categories' => function ($q) {
$q->select('categories.id', 'categories.name', 'categories.sort_order');
}])
->get();
return $this->prepareArts($ars);
}
private function fetchRecent()
{
$start = now()->subDays(7)->startOfDay();
$ars = Artwork::public()
->published()
->where('published_at', '>=', $start)
->orderByDesc('published_at')
->with(['user:id,name', 'categories' => function ($q) {
$q->select('categories.id', 'categories.name', 'categories.sort_order');
}])
->get();
return $this->prepareArts($ars);
}
private function prepareArts($ars)
{
return $ars->map(function (Artwork $ar) {
$primaryCategory = $ar->categories->sortBy('sort_order')->first();
$present = \App\Services\ThumbnailPresenter::present($ar, 'md');
return (object) [
'id' => $ar->id,
'name' => $ar->title,
'thumb' => $present['url'],
'thumb_srcset' => $present['srcset'] ?? $present['url'],
'gid_num' => $primaryCategory ? ((int) $primaryCategory->id % 5) * 5 : 0,
'category_name' => $primaryCategory->name ?? '',
'uname' => $ar->user->name ?? 'Skinbase',
];
});
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use App\Models\Artwork;
use App\Services\ArtworkService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class FeaturedArtworksController extends Controller
{
protected ArtworkService $artworks;
public function __construct(ArtworkService $artworks)
{
$this->artworks = $artworks;
}
public function index(Request $request)
{
$perPage = 39;
$type = (int) ($request->query('type', 4));
$typeFilter = $type === 4 ? null : $type;
$artworks = $this->artworks->getFeaturedArtworks($typeFilter, $perPage);
$artworks->getCollection()->transform(function (Artwork $artwork) {
$primaryCategory = $artwork->categories->sortBy('sort_order')->first();
$categoryName = $primaryCategory->name ?? '';
$gid = $primaryCategory ? ((int) $primaryCategory->id % 5) * 5 : 0;
$present = \App\Services\ThumbnailPresenter::present($artwork, 'md');
return (object) [
'id' => $artwork->id,
'name' => $artwork->title,
'category_name' => $categoryName,
'gid_num' => $gid,
'thumb_url' => $present['url'],
'thumb_srcset' => $present['srcset'] ?? $present['url'],
'uname' => $artwork->user->name ?? 'Skinbase',
];
});
$artworkTypes = [
1 => 'Bronze Awards',
2 => 'Silver Awards',
3 => 'Gold Awards',
4 => 'Featured Artworks',
];
$pageTitle = $artworkTypes[$type] ?? 'Featured Artworks';
return view('legacy.featured-artworks', [
'artworks' => $artworks,
'type' => $type,
'artworkTypes' => $artworkTypes,
'page_title' => $pageTitle,
]);
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Services\LegacyService;
class ForumController extends Controller
{
protected LegacyService $legacy;
public function __construct(LegacyService $legacy)
{
$this->legacy = $legacy;
}
public function index()
{
$data = $this->legacy->forumIndex();
return view('legacy.forum.index', $data);
}
public function topic(Request $request, $topic_id)
{
$data = $this->legacy->forumTopic((int) $topic_id, (int) $request->query('page', 1));
if (! $data) {
return view('legacy.placeholder');
}
if (isset($data['type']) && $data['type'] === 'subtopics') {
return view('legacy.forum.topic', $data);
}
return view('legacy.forum.posts', $data);
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Services\ArtworkService;
class HomeController extends Controller
{
protected ArtworkService $artworks;
public function __construct(ArtworkService $artworks)
{
$this->artworks = $artworks;
}
public function index(Request $request)
{
$page_title = 'Skinbase - Photography, Skins & Wallpapers';
$page_meta_description = 'Skinbase legacy home, rendered via Laravel.';
$page_meta_keywords = 'wallpapers, skins, photography, community';
// Use new ArtworkService as primary data source
$featuredResult = $this->artworks->getFeaturedArtworks(null, 39);
// If service returned a paginator, extract the first model for the single "featured" slot
if ($featuredResult instanceof \Illuminate\Pagination\LengthAwarePaginator) {
$featured = $featuredResult->getCollection()->first();
} elseif (is_array($featuredResult)) {
$featured = $featuredResult[0] ?? null;
} else {
// Collection or single item
$featured = method_exists($featuredResult, 'first') ? $featuredResult->first() : $featuredResult;
}
// Provide a memberFeatured fallback so the legacy view always has a value
$memberFeatured = $featured;
$latestUploads = $this->artworks->getLatestArtworks(20);
// Legacy forum/news data not available in new services yet — provide empty defaults
$forumNews = [];
$ourNews = [];
$latestForumActivity = [];
return view('legacy.home', compact(
'page_title',
'page_meta_description',
'page_meta_keywords',
'featured',
'memberFeatured',
'latestUploads',
'forumNews',
'ourNews',
'latestForumActivity'
));
}
}

View File

@@ -0,0 +1,106 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class InterviewController extends Controller
{
public function show(Request $request, $id, $slug = null)
{
$id = (int) $id;
// Handle comment POST
if ($request->isMethod('post')) {
$action = $request->input('action');
if ($action === 'store' && (!empty($_SESSION['web_login']['user_type']) && $_SESSION['web_login']['user_type'] > 1)) {
$comment = $request->input('comment');
$tekst = nl2br(htmlspecialchars($comment ?? '', ENT_QUOTES, 'UTF-8'));
$interviewId = (int) $request->input('interview_id');
try {
DB::connection('legacy')->table('interviews_comment')->insert([
'nid' => $interviewId,
'author' => $_SESSION['web_login']['username'] ?? 'Anonymous',
'datum' => DB::raw('CURRENT_TIMESTAMP'),
'tekst' => $tekst,
]);
$ar2 = DB::connection('legacy')->table('users')
->where('uname', $_SESSION['web_login']['username'])
->first();
if (!empty($ar2->user_id)) {
DB::connection('legacy')->table('users_statistics')
->where('user_id', $ar2->user_id)
->increment('newscomment');
}
} catch (\Throwable $e) {
// fail silently
}
}
}
try {
$ar = DB::connection('legacy')->table('interviews')->where('id', $id)->first();
} catch (\Throwable $e) {
$ar = null;
}
if (! $ar) {
return redirect('/interviews');
}
try {
$artworks = DB::connection('legacy')->table('wallz')
->where('uname', $ar->username)
->inRandomOrder()
->limit(2)
->get();
} catch (\Throwable $e) {
$artworks = collect();
}
try {
$comments = DB::connection('legacy')->table('interviews_comment as c')
->leftJoin('users as u', 'u.uname', '=', 'c.author')
->where('c.nid', $id)
->select('c.*', 'u.user_id', 'u.user_type', 'u.signature', 'u.icon')
->orderBy('c.datum')
->get();
} catch (\Throwable $e) {
$comments = collect();
}
// compute total posts per author across interviews_comment
$authors = $comments->pluck('author')->unique()->values()->all();
$postCounts = [];
if (!empty($authors)) {
try {
$counts = DB::connection('legacy')->table('interviews_comment')
->select('author', DB::raw('COUNT(*) as cnt'))
->whereIn('author', $authors)
->groupBy('author')
->get();
foreach ($counts as $c) {
$postCounts[$c->author] = $c->cnt;
}
} catch (\Throwable $e) {
// ignore
}
}
$page_title = 'Interview with ' . ($ar->username ?? '');
return view('legacy.interview', [
'ar' => $ar,
'artworks' => $artworks,
'comments' => $comments,
'postCounts' => $postCounts,
'page_title' => $page_title,
]);
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class InterviewsController extends Controller
{
public function index(Request $request)
{
try {
$interviews = DB::connection('legacy')->table('interviews AS t1')
->select('t1.id', 't1.headline', 't2.user_id', 't2.uname', 't2.icon')
->leftJoin('users AS t2', 't1.username', '=', 't2.uname')
->orderByDesc('t1.datum')
->limit(60)
->get();
} catch (\Throwable $e) {
$interviews = collect();
}
$page_title = 'Interviews';
return view('legacy.interviews', compact('interviews', 'page_title'));
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\ArtworkComment;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
class LatestCommentsController extends Controller
{
public function index(Request $request)
{
$hits = 20;
// Join artwork_comments -> artwork -> user, but only include artworks that are public, approved and published
$query = ArtworkComment::with(['user', 'artwork'])
->whereHas('artwork', function ($q) {
$q->public()->published()->whereNull('deleted_at');
})
->orderByDesc('created_at');
$comments = $query->paginate($hits)->withQueryString();
// Shape results for legacy view
$comments->getCollection()->transform(function (ArtworkComment $c) {
$art = $c->artwork;
$user = $c->user;
$present = $art ? \App\Services\ThumbnailPresenter::present($art, 'md') : null;
$thumb = $present ? ($present['url']) : '/gfx/sb_join.jpg';
return (object) [
'comment_id' => $c->getKey(),
'comment_description' => $c->content,
'commenter_id' => $c->user_id,
'country' => $user->country ?? null,
'icon' => $user->avatar ?? null,
'uname' => $user->username ?? $user->name ?? 'User',
'signature' => $user->signature ?? null,
'user_type' => $user->role ?? null,
'id' => $art->id ?? null,
'name' => $art->title ?? null,
'picture' => $art->file_name ?? null,
'thumb' => $thumb,
'artwork_slug' => $art->slug ?? Str::slug($art->title ?? ''),
'datetime' => $c->created_at?->toDateTimeString() ?? now()->toDateTimeString(),
];
});
$page_title = 'Latest Comments';
return view('legacy.latest-comments', compact('page_title', 'comments'));
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use App\Models\Artwork;
use App\Services\ArtworkService;
use Illuminate\Http\Request;
use Illuminate\Pagination\CursorPaginator;
use Illuminate\Support\Facades\Storage;
class LatestController extends Controller
{
protected ArtworkService $artworks;
public function __construct(ArtworkService $artworks)
{
$this->artworks = $artworks;
}
public function index(Request $request)
{
$perPage = 21;
/** @var CursorPaginator $artworks */
$artworks = $this->artworks->browsePublicArtworks($perPage);
// Shape data for legacy view without legacy tables.
$artworks->getCollection()->transform(function (Artwork $artwork) {
$primaryCategory = $artwork->categories->sortBy('sort_order')->first();
$categoryName = $primaryCategory->name ?? '';
$gid = $primaryCategory ? ((int) $primaryCategory->id % 5) * 5 : 0;
$present = \App\Services\ThumbnailPresenter::present($artwork, 'md');
return (object) [
'id' => $artwork->id,
'name' => $artwork->title,
'category_name' => $categoryName,
'gid_num' => $gid,
'thumb_url' => $present['url'],
'thumb_srcset' => $present['srcset'] ?? $present['url'],
'uname' => $artwork->user->name ?? 'Skinbase',
];
});
return view('legacy.latest-artworks', [
'artworks' => $artworks,
'page_title' => 'Latest Artworks',
]);
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Services\LegacyService;
use Illuminate\Support\Str;
class MembersController extends Controller
{
protected LegacyService $legacy;
public function __construct(LegacyService $legacy)
{
$this->legacy = $legacy;
}
public function photos(Request $request, $id = null)
{
$id = (int) ($id ?: 545);
$result = $this->legacy->categoryPage('', null, $id);
if (! $result) {
return redirect('/');
}
// categoryPage returns an array with keys used by legacy.browse
$page_title = $result['page_title'] ?? ($result['category']->category_name ?? 'Members Photos');
$artworks = $result['artworks'] ?? collect();
// Ensure artworks include `slug`, `thumb`, and `thumb_srcset` properties expected by the legacy view
if ($artworks && method_exists($artworks, 'getCollection')) {
$artworks->getCollection()->transform(function ($row) {
$row->slug = $row->slug ?? Str::slug($row->name ?? '');
$row->thumb = $row->thumb ?? ($row->thumb_url ?? null);
$row->thumb_srcset = $row->thumb_srcset ?? ($row->thumb_srcset ?? null);
return $row;
});
} elseif (is_iterable($artworks)) {
$artworks = collect($artworks)->map(function ($row) {
$row->slug = $row->slug ?? Str::slug($row->name ?? '');
$row->thumb = $row->thumb ?? ($row->thumb_url ?? null);
$row->thumb_srcset = $row->thumb_srcset ?? ($row->thumb_srcset ?? null);
return $row;
});
}
return view('legacy.browse', compact('page_title', 'artworks'));
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class MonthlyCommentatorsController extends Controller
{
public function index(Request $request)
{
$hits = 30;
$page = max(1, (int) $request->query('page', 1));
$query = DB::connection('legacy')->table('artworks_comments as t1')
->leftJoin('users as t2', 't1.user_id', '=', 't2.user_id')
->leftJoin('country as c', 't2.country', '=', 'c.id')
->where('t1.user_id', '>', 0)
->whereRaw("DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= t1.date")
->select(
't2.user_id',
't2.uname',
't2.user_type',
't2.country',
'c.name as country_name',
'c.flag as country_flag',
DB::raw('COUNT(*) as num_comments')
)
->groupBy('t1.user_id')
->orderByDesc('num_comments');
$rows = $query->paginate($hits)->withQueryString();
$page_title = 'Monthly Top Commentators';
return view('legacy.monthly-commentators', compact('page_title', 'rows'));
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class NewsController extends Controller
{
public function show(Request $request, $id, $slug = null)
{
$id = (int) $id;
try {
$news = DB::connection('legacy')->table('news as t1')
->leftJoin('users as t2', 't1.user_id', '=', 't2.user_id')
->where('t1.news_id', $id)
->select('t1.*', 't2.uname', 't2.user_type', 't2.signature', 't2.icon')
->first();
} catch (\Throwable $e) {
$news = null;
}
if (empty($news)) {
return redirect('/');
}
try {
$comments = DB::connection('legacy')->table('news_comment as c')
->leftJoin('users as u', 'c.user_id', '=', 'u.user_id')
->where('c.news_id', $id)
->select('c.posted', 'c.message', 'c.user_id', 'u.user_type', 'u.signature', 'u.icon', 'u.uname')
->orderBy('c.posted')
->get();
} catch (\Throwable $e) {
$comments = collect();
}
$page_title = ($news->headline ?? 'News') . ' - SkinBase News';
return view('legacy.news', compact('news', 'comments', 'page_title'));
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use App\Services\ArtworkService;
use App\Models\User;
use App\Models\Artwork;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Auth;
class ProfileController extends Controller
{
protected ArtworkService $artworkService;
public function __construct(ArtworkService $artworkService)
{
$this->artworkService = $artworkService;
}
public function show(Request $request, ?int $id = null, ?string $slug = null)
{
// Support /profile (current user) and /profile/{id}/{slug}
$id = $id ?? (Auth::check() ? Auth::id() : null);
if (! $id) {
abort(404);
}
$user = User::find($id);
if (! $user) {
abort(404);
}
// Determine visibility: owner sees all, others only public+approved+published
$isOwner = Auth::check() && Auth::id() === $user->id;
$perPage = 24;
// Use ArtworkService to fetch artworks for the profile
$artworks = $this->artworkService->getArtworksByUser($user->id, $isOwner, $perPage);
// Shape data for legacy view expectations
$artworks->getCollection()->transform(function (Artwork $art) {
$present = \App\Services\ThumbnailPresenter::present($art, 'md');
return (object) [
'id' => $art->id,
'name' => $art->title,
'picture' => $art->file_name,
'datum' => $art->published_at,
'thumb' => $present['url'],
'thumb_srcset' => $present['srcset'] ?? $present['url'],
'uname' => $art->user->name ?? 'Skinbase',
];
});
// Map new User model to legacy view shape expected by templates
$legacyUser = (object) [
'user_id' => $user->id,
'uname' => $user->name,
'real_name' => $user->name,
'icon' => $user->avatar ?? null,
'about_me' => $user->bio ?? null,
];
return view('legacy.profile', [
'user' => $legacyUser,
'artworks' => $artworks,
]);
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\ArtworkDownload;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Carbon\Carbon;
class TodayDownloadsController extends Controller
{
public function index(Request $request)
{
$hits = 30;
// Filter downloads created today and join to artworks that are public, approved and published
$today = Carbon::now()->toDateString();
$query = ArtworkDownload::with(['artwork'])
->whereDate('created_at', $today)
->whereHas('artwork', function ($q) {
$q->public()->published()->whereNull('deleted_at');
})
->selectRaw('artwork_id, COUNT(*) as num_downloads')
->groupBy('artwork_id')
->orderByDesc('num_downloads');
$paginator = $query->paginate($hits)->withQueryString();
// Map to the legacy browse shape
$paginator->getCollection()->transform(function ($row) {
// $row is a stdClass with artwork_id and num_downloads
$art = $row->artwork ?? null;
// If Eloquent didn't eager load artwork (group queries sometimes don't), fetch it
if (! $art && isset($row->artwork_id)) {
$art = \App\Models\Artwork::find($row->artwork_id);
}
$name = $art->title ?? null;
$picture = $art->file_name ?? null;
$ext = pathinfo($picture ?? '', PATHINFO_EXTENSION) ?: 'jpg';
$encoded = null; // legacy encoding unavailable; leave null
$present = $art ? \App\Services\ThumbnailPresenter::present($art, 'md') : null;
$thumb = $present ? $present['url'] : '/gfx/sb_join.jpg';
$categoryId = $art->categories->first()->id ?? null;
return (object) [
'id' => $art->id ?? null,
'name' => $name,
'picture' => $picture,
'slug' => $art->slug ?? Str::slug($name ?? ''),
'ext' => $ext,
'encoded' => $encoded,
'thumb' => $thumb,
'thumb_srcset' => $thumb,
'category' => $categoryId,
'num_downloads' => $row->num_downloads ?? 0,
'gid_num' => $categoryId ? ((int) $categoryId % 5) * 5 : 0,
];
});
$page_title = 'Today Downloaded Artworks';
return view('legacy.browse', ['page_title' => $page_title, 'artworks' => $paginator]);
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class TodayInHistoryController extends Controller
{
public function index(Request $request)
{
$hits = 39;
try {
$base = DB::connection('legacy')->table('featured_works as t0')
->leftJoin('artworks as t1', 't0.artwork_id', '=', 't1.id')
->join('artworks_categories as t2', 't1.category', '=', 't2.category_id')
->where('t1.approved', 1)
->whereRaw('MONTH(t0.post_date) = MONTH(CURRENT_DATE())')
->whereRaw('DAY(t0.post_date) = DAY(CURRENT_DATE())')
->select('t1.id', 't1.name', 't1.picture', 't1.uname', 't1.category', 't2.category_name');
$artworks = $base->orderBy('t0.post_date','desc')->paginate($hits);
} catch (\Throwable $e) {
$artworks = null;
}
if ($artworks && method_exists($artworks, 'getCollection')) {
$artworks->getCollection()->transform(function ($row) {
$row->ext = pathinfo($row->picture ?? '', PATHINFO_EXTENSION) ?: 'jpg';
$row->encoded = \App\Services\LegacyService::encode($row->id);
// Prefer new CDN when artwork exists with hash
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'];
}
$row->gid_num = ((int)($row->category ?? 0) % 5) * 5;
return $row;
});
}
return view('legacy.today-in-history', [
'artworks' => $artworks,
'page_title' => 'Popular on this day in history',
]);
}
}

View File

@@ -0,0 +1,129 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\Artwork;
use App\Models\ArtworkStats;
use App\Models\User;
class TopAuthorsController extends Controller
{
public function index(Request $request)
{
$perPage = 20;
$metric = strtolower($request->query('metric', 'views'));
if (! in_array($metric, ['views', 'downloads'])) {
$metric = 'views';
}
// Aggregate artwork_stats grouped by artwork.user_id, filtering only public+approved+published artworks
$sub = Artwork::query()
->select('artworks.user_id')
->join('artwork_stats', 'artwork_stats.artwork_id', '=', 'artworks.id')
->where('artworks.is_public', true)
->where('artworks.is_approved', true)
->whereNotNull('artworks.published_at')
->where('artworks.published_at', '<=', now())
->whereNull('artworks.deleted_at')
->selectRaw('artworks.user_id, SUM(artwork_stats.' . $metric . ') as total_metric, MAX(artworks.published_at) as latest_published')
->groupBy('artworks.user_id');
// Join with users to fetch profile info
$query = DB::table(DB::raw('(' . $sub->toSql() . ') as t'))
->mergeBindings($sub->getQuery())
->join('users as u', 'u.id', '=', 't.user_id')
->select('u.id as user_id', 'u.name as uname', 'u.username', 't.total_metric', 't.latest_published')
->orderByDesc('t.total_metric')
->orderByDesc('t.latest_published');
$authors = $query->paginate($perPage)->withQueryString();
// Map to legacy view shape
$authors->getCollection()->transform(function ($row) use ($metric) {
return (object) [
'user_id' => $row->user_id,
'uname' => $row->uname,
'username' => $row->username,
'total' => (int) $row->total_metric,
'metric' => $metric,
];
});
$page_title = 'Top Authors';
return view('legacy.top-authors', compact('page_title', 'authors', 'metric'));
}
}
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class TopAuthorsController extends Controller
{
public function index(Request $request)
{
// Top users (most active)
try {
$topUsers = DB::connection('legacy')->table('wallz as t1')
->leftJoin('users as t2', 't1.user_id', '=', 't2.user_id')
->select('t2.user_id', 't2.uname', 't2.icon', DB::raw('SUM(t1.dls) AS total_downloads'), DB::raw('COUNT(*) AS uploads'))
->groupBy('t1.user_id')
->orderByDesc('total_downloads')
->limit(23)
->get();
} catch (\Throwable $e) {
$topUsers = collect();
}
// Top followers
try {
$topFollowers = DB::connection('legacy')->table('friends_list as t1')
->rightJoin('users as t2', 't1.friend_id', '=', 't2.user_id')
->where('t1.friend_id', '>', 0)
->select('t2.uname', 't2.user_id', DB::raw('COUNT(*) as num'))
->groupBy('t1.friend_id')
->orderByDesc('num')
->limit(10)
->get();
} catch (\Throwable $e) {
$topFollowers = collect();
}
// Top commentators
try {
$topCommentators = DB::connection('legacy')->table('artworks_comments as t1')
->join('users as t2', 't1.user_id', '=', 't2.user_id')
->where('t1.user_id', '>', 0)
->select('t2.user_id','t2.uname','t2.user_type','t2.country', DB::raw('COUNT(*) as num_comments'))
->groupBy('t1.user_id')
->orderByDesc('num_comments')
->limit(10)
->get();
// enrich with country info if available
$topCommentators->transform(function ($c) {
if (!empty($c->country)) {
$cn = DB::connection('legacy')->table('country')->select('name','flag')->where('id', $c->country)->first();
$c->country_name = $cn->name ?? null;
$c->country_flag = $cn->flag ?? null;
} else {
$c->country_name = null;
$c->country_flag = null;
}
return $c;
});
} catch (\Throwable $e) {
$topCommentators = collect();
}
return view('legacy.top-authors', compact('topUsers', 'topFollowers', 'topCommentators'));
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace App\Http\Controllers\Legacy;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use App\Services\LegacyService;
class TopFavouritesController extends Controller
{
public function index(Request $request)
{
$hits = 21;
$page = max(1, (int) $request->query('page', 1));
$base = DB::connection('legacy')->table('artworks_favourites as t1')
->rightJoin('wallz as t2', 't1.artwork_id', '=', 't2.id')
->where('t2.approved', 1)
->select('t2.id', 't2.name', 't2.picture', 't2.category', DB::raw('COUNT(*) as num'))
->groupBy('t1.artwork_id');
try {
$paginator = (clone $base)->orderBy('num', 'desc')->paginate($hits)->withQueryString();
} catch (\Throwable $e) {
$paginator = collect();
}
// Map artworks to include expected properties for legacy card view
if ($paginator && method_exists($paginator, 'getCollection')) {
$paginator->getCollection()->transform(function ($row) {
$row->slug = $row->slug ?? Str::slug($row->name ?? '');
$ext = pathinfo($row->picture ?? '', PATHINFO_EXTENSION) ?: 'jpg';
$encoded = \App\Helpers\Thumb::encodeId((int) $row->id);
$row->encoded = $encoded;
$row->ext = $ext;
try {
$art = \App\Models\Artwork::find($row->id);
$present = \App\Services\ThumbnailPresenter::present($art ?: (array) $row, 'md');
$row->thumb = $row->thumb ?? $present['url'];
$row->thumb_srcset = $row->thumb_srcset ?? ($present['srcset'] ?? $present['url']);
} catch (\Throwable $e) {
$present = \App\Services\ThumbnailPresenter::present((array) $row, 'md');
$row->thumb = $row->thumb ?? $present['url'];
$row->thumb_srcset = $row->thumb_srcset ?? ($present['srcset'] ?? $present['url']);
}
$row->gid_num = ((int)($row->category ?? 0) % 5) * 5;
return $row;
});
}
$page_title = 'Top Favourites';
return view('legacy.top-favourites', ['page_title' => $page_title, 'artworks' => $paginator]);
}
}