From 6150cb402e90ae7fc2cf6f30e964b464c3068e8f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 31 Jan 2023 16:06:05 +0100 Subject: Add an endpoint to return all participants of a room with its breakout rooms Signed-off-by: Joas Schilling --- lib/Controller/RoomController.php | 33 +++++++++++++++++++++++++++- lib/Participant.php | 4 ++++ lib/Service/ParticipantService.php | 44 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/Controller/RoomController.php b/lib/Controller/RoomController.php index 2f725cc00..0e44e69a4 100644 --- a/lib/Controller/RoomController.php +++ b/lib/Controller/RoomController.php @@ -699,9 +699,39 @@ class RoomController extends AEnvironmentAwareController { return new DataResponse([], Http::STATUS_FORBIDDEN); } - $maxPingAge = $this->timeFactory->getTime() - Session::SESSION_TIMEOUT_KILL; $participants = $this->participantService->getSessionsAndParticipantsForRoom($this->room); + + return $this->formatParticipantList($participants, $includeStatus); + } + + /** + * @PublicPage + * @RequireParticipant + * @RequireModeratorOrNoLobby + * + * @param bool $includeStatus + * @return DataResponse + */ + public function getBreakoutRoomParticipants(bool $includeStatus = false): DataResponse { + if ($this->participant->getAttendee()->getParticipantType() === Participant::GUEST) { + return new DataResponse([], Http::STATUS_FORBIDDEN); + } + + $breakoutRooms = $this->breakoutRoomService->getBreakoutRooms($this->room, $this->participant); + $breakoutRooms[] = $this->room; + $participants = $this->participantService->getSessionsAndParticipantsForRooms($breakoutRooms); + + return $this->formatParticipantList($participants, $includeStatus); + } + + /** + * @param Participant[] $participants + * @param bool $includeStatus + * @return DataResponse + */ + protected function formatParticipantList(array $participants, bool $includeStatus): DataResponse { $results = $headers = $statuses = []; + $maxPingAge = $this->timeFactory->getTime() - Session::SESSION_TIMEOUT_KILL; if ($this->userId !== null && $includeStatus @@ -747,6 +777,7 @@ class RoomController extends AEnvironmentAwareController { } $result = [ + 'roomToken' => $participant->getRoom()->getToken(), 'inCall' => Participant::FLAG_DISCONNECTED, 'lastPing' => 0, 'sessionIds' => [], diff --git a/lib/Participant.php b/lib/Participant.php index 83e80f7f5..b11a9f74b 100644 --- a/lib/Participant.php +++ b/lib/Participant.php @@ -67,6 +67,10 @@ class Participant { $this->session = $session; } + public function getRoom(): Room { + return $this->room; + } + public function getAttendee(): Attendee { return $this->attendee; } diff --git a/lib/Service/ParticipantService.php b/lib/Service/ParticipantService.php index 2941972c8..f03fad5e6 100644 --- a/lib/Service/ParticipantService.php +++ b/lib/Service/ParticipantService.php @@ -1266,6 +1266,34 @@ class ParticipantService { return $this->getParticipantsFromQuery($query, $room); } + /** + * Get all sessions and attendees without a session for the room + * + * This will return multiple items for the same attendee if the attendee + * has multiple sessions in the room. + * + * @param Room[] $rooms + * @return Participant[] + */ + public function getSessionsAndParticipantsForRooms(array $rooms): array { + $roomIds = array_map(static fn (Room $room) => $room->getId(), $rooms); + $map = array_combine($roomIds, $rooms); + + $query = $this->connection->getQueryBuilder(); + + $helper = new SelectHelper(); + $helper->selectAttendeesTable($query); + $helper->selectSessionsTable($query); + $query->from('talk_attendees', 'a') + ->leftJoin( + 'a', 'talk_sessions', 's', + $query->expr()->eq('s.attendee_id', 'a.id') + ) + ->where($query->expr()->in('a.room_id', $query->createNamedParameter($roomIds, IQueryBuilder::PARAM_INT_ARRAY))); + + return $this->getParticipantsForRoomsFromQuery($query, $map); + } + /** * @param Room $room * @param int $maxAge @@ -1350,12 +1378,28 @@ class ParticipantService { /** * @param IQueryBuilder $query + * @param Room $room * @return Participant[] */ protected function getParticipantsFromQuery(IQueryBuilder $query, Room $room): array { + return $this->getParticipantsForRoomsFromQuery($query, [$room->getId() => $room]); + } + + /** + * @param IQueryBuilder $query + * @param Room[] $rooms Room ID => Room object + * @psalm-param array $rooms + * @return Participant[] + */ + protected function getParticipantsForRoomsFromQuery(IQueryBuilder $query, array $rooms): array { $participants = []; $result = $query->executeQuery(); while ($row = $result->fetch()) { + $room = $rooms[(int) $row['room_id']] ?? null; + if ($room === null) { + continue; + } + $attendee = $this->attendeeMapper->createAttendeeFromRow($row); if (isset($row['s_id'])) { $session = $this->sessionMapper->createSessionFromRow($row); -- cgit v1.2.3