chore: commit current workspace changes

This commit is contained in:
2026-05-02 09:37:14 +02:00
parent 79235133f0
commit caf1464aa5
121 changed files with 485218 additions and 181663 deletions

View File

@@ -148,7 +148,12 @@ class BrowseGalleryController extends \App\Http\Controllers\Controller
$ttl = self::SORT_TTL_MAP[$sort] ?? 300;
$mainCategories = $this->mainCategories();
$rootCategories = $contentType->rootCategories()->orderBy('sort_order')->orderBy('name')->get();
$rootCategories = $contentType->rootCategories()
->with('contentType')
->orderBy('sort_order')
->orderBy('name')
->get();
$rootCategoryLinks = $this->buildCategoryLinkItems($rootCategories, $contentSlug);
$normalizedPath = trim((string) $path, '/');
if ($normalizedPath === '') {
@@ -160,13 +165,14 @@ class BrowseGalleryController extends \App\Http\Controllers\Controller
'sort' => self::SORT_MAP[$sort] ?? ['published_at_ts:desc'],
], $perPage, false, $page)
);
$this->loadGalleryArtworkRelations($artworks->getCollection());
$artworks->getCollection()->transform(fn ($a) => $this->presentArtwork($a));
$seo = $this->buildPaginationSeo($request, url('/' . $contentSlug), $artworks);
return view('gallery.index', [
'gallery_type' => 'content-type',
'mainCategories' => $mainCategories,
'subcategories' => $rootCategories,
'subcategories' => $rootCategoryLinks,
'contentType' => $contentType,
'category' => null,
'artworks' => $artworks,
@@ -194,6 +200,8 @@ class BrowseGalleryController extends \App\Http\Controllers\Controller
abort(404);
}
$this->loadCategoryLineage($category);
$categorySlugs = $this->categoryFilterSlugs($category);
$filterExpression = $this->categoryPageFilterExpression($contentSlug, $categorySlugs);
@@ -205,14 +213,25 @@ class BrowseGalleryController extends \App\Http\Controllers\Controller
'sort' => self::SORT_MAP[$sort] ?? ['published_at_ts:desc'],
], $perPage, false, $page)
);
$this->loadGalleryArtworkRelations($artworks->getCollection());
$artworks->getCollection()->transform(fn ($a) => $this->presentArtwork($a));
$seo = $this->buildPaginationSeo($request, url('/' . $contentSlug . '/' . strtolower($category->full_slug_path)), $artworks);
$navigationCategory = $category->parent ?: $category;
$navigationPath = strtolower($navigationCategory->full_slug_path);
$subcategoryParent = (object) [
'id' => $navigationCategory->id,
'url' => $this->buildCategoryUrl($contentSlug, $navigationPath),
];
$subcategories = $navigationCategory->children()->orderBy('sort_order')->orderBy('name')->get();
$subcategories = $navigationCategory->children()
->with(['contentType', 'parent.contentType'])
->orderBy('sort_order')
->orderBy('name')
->get();
$subcategoryLinks = $this->buildCategoryLinkItems($subcategories, $contentSlug, $navigationPath);
if ($subcategories->isEmpty()) {
$subcategories = $rootCategories;
$subcategoryLinks = $rootCategoryLinks;
}
$breadcrumbs = collect(array_merge([
@@ -235,8 +254,8 @@ class BrowseGalleryController extends \App\Http\Controllers\Controller
return view('gallery.index', [
'gallery_type' => 'category',
'mainCategories' => $mainCategories,
'subcategories' => $subcategories,
'subcategory_parent' => $navigationCategory,
'subcategories' => $subcategoryLinks,
'subcategory_parent' => $subcategoryParent,
'contentType' => $contentType,
'category' => $category,
'artworks' => $artworks,
@@ -303,13 +322,12 @@ class BrowseGalleryController extends \App\Http\Controllers\Controller
$present = ThumbnailPresenter::present($artwork, 'md');
$group = $artwork->group;
$isGroupPublisher = $group !== null;
$avatarHash = $artwork->user?->profile?->avatar_hash ?? null;
$avatarUrl = $isGroupPublisher
? $group->avatarUrl()
: \App\Support\AvatarUrl::forUser(
(int) ($artwork->user_id ?? 0),
$artwork->user?->profile?->avatar_hash ?? null,
64
);
: ($avatarHash !== null
? \App\Support\AvatarUrl::forUser((int) ($artwork->user_id ?? 0), $avatarHash, 64)
: \App\Support\AvatarUrl::default());
$displayName = $isGroupPublisher ? ($group->name ?? 'Skinbase') : ($artwork->user?->name ?? 'Skinbase');
$username = $isGroupPublisher ? '' : ($artwork->user?->username ?? '');
$profileUrl = $isGroupPublisher ? $group->publicUrl() : ($username !== '' ? '/@' . $username : null);
@@ -349,27 +367,74 @@ class BrowseGalleryController extends \App\Http\Controllers\Controller
*/
private function categoryFilterSlugs(Category $category): array
{
$category->loadMissing('descendants');
$slugs = [];
$stack = [$category];
$pendingParentIds = [$category->id];
while ($stack !== []) {
/** @var Category $current */
$current = array_pop($stack);
if (! empty($current->slug)) {
$slugs[] = Str::lower($current->slug);
}
if (! empty($category->slug)) {
$slugs[] = Str::lower($category->slug);
}
foreach ($current->children as $child) {
$child->loadMissing('descendants');
$stack[] = $child;
while ($pendingParentIds !== []) {
$children = Category::query()
->whereIn('parent_id', $pendingParentIds)
->get(['id', 'slug']);
$pendingParentIds = $children->pluck('id')->all();
foreach ($children as $child) {
if (! empty($child->slug)) {
$slugs[] = Str::lower($child->slug);
}
}
}
return array_values(array_unique($slugs));
}
private function loadCategoryLineage(Category $category): void
{
$current = $category;
while ($current !== null) {
$current->loadMissing(['contentType', 'parent']);
$current = $current->parent;
}
}
private function buildCategoryLinkItems(Collection $categories, string $contentSlug, ?string $basePath = null): Collection
{
$normalizedBasePath = trim(strtolower((string) $basePath), '/');
return $categories->map(function (Category $category) use ($contentSlug, $normalizedBasePath) {
return (object) [
'id' => $category->id,
'name' => $category->name,
'slug' => $category->slug,
'url' => $this->buildCategoryUrl($contentSlug, implode('/', array_filter([$normalizedBasePath, $category->slug]))),
];
});
}
private function buildCategoryUrl(string $contentSlug, ?string $path = null): string
{
$normalizedPath = trim(strtolower((string) $path), '/');
return '/' . implode('/', array_filter([$contentSlug, $normalizedPath]));
}
private function loadGalleryArtworkRelations(Collection $artworks): void
{
if ($artworks->isEmpty()) {
return;
}
$artworks->loadMissing([
'user.profile',
'group',
'categories.contentType',
]);
}
private function categoryFilterClause(string $categorySlug): string
{
$quoted = addslashes($categorySlug);