Remove legacy frontend assets and update gallery routes
This commit is contained in:
@@ -80,7 +80,7 @@ final class ArtworkPageController extends Controller
|
||||
}
|
||||
|
||||
// ── Step 2: full load with all relations ───────────────────────────
|
||||
$artwork = Artwork::with(['user.profile', 'categories.contentType', 'categories.parent.contentType', 'tags', 'stats'])
|
||||
$artwork = Artwork::with(['user.profile', 'categories.contentType', 'categories.parent.contentType', 'tags', 'stats', 'awardStat'])
|
||||
->where('id', $id)
|
||||
->public()
|
||||
->published()
|
||||
|
||||
@@ -23,17 +23,27 @@ class ArtworkResource extends JsonResource
|
||||
$canonicalSlug = (string) $this->id;
|
||||
}
|
||||
|
||||
$followerCount = (int) ($this->user?->profile?->followers_count ?? 0);
|
||||
if (($followerCount <= 0) && Schema::hasTable('friends_list') && !empty($this->user?->id)) {
|
||||
$followerCount = (int) DB::table('friends_list')
|
||||
->where('friend_id', (int) $this->user->id)
|
||||
->count();
|
||||
$followerCount = 0;
|
||||
if (!empty($this->user?->id)) {
|
||||
if (Schema::hasTable('user_statistics')) {
|
||||
$followerCount = (int) DB::table('user_statistics')
|
||||
->where('user_id', (int) $this->user->id)
|
||||
->value('followers_count');
|
||||
}
|
||||
|
||||
// Legacy fallback for environments where new tables are unavailable.
|
||||
if (($followerCount <= 0) && Schema::hasTable('friends_list')) {
|
||||
$followerCount = (int) DB::table('friends_list')
|
||||
->where('friend_id', (int) $this->user->id)
|
||||
->count();
|
||||
}
|
||||
}
|
||||
|
||||
$viewerId = (int) optional($request->user())->id;
|
||||
$isLiked = false;
|
||||
$isFavorited = false;
|
||||
$isFollowing = false;
|
||||
$viewerAward = null;
|
||||
|
||||
if ($viewerId > 0) {
|
||||
if (Schema::hasTable('artwork_likes')) {
|
||||
@@ -48,11 +58,26 @@ class ArtworkResource extends JsonResource
|
||||
->where('artwork_id', (int) $this->id)
|
||||
->exists();
|
||||
|
||||
if (Schema::hasTable('friends_list') && !empty($this->user?->id)) {
|
||||
$isFollowing = DB::table('friends_list')
|
||||
if (!empty($this->user?->id)) {
|
||||
if (Schema::hasTable('user_followers')) {
|
||||
$isFollowing = DB::table('user_followers')
|
||||
->where('user_id', (int) $this->user->id)
|
||||
->where('follower_id', $viewerId)
|
||||
->exists();
|
||||
} elseif (Schema::hasTable('friends_list')) {
|
||||
// Legacy fallback only.
|
||||
$isFollowing = DB::table('friends_list')
|
||||
->where('user_id', $viewerId)
|
||||
->where('friend_id', (int) $this->user->id)
|
||||
->exists();
|
||||
}
|
||||
}
|
||||
|
||||
if (Schema::hasTable('artwork_awards')) {
|
||||
$viewerAward = DB::table('artwork_awards')
|
||||
->where('user_id', $viewerId)
|
||||
->where('friend_id', (int) $this->user->id)
|
||||
->exists();
|
||||
->where('artwork_id', (int) $this->id)
|
||||
->value('medal');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +126,13 @@ class ArtworkResource extends JsonResource
|
||||
'favorites' => (int) ($this->stats?->favorites ?? 0),
|
||||
'likes' => (int) ($this->stats?->rating_count ?? 0),
|
||||
],
|
||||
'awards' => [
|
||||
'gold' => (int) ($this->awardStat?->gold_count ?? 0),
|
||||
'silver' => (int) ($this->awardStat?->silver_count ?? 0),
|
||||
'bronze' => (int) ($this->awardStat?->bronze_count ?? 0),
|
||||
'score' => (int) ($this->awardStat?->score_total ?? 0),
|
||||
'viewer_award' => $viewerAward,
|
||||
],
|
||||
'categories' => $this->categories->map(fn ($category) => [
|
||||
'id' => (int) $category->id,
|
||||
'slug' => (string) $category->slug,
|
||||
|
||||
@@ -64,6 +64,8 @@ class AppServiceProvider extends ServiceProvider
|
||||
$this->configureUploadRateLimiters();
|
||||
$this->configureMessagingRateLimiters();
|
||||
$this->configureDownloadRateLimiter();
|
||||
$this->configureArtworkRateLimiters();
|
||||
$this->configureReactionRateLimiters();
|
||||
$this->configureSettingsRateLimiters();
|
||||
$this->configureMailFailureLogging();
|
||||
|
||||
@@ -275,6 +277,44 @@ class AppServiceProvider extends ServiceProvider
|
||||
});
|
||||
}
|
||||
|
||||
private function configureArtworkRateLimiters(): void
|
||||
{
|
||||
RateLimiter::for('artwork-awards', function (Request $request): array {
|
||||
$userId = $request->user()?->id;
|
||||
$artworkId = (int) $request->route('id');
|
||||
|
||||
return [
|
||||
// Prevent burst spam on a single artwork while allowing normal exploration.
|
||||
Limit::perMinute(20)->by('awards:user:' . ($userId ?? 'guest') . ':art:' . $artworkId),
|
||||
// Global safety net for user/IP across all artworks.
|
||||
Limit::perMinute(120)->by('awards:user:' . ($userId ?? 'guest')),
|
||||
Limit::perMinute(180)->by('awards:ip:' . $request->ip()),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
private function configureReactionRateLimiters(): void
|
||||
{
|
||||
RateLimiter::for('reactions-read', function (Request $request): array {
|
||||
$userId = $request->user()?->id;
|
||||
|
||||
return [
|
||||
// Comment-heavy pages can trigger many reaction reads at once.
|
||||
Limit::perMinute(600)->by('reactions-read:user:' . ($userId ?? 'guest')),
|
||||
Limit::perMinute(900)->by('reactions-read:ip:' . $request->ip()),
|
||||
];
|
||||
});
|
||||
|
||||
RateLimiter::for('reactions-write', function (Request $request): array {
|
||||
$userId = $request->user()?->id;
|
||||
|
||||
return [
|
||||
Limit::perMinute(120)->by('reactions-write:user:' . ($userId ?? 'guest')),
|
||||
Limit::perMinute(180)->by('reactions-write:ip:' . $request->ip()),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
private function configureSettingsRateLimiters(): void
|
||||
{
|
||||
RateLimiter::for('username-check', function (Request $request): Limit {
|
||||
|
||||
Reference in New Issue
Block a user