, approved_uploads: int} */ public function assess(User $user, ?Artwork $artwork = null): array { if ($user->isAdmin()) { return ['requires_review' => false, 'reasons' => [], 'approved_uploads' => PHP_INT_MAX]; } $approvedUploads = $this->approvedArtworkCount($user, $artwork); $minimumApproved = max(1, (int) config('uploads.moderation.minimum_approved_uploads', 5)); $reasons = []; if ($approvedUploads < $minimumApproved) { $reasons[] = 'insufficient_approved_uploads'; if ($user->email_verified_at === null) { $reasons[] = 'email_not_verified'; } $minimumAgeDays = max(0, (int) config('uploads.moderation.minimum_account_age_days', 7)); if ($user->created_at?->gt(now()->subDays($minimumAgeDays))) { $reasons[] = 'new_account'; } if ((int) ($user->level ?? 1) <= (int) config('uploads.moderation.maximum_untrusted_level', 1)) { $reasons[] = 'low_level'; } if ((int) ($user->bot_risk_score ?? 0) >= (int) config('uploads.moderation.bot_risk_review_threshold', 40)) { $reasons[] = 'bot_risk'; } if ((int) ($user->spam_reports ?? 0) > 0) { $reasons[] = 'spam_reports'; } } if ($artwork && $this->looksPromotional($artwork)) { $reasons[] = 'promotional_content'; } return [ 'requires_review' => $reasons !== [], 'reasons' => array_values(array_unique($reasons)), 'approved_uploads' => $approvedUploads, ]; } private function approvedArtworkCount(User $user, ?Artwork $artwork): int { $query = $user->artworks() ->where('is_approved', true) ->whereNotNull('published_at') ->where(function ($status): void { $status->whereNull('artwork_status') ->orWhereNotIn('artwork_status', ['review', 'rejected', 'scheduled', 'draft']); }) ->where(function ($source): void { $source->whereNull('approval_source') ->orWhere('approval_source', 'moderator'); }); if ($artwork?->exists) { $query->whereKeyNot($artwork->getKey()); } return (int) $query->count(); } private function looksPromotional(Artwork $artwork): bool { $text = strtolower(implode(' ', [ (string) $artwork->title, (string) $artwork->description, (string) $artwork->file_name, ])); foreach ((array) config('uploads.moderation.promotional_patterns', []) as $pattern) { if ($pattern !== '' && str_contains($text, strtolower((string) $pattern))) { return true; } } return (bool) preg_match('/(?:https?:\/\/|www\.|\b[a-z0-9-]+\.(?:com|net|org|io|co)\b)/i', $text); } }