Save workspace changes

This commit is contained in:
2026-04-18 17:02:56 +02:00
parent f02ea9a711
commit 87d60af5a9
4220 changed files with 1388603 additions and 1554 deletions

View File

@@ -5,6 +5,7 @@ use App\Services\Maturity\ArtworkMaturityService;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Http\Resources\MissingValue;
use App\Services\ThumbnailService;
use Illuminate\Support\Str;
class ArtworkListResource extends JsonResource
{
@@ -53,12 +54,16 @@ class ArtworkListResource extends JsonResource
$slugVal = $get('slug');
$hash = (string) ($get('hash') ?? '');
$thumbExt = (string) ($get('thumb_ext') ?? '');
$canonicalSlug = Str::slug((string) ($slugVal ?: $get('title') ?: 'artwork'));
if ($canonicalSlug === '') {
$canonicalSlug = (string) ($get('id') ?? 'artwork');
}
$webUrl = $contentTypeSlug && $categoryPath && $slugVal
? '/' . strtolower($contentTypeSlug) . '/' . strtolower($categoryPath) . '/' . $slugVal
: null;
$artId = $get('id');
$directUrl = $artId && $slugVal ? '/art/' . $artId . '/' . $slugVal : null;
$directUrl = $artId ? '/art/' . $artId . '/' . $canonicalSlug : null;
$decode = static fn (?string $v): string => html_entity_decode((string) ($v ?? ''), ENT_QUOTES | ENT_HTML5, 'UTF-8');
@@ -102,10 +107,11 @@ class ArtworkListResource extends JsonResource
'content_type_name' => $decode($contentTypeName),
'url' => $webUrl,
] : null,
'canonical_url' => $directUrl,
'urls' => [
'web' => $webUrl ?? $directUrl,
'direct' => $directUrl,
'canonical' => $webUrl ?? $directUrl,
'canonical' => $directUrl ?? $webUrl,
],
], $this->resource, $request->user());
}

View File

@@ -1,6 +1,8 @@
<?php
namespace App\Http\Resources;
use App\Models\WorldRelation;
use App\Models\WorldSubmission;
use App\Services\ArtworkEvolutionService;
use App\Services\ContentSanitizer;
use App\Services\Maturity\ArtworkMaturityService;
@@ -16,7 +18,7 @@ class ArtworkResource extends JsonResource
*/
public function toArray($request): array
{
$this->resource->loadMissing(['group', 'uploadedBy.profile', 'primaryAuthor.profile', 'contributors.user.profile']);
$this->resource->loadMissing(['group', 'uploadedBy.profile', 'primaryAuthor.profile', 'contributors.user.profile', 'worldSubmissions.world']);
$md = ThumbnailPresenter::present($this->resource, 'md');
$lg = ThumbnailPresenter::present($this->resource, 'lg');
@@ -52,6 +54,7 @@ class ArtworkResource extends JsonResource
$isFollowing = false;
$isFollowingGroup = false;
$viewerAward = null;
$isOwner = $viewerId > 0 && $viewerId === (int) ($this->user?->id ?? 0);
$bookmarksCount = Schema::hasTable('artwork_bookmarks')
? (int) DB::table('artwork_bookmarks')->where('artwork_id', (int) $this->id)->count()
@@ -213,8 +216,12 @@ class ArtworkResource extends JsonResource
'is_following_group' => $isFollowingGroup,
'is_following_publisher' => $publisher['type'] === 'group' ? $isFollowingGroup : $isFollowing,
'is_authenticated' => $viewerId > 0,
'is_owner' => $isOwner,
'id' => $viewerId > 0 ? $viewerId : null,
],
'management' => [
'analytics_url' => $isOwner ? route('studio.artworks.analytics', ['id' => (int) $this->id]) : null,
],
'stats' => [
'bookmarks' => $bookmarksCount,
'views' => (int) ($this->stats?->views ?? 0),
@@ -245,6 +252,7 @@ class ArtworkResource extends JsonResource
],
'maturity' => app(ArtworkMaturityService::class)->presentation($this->resource, $request->user()),
'evolution' => app(ArtworkEvolutionService::class)->publicPayload($this->resource, $request->user()),
'world_participation' => $this->resolveWorldParticipation(),
'categories' => $this->categories->map(fn ($category) => [
'id' => (int) $category->id,
'slug' => (string) $category->slug,
@@ -324,6 +332,77 @@ class ArtworkResource extends JsonResource
return ContentSanitizer::render($rawDescription);
}
private function resolveWorldParticipation(): array
{
$items = collect();
if (Schema::hasTable('world_relations') && Schema::hasTable('worlds')) {
$items = $items->concat(
WorldRelation::query()
->with('world')
->where('related_type', WorldRelation::TYPE_ARTWORK)
->where('related_id', (int) $this->id)
->get()
->filter(fn (WorldRelation $relation): bool => $relation->world !== null && $relation->world->isPubliclyVisible())
->map(function (WorldRelation $relation): array {
$world = $relation->world;
return [
'world_id' => (int) $relation->world_id,
'world_title' => (string) $world->title,
'world_slug' => (string) $world->slug,
'world_url' => $world->publicUrl(),
'badge_label' => 'Part of ' . $world->title,
'status' => 'curated',
'status_label' => 'Curated',
'tone' => 'curated',
'sort_priority' => 1,
];
})
);
}
if (Schema::hasTable('world_submissions')) {
$items = $items->concat(
$this->worldSubmissions
->filter(function (WorldSubmission $submission): bool {
return (string) $submission->status === WorldSubmission::STATUS_LIVE
&& $submission->world !== null
&& $submission->world->isPubliclyVisible();
})
->map(function (WorldSubmission $submission): array {
$world = $submission->world;
$isFeatured = (bool) $submission->is_featured;
return [
'world_id' => (int) $submission->world_id,
'world_title' => (string) $world->title,
'world_slug' => (string) $world->slug,
'world_url' => $world->publicUrl(),
'badge_label' => ($isFeatured ? 'Featured in ' : 'Part of ') . $world->title,
'status' => (string) $submission->status,
'status_label' => $isFeatured ? 'Featured' : 'Community submission',
'tone' => $isFeatured ? 'featured' : 'community',
'sort_priority' => $isFeatured ? 0 : 2,
];
})
);
}
return $items
->sortBy('sort_priority')
->groupBy('world_id')
->map(function ($group): array {
$item = $group->first();
unset($item['sort_priority']);
return $item;
})
->sortBy(fn (array $item): string => strtolower((string) $item['world_title']))
->values()
->all();
}
private function authorCanPublishLinks(): bool
{
$level = (int) ($this->user?->level ?? 1);