> */ protected array $participantsPerRoom = []; public function __construct( protected ParticipantService $participantService, protected AvatarService $avatarService, ) { } /** * @return array{type: string, id: string} */ public function convertTypeAndId(Room $room, string $type, string $id): array { if ($type === Attendee::ACTOR_USERS) { $type = Attendee::ACTOR_FEDERATED_USERS; $id = $this->createCloudIdFromUserIdAndFullServerUrl($id, $room->getRemoteServer()); } elseif ($type === Attendee::ACTOR_FEDERATED_USERS) { $localParticipants = $this->getLocalParticipants($room); if (isset($localParticipants[$id])) { $local = $localParticipants[$id]; $type = Attendee::ACTOR_USERS; $id = $local['userId']; } } return ['type' => $type, 'id' => $id]; } public function convertAttendee(Room $room, array $entry, string $typeField, string $idField, string $displayNameField): array { if (!isset($entry[$typeField])) { return $entry; } if ($entry[$typeField] === Attendee::ACTOR_USERS) { $entry[$typeField] = Attendee::ACTOR_FEDERATED_USERS; $entry[$idField] = $this->createCloudIdFromUserIdAndFullServerUrl($entry[$idField], $room->getRemoteServer()); } elseif ($entry[$typeField] === Attendee::ACTOR_FEDERATED_USERS) { $localParticipants = $this->getLocalParticipants($room); if (isset($localParticipants[$entry[$idField]])) { $local = $localParticipants[$entry[$idField]]; $entry[$typeField] = Attendee::ACTOR_USERS; $entry[$idField] = $local['userId']; $entry[$displayNameField] = $local['displayName']; } } return $entry; } public function convertAttendees(Room $room, array $entries, string $typeField, string $idField, string $displayNameField): array { return array_map( fn (array $entry): array => $this->convertAttendee($room, $entry, $typeField, $idField, $displayNameField), $entries ); } protected function convertMessageParameter(Room $room, array $parameter): array { if ($parameter['type'] === 'user') { // RichObjectDefinition, not Attendee::ACTOR_USERS if (!isset($parameter['server'])) { $parameter['server'] = $room->getRemoteServer(); if (!isset($parameter['mention-id'])) { $parameter['mention-id'] = $parameter['id']; } } elseif ($parameter['server']) { $localParticipants = $this->getLocalParticipants($room); $cloudId = $this->createCloudIdFromUserIdAndFullServerUrl($parameter['id'], $parameter['server']); if (!isset($parameter['mention-id'])) { $parameter['mention-id'] = 'federated_user/' . $parameter['id'] . '@' . $parameter['server']; } if (isset($localParticipants[$cloudId])) { unset($parameter['server']); $parameter['name'] = $localParticipants[$cloudId]['displayName']; } } } elseif ($parameter['type'] === 'call' && $parameter['id'] === $room->getRemoteToken()) { $parameter['id'] = $room->getToken(); $parameter['icon-url'] = $this->avatarService->getAvatarUrl($room); if (!isset($parameter['mention-id'])) { $parameter['mention-id'] = 'all'; } } elseif ($parameter['type'] === 'circle') { if (!isset($parameter['mention-id'])) { $parameter['mention-id'] = 'team/' . $parameter['id']; } } elseif ($parameter['type'] === 'user-group') { if (!isset($parameter['mention-id'])) { $parameter['mention-id'] = 'group/' . $parameter['id']; } } elseif ($parameter['type'] === 'email' || $parameter['type'] === 'guest') { if (!isset($parameter['mention-id'])) { $parameter['mention-id'] = $parameter['type'] . '/' . $parameter['id']; } } return $parameter; } public function convertMessageParameters(Room $room, array $message): array { $message['messageParameters'] = array_map( fn (array $message): array => $this->convertMessageParameter($room, $message), $message['messageParameters'] ); return $message; } /** * @param Room $room * @param TalkChatMessageWithParent $message * @return TalkChatMessageWithParent */ public function convertMessage(Room $room, array $message): array { $message['token'] = $room->getToken(); $message = $this->convertAttendee($room, $message, 'actorType', 'actorId', 'actorDisplayName'); $message = $this->convertAttendee($room, $message, 'lastEditActorType', 'lastEditActorId', 'lastEditActorDisplayName'); $message = $this->convertMessageParameters($room, $message); if (isset($message['parent'])) { $message['parent'] = $this->convertMessage($room, $message['parent']); } return $message; } /** * @param Room $room * @param TalkChatMessageWithParent[] $messages * @return TalkChatMessageWithParent[] */ public function convertMessages(Room $room, array $messages): array { return array_map( fn (array $message): array => $this->convertMessage($room, $message), $messages ); } /** * @param Room $room * @param TalkThreadInfo $threadInfo * @return TalkThreadInfo */ public function convertThreadInfo(Room $room, array $threadInfo): array { $threadInfo['thread']['roomToken'] = $room->getToken(); if (isset($threadInfo['first'])) { $threadInfo['first'] = $this->convertMessageParameters($room, $threadInfo['first']); } if (isset($threadInfo['last'])) { $threadInfo['last'] = $this->convertMessageParameters($room, $threadInfo['last']); } return $threadInfo; } /** * @param Room $room * @param list $threadInfos * @return list */ public function convertThreadInfos(Room $room, array $threadInfos): array { return array_map( fn (array $threadInfo): array => $this->convertThreadInfo($room, $threadInfo), $threadInfos ); } /** * @template T of TalkPoll|TalkPollDraft * @param Room $room * @param TalkPoll|TalkPollDraft $poll * @psalm-param T $poll * @return TalkPoll|TalkPollDraft * @psalm-return T */ public function convertPoll(Room $room, array $poll): array { $poll = $this->convertAttendee($room, $poll, 'actorType', 'actorId', 'actorDisplayName'); if (isset($poll['details'])) { $poll['details'] = array_map( fn (array $vote): array => $this->convertAttendee($room, $vote, 'actorType', 'actorId', 'actorDisplayName'), $poll['details'] ); } return $poll; } /** * @param Room $room * @param TalkReaction[] $reactions * @return TalkReaction[] */ protected function convertReactions(Room $room, array $reactions): array { return array_map( fn (array $reaction): array => $this->convertAttendee($room, $reaction, 'actorType', 'actorId', 'actorDisplayName'), $reactions ); } /** * @param Room $room * @param array $reactionsList * @return array */ public function convertReactionsList(Room $room, array $reactionsList): array { return array_map( fn (array $reactions): array => $this->convertReactions($room, $reactions), $reactionsList ); } /** * @return array */ protected function getLocalParticipants(Room $room): array { if (array_key_exists($room->getToken(), $this->participantsPerRoom)) { return $this->participantsPerRoom[$room->getToken()]; } $this->participantsPerRoom[$room->getToken()] = []; $localParticipants = $this->participantService->getActorsByType($room, Attendee::ACTOR_USERS); foreach ($localParticipants as $participant) { $this->participantsPerRoom[$room->getToken()][$participant->getInvitedCloudId()] = [ 'userId' => $participant->getActorId(), 'displayName' => $participant->getDisplayName(), ]; } return $this->participantsPerRoom[$room->getToken()]; } protected function createCloudIdFromUserIdAndFullServerUrl(string $userId, string $serverUrl): string { if (str_starts_with($serverUrl, 'https://')) { $serverUrl = substr($serverUrl, strlen('https://')); } return $userId . '@' . $serverUrl; } }