ArtworkComment::query() ->with('artwork:id,title,slug,user_id') ->whereNull('deleted_at') ->where(function (EloquentBuilder $query): void { $query->whereNotNull('raw_content')->where('raw_content', '!=', '') ->orWhere(function (EloquentBuilder $fallback): void { $fallback->whereNotNull('content')->where('content', '!=', ''); }); }) ->orderBy('id'), ModerationContentType::ArtworkDescription => Artwork::query() ->whereNotNull('description') ->where('description', '!=', '') ->orderBy('id'), ModerationContentType::ArtworkTitle => Artwork::query() ->whereNotNull('title') ->where('title', '!=', '') ->orderBy('id'), ModerationContentType::UserBio => UserProfile::query() ->with('user:id,username,name') ->where(function (EloquentBuilder $query): void { $query->whereNotNull('about')->where('about', '!=', '') ->orWhere(function (EloquentBuilder $fallback): void { $fallback->whereNotNull('description')->where('description', '!=', ''); }); }) ->orderBy('user_id'), ModerationContentType::UserProfileLink => UserSocialLink::query() ->with('user:id,username,name') ->whereNotNull('url') ->where('url', '!=', '') ->orderBy('id'), ModerationContentType::CollectionTitle => Collection::query() ->with('user:id,username,name') ->whereNotNull('title') ->where('title', '!=', '') ->orderBy('id'), ModerationContentType::CollectionDescription => Collection::query() ->with('user:id,username,name') ->whereNotNull('description') ->where('description', '!=', '') ->orderBy('id'), ModerationContentType::StoryTitle => Story::query() ->with('creator:id,username,name') ->whereNotNull('title') ->where('title', '!=', '') ->orderBy('id'), ModerationContentType::StoryContent => Story::query() ->with('creator:id,username,name') ->whereNotNull('content') ->where('content', '!=', '') ->orderBy('id'), ModerationContentType::CardTitle => NovaCard::query() ->with('user:id,username,name') ->whereNotNull('title') ->where('title', '!=', '') ->orderBy('id'), ModerationContentType::CardText => NovaCard::query() ->with('user:id,username,name') ->where(function (EloquentBuilder $query): void { $query->whereNotNull('quote_text')->where('quote_text', '!=', '') ->orWhere(function (EloquentBuilder $description): void { $description->whereNotNull('description')->where('description', '!=', ''); }); }) ->orderBy('id'), default => throw new \InvalidArgumentException('Unsupported moderation content type: ' . $type->value), }; } /** * @param Artwork|ArtworkComment|Collection|Story|NovaCard|UserProfile|UserSocialLink $row * @return array */ public function buildContext(ModerationContentType $type, object $row): array { return match ($type) { ModerationContentType::ArtworkComment => [ 'content_type' => $type->value, 'content_id' => (int) $row->id, 'content_target_type' => 'artwork_comment', 'content_target_id' => (int) $row->id, 'artwork_id' => (int) $row->artwork_id, 'user_id' => $row->user_id ? (int) $row->user_id : null, 'content_snapshot' => (string) ($row->raw_content ?: $row->content), 'is_publicly_exposed' => true, ], ModerationContentType::ArtworkDescription => [ 'content_type' => $type->value, 'content_id' => (int) $row->id, 'content_target_type' => 'artwork', 'content_target_id' => (int) $row->id, 'artwork_id' => (int) $row->id, 'user_id' => $row->user_id ? (int) $row->user_id : null, 'content_snapshot' => (string) ($row->description ?? ''), 'is_publicly_exposed' => (bool) ($row->is_public ?? false), ], ModerationContentType::ArtworkTitle => [ 'content_type' => $type->value, 'content_id' => (int) $row->id, 'content_target_type' => 'artwork', 'content_target_id' => (int) $row->id, 'artwork_id' => (int) $row->id, 'user_id' => $row->user_id ? (int) $row->user_id : null, 'content_snapshot' => (string) ($row->title ?? ''), 'is_publicly_exposed' => (bool) ($row->is_public ?? false), ], ModerationContentType::UserBio => [ 'content_type' => $type->value, 'content_id' => (int) $row->user_id, 'content_target_type' => 'user_profile', 'content_target_id' => (int) $row->user_id, 'user_id' => (int) $row->user_id, 'content_snapshot' => trim((string) ($row->about ?: $row->description ?: '')), 'is_publicly_exposed' => true, ], ModerationContentType::UserProfileLink => [ 'content_type' => $type->value, 'content_id' => (int) $row->id, 'content_target_type' => 'user_social_link', 'content_target_id' => (int) $row->id, 'user_id' => (int) $row->user_id, 'content_snapshot' => trim((string) ($row->url ?? '')), 'is_publicly_exposed' => true, ], ModerationContentType::CollectionTitle => [ 'content_type' => $type->value, 'content_id' => (int) $row->id, 'content_target_type' => 'collection', 'content_target_id' => (int) $row->id, 'user_id' => $row->user_id ? (int) $row->user_id : null, 'content_snapshot' => (string) ($row->title ?? ''), 'is_publicly_exposed' => in_array((string) ($row->visibility ?? ''), ['public', 'unlisted'], true), ], ModerationContentType::CollectionDescription => [ 'content_type' => $type->value, 'content_id' => (int) $row->id, 'content_target_type' => 'collection', 'content_target_id' => (int) $row->id, 'user_id' => $row->user_id ? (int) $row->user_id : null, 'content_snapshot' => (string) ($row->description ?? ''), 'is_publicly_exposed' => in_array((string) ($row->visibility ?? ''), ['public', 'unlisted'], true), ], ModerationContentType::StoryTitle => [ 'content_type' => $type->value, 'content_id' => (int) $row->id, 'content_target_type' => 'story', 'content_target_id' => (int) $row->id, 'user_id' => $row->creator_id ? (int) $row->creator_id : null, 'content_snapshot' => (string) ($row->title ?? ''), 'is_publicly_exposed' => in_array((string) ($row->status ?? ''), ['published', 'scheduled'], true), ], ModerationContentType::StoryContent => [ 'content_type' => $type->value, 'content_id' => (int) $row->id, 'content_target_type' => 'story', 'content_target_id' => (int) $row->id, 'user_id' => $row->creator_id ? (int) $row->creator_id : null, 'content_snapshot' => (string) ($row->content ?? ''), 'is_publicly_exposed' => in_array((string) ($row->status ?? ''), ['published', 'scheduled'], true), ], ModerationContentType::CardTitle => [ 'content_type' => $type->value, 'content_id' => (int) $row->id, 'content_target_type' => 'nova_card', 'content_target_id' => (int) $row->id, 'user_id' => $row->user_id ? (int) $row->user_id : null, 'content_snapshot' => (string) ($row->title ?? ''), 'is_publicly_exposed' => in_array((string) ($row->visibility ?? ''), ['public', 'unlisted'], true), ], ModerationContentType::CardText => [ 'content_type' => $type->value, 'content_id' => (int) $row->id, 'content_target_type' => 'nova_card', 'content_target_id' => (int) $row->id, 'user_id' => $row->user_id ? (int) $row->user_id : null, 'content_snapshot' => trim(implode("\n", array_filter([ (string) ($row->quote_text ?? ''), (string) ($row->description ?? ''), (string) ($row->quote_author ?? ''), (string) ($row->quote_source ?? ''), ]))), 'is_publicly_exposed' => in_array((string) ($row->visibility ?? ''), ['public', 'unlisted'], true), ], default => throw new \InvalidArgumentException('Unsupported moderation content type: ' . $type->value), }; } /** * @return array{context:array|null, type:ModerationContentType|null} */ public function contextForFinding(ContentModerationFinding $finding): array { return match ($finding->content_type) { ModerationContentType::ArtworkComment => $this->commentContextForFinding($finding), ModerationContentType::ArtworkDescription => $this->descriptionContextForFinding($finding), ModerationContentType::ArtworkTitle => $this->artworkTitleContextForFinding($finding), ModerationContentType::UserBio => $this->userBioContextForFinding($finding), ModerationContentType::UserProfileLink => $this->userProfileLinkContextForFinding($finding), ModerationContentType::CollectionTitle => $this->collectionTitleContextForFinding($finding), ModerationContentType::CollectionDescription => $this->collectionDescriptionContextForFinding($finding), ModerationContentType::StoryTitle => $this->storyTitleContextForFinding($finding), ModerationContentType::StoryContent => $this->storyContentContextForFinding($finding), ModerationContentType::CardTitle => $this->cardTitleContextForFinding($finding), ModerationContentType::CardText => $this->cardTextContextForFinding($finding), default => ['context' => null, 'type' => null], }; } /** * @return array{context:array|null, type:ModerationContentType|null} */ private function commentContextForFinding(ContentModerationFinding $finding): array { $comment = ArtworkComment::query()->find($finding->content_id); if (! $comment) { return ['context' => null, 'type' => null]; } return [ 'context' => $this->buildContext(ModerationContentType::ArtworkComment, $comment), 'type' => ModerationContentType::ArtworkComment, ]; } /** * @return array{context:array|null, type:ModerationContentType|null} */ private function descriptionContextForFinding(ContentModerationFinding $finding): array { $artworkId = (int) ($finding->artwork_id ?? $finding->content_id); $artwork = Artwork::query()->find($artworkId); if (! $artwork) { return ['context' => null, 'type' => null]; } return [ 'context' => $this->buildContext(ModerationContentType::ArtworkDescription, $artwork), 'type' => ModerationContentType::ArtworkDescription, ]; } private function artworkTitleContextForFinding(ContentModerationFinding $finding): array { $artwork = Artwork::query()->find((int) ($finding->artwork_id ?? $finding->content_id)); if (! $artwork) { return ['context' => null, 'type' => null]; } return ['context' => $this->buildContext(ModerationContentType::ArtworkTitle, $artwork), 'type' => ModerationContentType::ArtworkTitle]; } private function userBioContextForFinding(ContentModerationFinding $finding): array { $profile = UserProfile::query()->find($finding->content_id); if (! $profile) { return ['context' => null, 'type' => null]; } return ['context' => $this->buildContext(ModerationContentType::UserBio, $profile), 'type' => ModerationContentType::UserBio]; } private function userProfileLinkContextForFinding(ContentModerationFinding $finding): array { $link = UserSocialLink::query()->find($finding->content_id); if (! $link) { return ['context' => null, 'type' => null]; } return ['context' => $this->buildContext(ModerationContentType::UserProfileLink, $link), 'type' => ModerationContentType::UserProfileLink]; } private function collectionTitleContextForFinding(ContentModerationFinding $finding): array { $collection = Collection::query()->find($finding->content_id); if (! $collection) { return ['context' => null, 'type' => null]; } return ['context' => $this->buildContext(ModerationContentType::CollectionTitle, $collection), 'type' => ModerationContentType::CollectionTitle]; } private function collectionDescriptionContextForFinding(ContentModerationFinding $finding): array { $collection = Collection::query()->find($finding->content_id); if (! $collection) { return ['context' => null, 'type' => null]; } return ['context' => $this->buildContext(ModerationContentType::CollectionDescription, $collection), 'type' => ModerationContentType::CollectionDescription]; } private function storyTitleContextForFinding(ContentModerationFinding $finding): array { $story = Story::query()->find($finding->content_id); if (! $story) { return ['context' => null, 'type' => null]; } return ['context' => $this->buildContext(ModerationContentType::StoryTitle, $story), 'type' => ModerationContentType::StoryTitle]; } private function storyContentContextForFinding(ContentModerationFinding $finding): array { $story = Story::query()->find($finding->content_id); if (! $story) { return ['context' => null, 'type' => null]; } return ['context' => $this->buildContext(ModerationContentType::StoryContent, $story), 'type' => ModerationContentType::StoryContent]; } private function cardTitleContextForFinding(ContentModerationFinding $finding): array { $card = NovaCard::query()->find($finding->content_id); if (! $card) { return ['context' => null, 'type' => null]; } return ['context' => $this->buildContext(ModerationContentType::CardTitle, $card), 'type' => ModerationContentType::CardTitle]; } private function cardTextContextForFinding(ContentModerationFinding $finding): array { $card = NovaCard::query()->find($finding->content_id); if (! $card) { return ['context' => null, 'type' => null]; } return ['context' => $this->buildContext(ModerationContentType::CardText, $card), 'type' => ModerationContentType::CardText]; } }