2020-05-16 17:14:17 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace OCA\BigBlueButton\BigBlueButton;
|
|
|
|
|
|
|
|
use BigBlueButton\BigBlueButton;
|
|
|
|
use BigBlueButton\Parameters\CreateMeetingParameters;
|
|
|
|
use BigBlueButton\Parameters\JoinMeetingParameters;
|
2020-05-17 11:09:16 +02:00
|
|
|
use BigBlueButton\Parameters\GetRecordingsParameters;
|
|
|
|
use BigBlueButton\Core\Record;
|
|
|
|
use BigBlueButton\Parameters\DeleteRecordingsParameters;
|
2020-05-17 13:39:01 +02:00
|
|
|
use BigBlueButton\Parameters\IsMeetingRunningParameters;
|
2020-05-16 17:14:17 +02:00
|
|
|
use OCA\BigBlueButton\Db\Room;
|
2020-06-15 17:23:53 +02:00
|
|
|
use OCA\BigBlueButton\Db\RoomShare;
|
|
|
|
use OCA\BigBlueButton\Service\RoomShareService;
|
2020-05-16 17:14:17 +02:00
|
|
|
use OCP\IConfig;
|
|
|
|
use OCP\IURLGenerator;
|
2020-06-15 17:23:53 +02:00
|
|
|
use OCP\IGroupManager;
|
2020-05-16 17:14:17 +02:00
|
|
|
|
|
|
|
class API
|
|
|
|
{
|
|
|
|
/** @var IConfig */
|
|
|
|
private $config;
|
|
|
|
|
|
|
|
/** @var IURLGenerator */
|
|
|
|
private $urlGenerator;
|
|
|
|
|
2020-06-15 17:23:53 +02:00
|
|
|
/** @var IGroupManager */
|
|
|
|
private $groupManager;
|
|
|
|
|
|
|
|
/** @var RoomShareService */
|
|
|
|
private $roomShareService;
|
|
|
|
|
2020-05-16 17:14:17 +02:00
|
|
|
/** @var BigBlueButton */
|
|
|
|
private $server;
|
|
|
|
|
|
|
|
public function __construct(
|
|
|
|
IConfig $config,
|
2020-06-15 17:23:53 +02:00
|
|
|
IURLGenerator $urlGenerator,
|
|
|
|
IGroupManager $groupManager,
|
|
|
|
RoomShareService $roomShareService
|
2020-05-16 17:14:17 +02:00
|
|
|
) {
|
|
|
|
$this->config = $config;
|
|
|
|
$this->urlGenerator = $urlGenerator;
|
2020-06-15 17:23:53 +02:00
|
|
|
$this->groupManager = $groupManager;
|
|
|
|
$this->roomShareService = $roomShareService;
|
2020-05-16 17:14:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private function getServer()
|
|
|
|
{
|
|
|
|
if (!$this->server) {
|
|
|
|
$apiUrl = $this->config->getAppValue('bbb', 'api.url');
|
|
|
|
$secret = $this->config->getAppValue('bbb', 'api.secret');
|
|
|
|
|
|
|
|
$this->server = new BigBlueButton($apiUrl, $secret);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->server;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create join url.
|
|
|
|
*
|
|
|
|
* @return string join url
|
|
|
|
*/
|
|
|
|
public function createJoinUrl(Room $room, int $creationTime, string $displayname, string $uid = null)
|
|
|
|
{
|
2020-06-15 17:23:53 +02:00
|
|
|
$password = $this->isModerator($room, $uid) ? $room->moderatorPassword : $room->attendeePassword;
|
2020-05-16 17:14:17 +02:00
|
|
|
|
|
|
|
$joinMeetingParams = new JoinMeetingParameters($room->uid, $displayname, $password);
|
|
|
|
|
|
|
|
$joinMeetingParams->setCreationTime($creationTime);
|
|
|
|
$joinMeetingParams->setJoinViaHtml5(true);
|
|
|
|
$joinMeetingParams->setRedirect(true);
|
2020-06-04 18:56:55 +02:00
|
|
|
$joinMeetingParams->setGuest($uid === null);
|
2020-05-16 17:14:17 +02:00
|
|
|
|
|
|
|
if ($uid) {
|
|
|
|
$joinMeetingParams->setUserId($uid);
|
|
|
|
// $joinMeetingParams->setAvatarURL();
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->getServer()->getJoinMeetingURL($joinMeetingParams);
|
|
|
|
}
|
|
|
|
|
2020-06-15 17:23:53 +02:00
|
|
|
private function isModerator(Room $room, string $uid): bool
|
|
|
|
{
|
|
|
|
if ($uid === null) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($uid === $room->userId) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
$shares = $this->roomShareService->findAll($room->id);
|
|
|
|
|
|
|
|
/** @var RoomShare $share */
|
|
|
|
foreach ($shares as $share) {
|
|
|
|
if (!$share->hasModeratorPermission()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($share->getShareType() === RoomShare::SHARE_TYPE_USER) {
|
|
|
|
if ($share->getShareWith() === $uid) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} elseif ($share->getShareType() === RoomShare::SHARE_TYPE_GROUP) {
|
|
|
|
if ($this->groupManager->isInGroup($uid, $share->getShareWith())) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-05-16 17:14:17 +02:00
|
|
|
/**
|
|
|
|
* Create meeting room.
|
|
|
|
*
|
|
|
|
* @return int creation time
|
|
|
|
*/
|
|
|
|
public function createMeeting(Room $room, Presentation $presentation = null)
|
|
|
|
{
|
|
|
|
$bbb = $this->getServer();
|
2020-06-10 13:53:46 +02:00
|
|
|
$meetingParams = $this->buildMeetingParams($room, $presentation);
|
2020-05-16 17:14:17 +02:00
|
|
|
|
|
|
|
try {
|
2020-06-10 13:53:46 +02:00
|
|
|
$response = $bbb->createMeeting($meetingParams);
|
2020-05-16 17:14:17 +02:00
|
|
|
} catch (\Exception $e) {
|
2020-06-10 13:53:46 +02:00
|
|
|
throw new \Exception('Can not process create request: ' . $bbb->getCreateMeetingUrl($meetingParams));
|
2020-05-16 17:14:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!$response->success()) {
|
|
|
|
throw new \Exception('Can not create meeting');
|
|
|
|
}
|
|
|
|
|
|
|
|
return $response->getCreationTime();
|
|
|
|
}
|
|
|
|
|
2020-06-10 13:53:46 +02:00
|
|
|
private function buildMeetingParams(Room $room, Presentation $presentation = null): CreateMeetingParameters
|
2020-05-16 17:14:17 +02:00
|
|
|
{
|
|
|
|
$createMeetingParams = new CreateMeetingParameters($room->uid, $room->name);
|
|
|
|
$createMeetingParams->setAttendeePassword($room->attendeePassword);
|
|
|
|
$createMeetingParams->setModeratorPassword($room->moderatorPassword);
|
|
|
|
$createMeetingParams->setRecord($room->record);
|
|
|
|
$createMeetingParams->setAllowStartStopRecording($room->record);
|
|
|
|
$createMeetingParams->setLogoutUrl($this->urlGenerator->getBaseUrl());
|
|
|
|
|
|
|
|
$invitationUrl = $this->urlGenerator->linkToRouteAbsolute('bbb.join.index', ['token' => $room->uid]);
|
|
|
|
$createMeetingParams->setModeratorOnlyMessage('To invite someone to the meeting, send them this link: ' . $invitationUrl);
|
|
|
|
|
|
|
|
if (!empty($room->welcome)) {
|
|
|
|
$createMeetingParams->setWelcomeMessage($room->welcome);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($room->maxParticipants > 0) {
|
|
|
|
$createMeetingParams->setMaxParticipants($room->maxParticipants);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($presentation !== null && $presentation->isValid()) {
|
|
|
|
$createMeetingParams->addPresentation($presentation->getUrl(), null, $presentation->getFilename());
|
|
|
|
}
|
|
|
|
|
2020-06-04 18:56:55 +02:00
|
|
|
if ($room->access === Room::ACCESS_WAITING_ROOM) {
|
|
|
|
$createMeetingParams->setGuestPolicyAskModerator();
|
|
|
|
}
|
|
|
|
|
2020-05-16 17:14:17 +02:00
|
|
|
return $createMeetingParams;
|
|
|
|
}
|
2020-05-17 11:09:16 +02:00
|
|
|
|
|
|
|
public function getRecording(string $recordId)
|
|
|
|
{
|
|
|
|
$recordingParams = new GetRecordingsParameters();
|
|
|
|
$recordingParams->setRecordId($recordId);
|
|
|
|
$recordingParams->setState('any');
|
|
|
|
|
|
|
|
$response = $this->getServer()->getRecordings($recordingParams);
|
|
|
|
|
|
|
|
if (!$response->success()) {
|
|
|
|
throw new \Exception('Could not process get recording request');
|
|
|
|
}
|
|
|
|
|
|
|
|
$records = $response->getRecords();
|
|
|
|
|
|
|
|
if (count($records) === 0) {
|
|
|
|
throw new \Exception('Found no record with given id');
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->recordToArray($records[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getRecordings(Room $room)
|
|
|
|
{
|
|
|
|
$recordingParams = new GetRecordingsParameters();
|
|
|
|
$recordingParams->setMeetingId($room->uid);
|
|
|
|
$recordingParams->setState('processing,processed,published,unpublished');
|
|
|
|
|
|
|
|
$response = $this->getServer()->getRecordings($recordingParams);
|
|
|
|
|
|
|
|
if (!$response->success()) {
|
|
|
|
throw new \Exception('Could not process get recordings request');
|
|
|
|
}
|
|
|
|
|
|
|
|
$records = $response->getRecords();
|
|
|
|
|
|
|
|
return array_map(function ($record) {
|
|
|
|
return $this->recordToArray($record);
|
|
|
|
}, $records);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function deleteRecording(string $recordingId): bool
|
|
|
|
{
|
|
|
|
$deleteParams = new DeleteRecordingsParameters($recordingId);
|
|
|
|
|
|
|
|
$response = $this->getServer()->deleteRecordings($deleteParams);
|
|
|
|
|
|
|
|
return $response->isDeleted();
|
|
|
|
}
|
|
|
|
|
|
|
|
private function recordToArray(Record $record)
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
'id' => $record->getRecordId(),
|
|
|
|
'name' => $record->getName(),
|
|
|
|
'published' => $record->isPublished(),
|
|
|
|
'state' => $record->getState(),
|
|
|
|
'startTime' => $record->getStartTime(),
|
|
|
|
'participants' => $record->getParticipantCount(),
|
|
|
|
'type' => $record->getPlaybackType(),
|
|
|
|
'length' => $record->getPlaybackLength(),
|
|
|
|
'url' => $record->getPlaybackUrl(),
|
|
|
|
'metas' => $record->getMetas(),
|
|
|
|
];
|
|
|
|
}
|
2020-05-17 13:39:01 +02:00
|
|
|
|
|
|
|
public function check($url, $secret)
|
|
|
|
{
|
|
|
|
$server = new BigBlueButton($url, $secret);
|
|
|
|
|
|
|
|
$meetingParams = new IsMeetingRunningParameters('foobar');
|
|
|
|
|
|
|
|
try {
|
|
|
|
$response = $server->isMeetingRunning($meetingParams);
|
|
|
|
|
|
|
|
if (!$response->success() && !$response->failed()) {
|
|
|
|
return 'invalid-url';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$response->success()) {
|
|
|
|
return 'invalid-secret';
|
|
|
|
}
|
|
|
|
|
|
|
|
return 'success';
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
return 'invalid-url';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getVersion($url = null)
|
|
|
|
{
|
|
|
|
$server = $url === null ? $this->getServer() : new BigBlueButton($url, '');
|
|
|
|
|
|
|
|
return $server->getApiVersion()->getVersion();
|
|
|
|
}
|
2020-05-16 17:14:17 +02:00
|
|
|
}
|