Collapse profile group contribution queries
This commit is contained in:
@@ -1499,7 +1499,7 @@ class ProfileController extends Controller
|
||||
|
||||
private function buildGroupContributionHistory(User $user): array
|
||||
{
|
||||
return GroupContributorStat::query()
|
||||
$stats = GroupContributorStat::query()
|
||||
->with(['group.owner.profile'])
|
||||
->where('user_id', $user->id)
|
||||
->whereHas('group', fn ($query) => $query
|
||||
@@ -1508,29 +1508,60 @@ class ProfileController extends Controller
|
||||
->orderByDesc('release_count')
|
||||
->orderByDesc('credited_artworks_count')
|
||||
->limit(8)
|
||||
->get();
|
||||
|
||||
$groupIds = $stats->pluck('group_id')->map(static fn ($id): int => (int) $id)->values()->all();
|
||||
if ($groupIds === []) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$membershipsByGroup = GroupMember::query()
|
||||
->whereIn('group_id', $groupIds)
|
||||
->where('user_id', $user->id)
|
||||
->where('status', Group::STATUS_ACTIVE)
|
||||
->get()
|
||||
->map(function (GroupContributorStat $stat) use ($user): ?array {
|
||||
->keyBy('group_id');
|
||||
|
||||
$releaseRolesByGroup = GroupReleaseContributor::query()
|
||||
->join('group_releases as bulk_releases', 'bulk_releases.id', '=', 'group_release_contributors.group_release_id')
|
||||
->where('group_release_contributors.user_id', $user->id)
|
||||
->whereIn('bulk_releases.group_id', $groupIds)
|
||||
->whereNull('bulk_releases.deleted_at')
|
||||
->orderBy('group_release_contributors.id')
|
||||
->get([
|
||||
'bulk_releases.group_id',
|
||||
'group_release_contributors.role_label',
|
||||
])
|
||||
->groupBy('group_id');
|
||||
|
||||
$projectRolesByGroup = GroupProjectMember::query()
|
||||
->join('group_projects as bulk_projects', 'bulk_projects.id', '=', 'group_project_members.group_project_id')
|
||||
->where('group_project_members.user_id', $user->id)
|
||||
->whereIn('bulk_projects.group_id', $groupIds)
|
||||
->whereNull('bulk_projects.deleted_at')
|
||||
->orderBy('group_project_members.id')
|
||||
->get([
|
||||
'bulk_projects.group_id',
|
||||
'group_project_members.role_label',
|
||||
])
|
||||
->groupBy('group_id');
|
||||
|
||||
$recentReleasesByGroup = $this->loadRecentGroupReleaseTitles($user, $groupIds);
|
||||
|
||||
return $stats
|
||||
->map(function (GroupContributorStat $stat) use ($user, $membershipsByGroup, $releaseRolesByGroup, $projectRolesByGroup, $recentReleasesByGroup): ?array {
|
||||
$group = $stat->group;
|
||||
|
||||
if (! $group) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$member = GroupMember::query()
|
||||
->where('group_id', $group->id)
|
||||
->where('user_id', $user->id)
|
||||
->where('status', Group::STATUS_ACTIVE)
|
||||
->first();
|
||||
$groupId = (int) $group->id;
|
||||
$member = $membershipsByGroup->get($groupId);
|
||||
|
||||
$roleLabels = collect()
|
||||
->merge(GroupReleaseContributor::query()
|
||||
->where('user_id', $user->id)
|
||||
->whereHas('release', fn ($query) => $query->where('group_id', $group->id))
|
||||
->pluck('role_label'))
|
||||
->merge(GroupProjectMember::query()
|
||||
->where('user_id', $user->id)
|
||||
->whereHas('project', fn ($query) => $query->where('group_id', $group->id))
|
||||
->pluck('role_label'))
|
||||
->merge($releaseRolesByGroup->get($groupId, collect())->pluck('role_label'))
|
||||
->merge($projectRolesByGroup->get($groupId, collect())->pluck('role_label'))
|
||||
->filter()
|
||||
->map(fn ($label): string => trim((string) $label))
|
||||
->filter()
|
||||
@@ -1538,21 +1569,7 @@ class ProfileController extends Controller
|
||||
->values()
|
||||
->all();
|
||||
|
||||
$recentReleaseTitles = GroupRelease::query()
|
||||
->where('group_id', $group->id)
|
||||
->where('visibility', GroupRelease::VISIBILITY_PUBLIC)
|
||||
->where(function ($query) use ($user): void {
|
||||
$query->where('lead_user_id', $user->id)
|
||||
->orWhere('created_by_user_id', $user->id)
|
||||
->orWhereHas('contributorLinks', fn ($contributorQuery) => $contributorQuery->where('user_id', $user->id));
|
||||
})
|
||||
->orderByDesc('released_at')
|
||||
->latest('updated_at')
|
||||
->limit(3)
|
||||
->pluck('title')
|
||||
->map(fn ($title): string => (string) $title)
|
||||
->values()
|
||||
->all();
|
||||
$recentReleaseTitles = $recentReleasesByGroup->get($groupId, collect())->all();
|
||||
|
||||
$joinedAt = $group->isOwnedBy($user)
|
||||
? $group->created_at?->toISOString()
|
||||
@@ -1589,6 +1606,45 @@ class ProfileController extends Controller
|
||||
->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the same top-three public releases per group as the previous
|
||||
* per-group LIMIT query, while keeping the existing two-column ordering.
|
||||
*
|
||||
* @param array<int, int> $groupIds
|
||||
* @return \Illuminate\Support\Collection<int, \Illuminate\Support\Collection<int, string>>
|
||||
*/
|
||||
private function loadRecentGroupReleaseTitles(User $user, array $groupIds): \Illuminate\Support\Collection
|
||||
{
|
||||
$eligibleReleases = GroupRelease::query()
|
||||
->whereIn('group_id', $groupIds)
|
||||
->where('visibility', GroupRelease::VISIBILITY_PUBLIC)
|
||||
->where(function ($query) use ($user): void {
|
||||
$query->where('lead_user_id', $user->id)
|
||||
->orWhere('created_by_user_id', $user->id)
|
||||
->orWhereHas('contributorLinks', fn ($contributorQuery) => $contributorQuery->where('user_id', $user->id));
|
||||
})
|
||||
->select(['id', 'group_id', 'title', 'released_at', 'updated_at']);
|
||||
|
||||
$ranked = DB::query()
|
||||
->fromSub($eligibleReleases, 'eligible_group_releases')
|
||||
->select([
|
||||
'group_id',
|
||||
'title',
|
||||
'released_at',
|
||||
'updated_at',
|
||||
])
|
||||
->selectRaw('ROW_NUMBER() OVER (PARTITION BY group_id ORDER BY released_at DESC, updated_at DESC) as release_rank');
|
||||
|
||||
return DB::query()
|
||||
->fromSub($ranked, 'ranked_group_releases')
|
||||
->where('release_rank', '<=', 3)
|
||||
->orderBy('group_id')
|
||||
->orderBy('release_rank')
|
||||
->get(['group_id', 'title'])
|
||||
->groupBy('group_id')
|
||||
->map(fn ($rows) => $rows->pluck('title')->map(fn ($title): string => (string) $title)->values());
|
||||
}
|
||||
|
||||
private function resolveFavouriteTable(): ?string
|
||||
{
|
||||
foreach (['artwork_favourites', 'user_favorites', 'artworks_favourites', 'favourites'] as $table) {
|
||||
|
||||
Reference in New Issue
Block a user