160 lines
10 KiB
PHP
160 lines
10 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Group;
|
|
use App\Models\User;
|
|
use App\Support\AvatarUrl;
|
|
use Illuminate\Support\Str;
|
|
|
|
class GroupCardService
|
|
{
|
|
public function __construct(
|
|
private readonly GroupRecruitmentService $recruitment,
|
|
private readonly GroupReputationService $reputation,
|
|
private readonly GroupFollowService $follows,
|
|
private readonly GroupMembershipService $memberships,
|
|
) {
|
|
}
|
|
|
|
public function mapGroupCard(Group $group, ?User $viewer = null): array
|
|
{
|
|
$owner = $group->relationLoaded('owner') ? $group->owner : $group->owner()->with('profile')->first();
|
|
$recruitment = $this->recruitment->payloadForGroup($group);
|
|
$canManage = $viewer ? $group->canManage($viewer) : false;
|
|
$canManageMembers = $viewer ? $group->canManageMembers($viewer) : false;
|
|
$canPublishArtworks = $viewer ? $group->canPublishArtworks($viewer) : false;
|
|
$canManageCollections = $viewer ? $group->canManageCollections($viewer) : false;
|
|
$canRequestJoin = $viewer ? $group->canRequestJoin($viewer) : false;
|
|
$canReviewJoinRequests = $viewer ? $group->canReviewJoinRequests($viewer) : false;
|
|
$canReviewSubmissions = $viewer ? $group->canReviewSubmissions($viewer) : false;
|
|
$canManageRecruitment = $viewer ? $group->canManageRecruitment($viewer) : false;
|
|
$canManagePosts = $viewer ? $group->canManagePosts($viewer) : false;
|
|
$canPublishPosts = $viewer ? $group->canPublishPosts($viewer) : false;
|
|
$canPinPosts = $viewer ? $group->canPinPosts($viewer) : false;
|
|
$canManageMemberPermissions = $viewer ? $group->canManageMemberPermissions($viewer) : false;
|
|
$canManageProjects = $viewer ? $group->canManageProjects($viewer) : false;
|
|
$canManageReleases = $viewer ? $group->canManageReleases($viewer) : false;
|
|
$canPublishReleases = $viewer ? $group->canPublishReleases($viewer) : false;
|
|
$canManageMilestones = $viewer ? $group->canManageMilestones($viewer) : false;
|
|
$canViewReputationDashboard = $viewer ? $group->canViewReputationDashboard($viewer) : false;
|
|
$canManageBadges = $viewer ? $group->canManageBadges($viewer) : false;
|
|
$canViewInternalTrustMetrics = $viewer ? $group->canViewInternalTrustMetrics($viewer) : false;
|
|
$canManageChallenges = $viewer ? $group->canManageChallenges($viewer) : false;
|
|
$canManageEvents = $viewer ? $group->canManageEvents($viewer) : false;
|
|
$canPublishEventUpdates = $viewer ? $group->canPublishEventUpdates($viewer) : false;
|
|
$canManageAssets = $viewer ? $group->canManageAssets($viewer) : false;
|
|
$canViewInternalAssets = $viewer ? $group->canViewInternalAssets($viewer) : false;
|
|
$canPinActivity = $viewer ? $group->canPinActivity($viewer) : false;
|
|
$trustSignals = $this->reputation->trustSignals($group);
|
|
$badges = $this->reputation->groupBadges($group, 6);
|
|
|
|
return [
|
|
'id' => (int) $group->id,
|
|
'entity_type' => 'group',
|
|
'name' => (string) $group->name,
|
|
'slug' => (string) $group->slug,
|
|
'headline' => $group->headline,
|
|
'bio_excerpt' => Str::limit((string) ($group->bio ?? ''), 180),
|
|
'visibility' => (string) $group->visibility,
|
|
'status' => (string) ($group->status ?? Group::LIFECYCLE_ACTIVE),
|
|
'membership_policy' => (string) ($group->membership_policy ?? Group::MEMBERSHIP_INVITE_ONLY),
|
|
'type' => $group->type,
|
|
'is_verified' => (bool) $group->is_verified,
|
|
'is_recruiting' => (bool) ($recruitment['is_recruiting'] ?? false),
|
|
'recruitment_headline' => $recruitment['headline'] ?? null,
|
|
'avatar_url' => $group->avatarUrl(),
|
|
'banner_url' => $group->bannerUrl(),
|
|
'owner' => [
|
|
'id' => (int) ($owner?->id ?? 0),
|
|
'name' => $owner?->name,
|
|
'username' => $owner?->username,
|
|
'avatar_url' => $owner ? AvatarUrl::forUser((int) $owner->id, $owner->profile?->avatar_hash, 72) : null,
|
|
'profile_url' => $owner?->username ? route('profile.show', ['username' => strtolower((string) $owner->username)]) : null,
|
|
],
|
|
'counts' => [
|
|
'artworks' => (int) $group->artworks_count,
|
|
'collections' => (int) $group->collections_count,
|
|
'followers' => (int) $group->followers_count,
|
|
'members' => $group->relationLoaded('members')
|
|
? (int) $group->members->where('status', Group::STATUS_ACTIVE)->count()
|
|
: (int) $group->members()->where('status', Group::STATUS_ACTIVE)->count(),
|
|
],
|
|
'permissions' => [
|
|
'can_manage' => $canManage,
|
|
'can_manage_members' => $canManageMembers,
|
|
'can_publish_artworks' => $canPublishArtworks,
|
|
'can_manage_collections' => $canManageCollections,
|
|
'can_request_join' => $canRequestJoin,
|
|
'can_review_join_requests' => $canReviewJoinRequests,
|
|
'can_submit_artwork_for_review' => $viewer ? $group->canSubmitArtworkForReview($viewer) : false,
|
|
'can_review_submissions' => $canReviewSubmissions,
|
|
'can_manage_recruitment' => $canManageRecruitment,
|
|
'can_manage_posts' => $canManagePosts,
|
|
'can_publish_posts' => $canPublishPosts,
|
|
'can_pin_posts' => $canPinPosts,
|
|
'can_manage_member_permissions' => $canManageMemberPermissions,
|
|
'can_manage_projects' => $canManageProjects,
|
|
'can_manage_releases' => $canManageReleases,
|
|
'can_publish_releases' => $canPublishReleases,
|
|
'can_manage_milestones' => $canManageMilestones,
|
|
'can_view_reputation_dashboard' => $canViewReputationDashboard,
|
|
'can_manage_badges' => $canManageBadges,
|
|
'can_view_internal_trust_metrics' => $canViewInternalTrustMetrics,
|
|
'can_manage_challenges' => $canManageChallenges,
|
|
'can_manage_events' => $canManageEvents,
|
|
'can_publish_event_updates' => $canPublishEventUpdates,
|
|
'can_manage_assets' => $canManageAssets,
|
|
'can_view_internal_assets' => $canViewInternalAssets,
|
|
'can_pin_activity' => $canPinActivity,
|
|
],
|
|
'trust_signals' => $trustSignals,
|
|
'badges' => $badges,
|
|
'badge_keys' => array_values(array_filter(array_map(
|
|
static fn (array $badge): ?string => $badge['key'] ?? null,
|
|
$badges,
|
|
))),
|
|
'viewer' => [
|
|
'role' => $viewer ? $group->activeRoleFor($viewer) : null,
|
|
'role_label' => $viewer ? Group::displayRole($group->activeRoleFor($viewer)) : null,
|
|
'is_following' => $viewer ? $this->follows->isFollowing($group, $viewer) : false,
|
|
'permission_overrides' => $viewer ? $group->permissionOverridesFor($viewer) : [],
|
|
],
|
|
'urls' => [
|
|
'public' => $group->publicUrl(),
|
|
'studio' => route('studio.groups.show', ['group' => $group]),
|
|
'studio_artworks' => route('studio.groups.artworks', ['group' => $group]),
|
|
'studio_collections' => route('studio.groups.collections', ['group' => $group]),
|
|
'studio_members' => route('studio.groups.members', ['group' => $group]),
|
|
'studio_invitations' => $canManageMembers ? route('studio.groups.invitations', ['group' => $group]) : null,
|
|
'studio_join_requests' => $canReviewJoinRequests ? route('studio.groups.join-requests', ['group' => $group]) : null,
|
|
'studio_review' => $canReviewSubmissions ? route('studio.groups.review', ['group' => $group]) : null,
|
|
'studio_recruitment' => $canManageRecruitment ? route('studio.groups.recruitment', ['group' => $group]) : null,
|
|
'studio_posts' => $canManagePosts ? route('studio.groups.posts.index', ['group' => $group]) : null,
|
|
'studio_projects' => $canManageProjects ? route('studio.groups.projects.index', ['group' => $group]) : null,
|
|
'studio_releases' => $canManageReleases ? route('studio.groups.releases.index', ['group' => $group]) : null,
|
|
'studio_reputation' => $canViewReputationDashboard ? route('studio.groups.reputation', ['group' => $group]) : null,
|
|
'studio_challenges' => $canManageChallenges ? route('studio.groups.challenges.index', ['group' => $group]) : null,
|
|
'studio_events' => ($canManageEvents || $canPublishEventUpdates) ? route('studio.groups.events.index', ['group' => $group]) : null,
|
|
'studio_assets' => ($canManageAssets || $canViewInternalAssets) ? route('studio.groups.assets.index', ['group' => $group]) : null,
|
|
'studio_activity' => route('studio.groups.activity', ['group' => $group]),
|
|
'studio_settings' => $canManage ? route('studio.groups.settings', ['group' => $group]) : null,
|
|
'upload' => ($canPublishArtworks || ($viewer && $group->canCreateArtworkDrafts($viewer))) ? route('upload', ['group' => $group->slug]) : null,
|
|
'collection_create' => $canManageCollections ? route('settings.collections.create', ['group' => $group->slug]) : null,
|
|
'follow' => route('groups.follow', ['group' => $group]),
|
|
'unfollow' => route('groups.unfollow', ['group' => $group]),
|
|
'join_request_store' => $canRequestJoin ? route('groups.join-requests.store', ['group' => $group]) : null,
|
|
'join_request_withdraw_pattern' => $viewer ? route('groups.join-requests.destroy', ['group' => $group, 'joinRequest' => '__JOIN_REQUEST__']) : null,
|
|
'posts' => route('groups.section', ['group' => $group, 'section' => 'posts']),
|
|
'projects' => route('groups.section', ['group' => $group, 'section' => 'projects']),
|
|
'releases' => route('groups.section', ['group' => $group, 'section' => 'releases']),
|
|
'challenges' => route('groups.section', ['group' => $group, 'section' => 'challenges']),
|
|
'events' => route('groups.section', ['group' => $group, 'section' => 'events']),
|
|
'activity' => route('groups.section', ['group' => $group, 'section' => 'activity']),
|
|
],
|
|
'pending_invites_count' => $this->memberships->pendingInviteCount($group),
|
|
];
|
|
}
|
|
} |