From 024b9ea4e9960af79e7040cc64f7abccae1f4f98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ducoulombier?= Date: Thu, 25 Jun 2020 07:38:15 +0200 Subject: [PATCH] Zoom meeting recording file management - refs BT#17288 --- plugin/zoom/admin.php | 5 +- plugin/zoom/lang/english.php | 28 ++-- plugin/zoom/lang/french.php | 28 ++-- plugin/zoom/lib/API/JWTClient.php | 56 +++++++- plugin/zoom/lib/API/RecordingList.php | 36 +++++ plugin/zoom/lib/API/RecordingMeeting.php | 2 +- plugin/zoom/lib/File.php | 31 +++++ plugin/zoom/lib/Recording.php | 71 ++++++++++ plugin/zoom/lib/zoom_plugin.class.php | 164 ++++++++++++++++++++++- plugin/zoom/meeting.php | 147 ++++++++++---------- plugin/zoom/start.php | 2 +- plugin/zoom/view/admin.tpl | 30 ++++- plugin/zoom/view/meeting.tpl | 142 ++++++-------------- 13 files changed, 528 insertions(+), 214 deletions(-) create mode 100644 plugin/zoom/lib/API/RecordingList.php create mode 100644 plugin/zoom/lib/File.php create mode 100644 plugin/zoom/lib/Recording.php diff --git a/plugin/zoom/admin.php b/plugin/zoom/admin.php index 1d9fde4df5..62ee64e6ba 100644 --- a/plugin/zoom/admin.php +++ b/plugin/zoom/admin.php @@ -11,7 +11,7 @@ require_once __DIR__.'/config.php'; api_protect_admin_script(); -$tool_name = get_lang('ZoomVideoconference'); +$tool_name = get_lang('ZoomVideoconferences'); $plugin = ZoomPlugin::create(); @@ -49,6 +49,9 @@ $form->setDefaults([ $tpl = new Template($tool_name); $tpl->assign('meetings', $plugin->getPeriodMeetings($type, $startDate, $endDate)); +if ($plugin->get('enableCloudRecording')) { + $tpl->assign('recordings', $plugin->getRecordings($startDate, $endDate)); +} $tpl->assign('search_form', $form->returnForm()); $tpl->assign('content', $tpl->fetch('zoom/view/admin.tpl')); $tpl->display_one_col_template(); diff --git a/plugin/zoom/lang/english.php b/plugin/zoom/lang/english.php index 8106a0812f..dd843a092d 100755 --- a/plugin/zoom/lang/english.php +++ b/plugin/zoom/lang/english.php @@ -42,39 +42,38 @@ Will not work for a basic profile."; // please keep these lines alphabetically sorted $strings['AllCourseUsersWereRegistered'] = "All course students were registered"; -$strings['AllRecordingsWereCopiedToCourse'] = "All recordings were copied to the course"; $strings['Agenda'] = "Agenda"; -$strings['CopyAllRecordingsToCourse'] = "Copy all recordings to course"; $strings['CopyingJoinURL'] = "Copying join URL"; -$strings['CopyJoinURL'] = "Copy join URL"; -$strings['CopyRecordingToCourse'] = "Copy recording to course"; +$strings['CopyJoinAsURL'] = "Copy 'join as' URL"; +$strings['CopyToCourse'] = "Copy to course"; $strings['CouldNotCopyJoinURL'] = "Could not copy join URL"; $strings['Course'] = "Cours"; $strings['CreatedAt'] = "Created at"; +$strings['CreateLinkInCourse'] = "Create link(s) in course"; $strings['DeleteMeeting'] = "Delete meeting"; -$strings['DeleteRecordings'] = "Delete recordings"; +$strings['DeleteFile'] = "Delete file(s)"; $strings['Details'] = "Details"; +$strings['DoIt'] = "Do it"; $strings['Duration'] = "Duration"; $strings['DurationFormat'] = "%hh%I"; $strings['DurationInMinutes'] = "Duration (in minutes)"; $strings['EndDate'] = "End Date"; +$strings['Files'] = "Files"; $strings['Finished'] = "finished"; +$strings['FileWasCopiedToCourse'] = "The file was copied to the course"; +$strings['FileWasDeleted'] = "The file was deleted"; $strings['InstantMeeting'] = "Instant meeting"; -$strings['InstanceParticipants'] = "Participants"; -$strings['InstancesAndRecordings'] = "Instances et enregistrements"; $strings['Join'] = "Join"; -$strings['JoinMeeting'] = "Join meeting"; -$strings['JoinURL'] = "Join URL"; +$strings['JoinMeetingAsMyself'] = "Join meeting as myself"; $strings['JoinURLCopied'] = "Join URL copied"; $strings['JoinURLToSendToParticipants'] = "Join URL to send to participants"; -$strings['JoinURLToShare'] = "Join URL to share"; $strings['LiveMeetings'] = "Live meetings"; +$strings['LinkToFileWasCreatedInCourse'] = "A link to the file was added to the course"; $strings['MeetingDeleted'] = "Meeting deleted"; +$strings['MeetingsFound'] = "Meetings found"; $strings['MeetingUpdated'] = "Meeting updated"; $strings['NewMeetingCreated'] = "New meeting created"; $strings['Password'] = "Password"; -$strings['RecordingsWereDeleted'] = "Recordings were deleted"; -$strings['RecordingWasCopiedToCourse'] = "The recording was copied to the course"; $strings['RecurringWithFixedTime'] = "Recurring with fixed time"; $strings['RecurringWithNoFixedTime'] = "Recurring with no fixed time"; $strings['RegisterAllCourseUsers'] = "Register all course users"; @@ -93,12 +92,11 @@ $strings['StartMeeting'] = "Start meeting"; $strings['StartTime'] = "Start time"; $strings['Topic'] = "Topic"; $strings['TopicAndAgenda'] = "Topic and agenda"; -$strings['TotalSize'] = "Total size"; $strings['Type'] = "Type"; $strings['UpcomingMeetings'] = "Upcoming meetings"; $strings['UpdateMeeting'] = "Update meeting"; $strings['UpdateRegisteredUserList'] = "Update registered user list"; $strings['Y-m-d H:i'] = "Y-m-d H:i"; $strings['Waiting'] = "waiting"; -$strings['ZoomVideoconference'] = "Zoom Videoconference"; -$strings['ZoomVideoconferences'] = "Zoom Videoconferences"; +$strings['XRecordingOfMeetingXFromXDurationXDotX'] = "%s recording of meeting %s from %s (%s).%s"; +$strings['ZoomVideoConferences'] = "Zoom Video Conferences"; diff --git a/plugin/zoom/lang/french.php b/plugin/zoom/lang/french.php index 68f375362e..21b8ca44ac 100755 --- a/plugin/zoom/lang/french.php +++ b/plugin/zoom/lang/french.php @@ -41,39 +41,38 @@ Ne fonctionnera pas pour un profil de base."; // please keep these lines alphabetically sorted $strings['AllCourseUsersWereRegistered'] = "Tous les étudiants du cours sont inscrits"; -$strings['AllRecordingsWereCopiedToCourse'] = "Tous les enregistrements ont été copiés dans le cours"; $strings['Agenda'] = "Ordre du jour"; -$strings['CopyAllRecordingsToCourse'] = "Copier tous les enregistrements dans le cours"; $strings['CopyingJoinURL'] = "Copie de l'URL pour rejoindre en cours"; -$strings['CopyJoinURL'] = "Copier l'URL pour rejoindre"; -$strings['CopyRecordingToCourse'] = "Copier l'enregistrement dans le cours"; +$strings['CopyJoinAsURL'] = "Copier l'URL pour 'rejoindre en tant que'"; +$strings['CopyToCourse'] = "Copier dans le cours"; $strings['CouldNotCopyJoinURL'] = "Échec de la copie de l'URL pour rejoindre"; $strings['Course'] = "Cours"; $strings['CreatedAt'] = "Créé à"; +$strings['CreateLinkInCourse'] = "Créer dans le cours un ou des lien(s) vers le(s) fichier(s)"; $strings['DeleteMeeting'] = "Effacer la conférence"; -$strings['DeleteRecordings'] = "Supprimer l'enregistrement"; +$strings['DeleteFile'] = "Supprimer ce(s) fichier(s)"; $strings['Details'] = "Détail"; +$strings['DoIt'] = "Fais-le"; $strings['Duration'] = "Durée"; $strings['DurationFormat'] = "%hh%I"; $strings['DurationInMinutes'] = "Durée (en minutes)"; $strings['EndDate'] = "Date de fin"; +$strings['Files'] = "Fichiers"; $strings['Finished'] = "terminée"; +$strings['FileWasCopiedToCourse'] = "Le fichier a été copié dans le cours"; +$strings['FileWasDeleted'] = "Le fichier a été effacé"; $strings['InstantMeeting'] = "Conférence instantanée"; -$strings['InstanceParticipants'] = "Participants"; -$strings['InstancesAndRecordings'] = "Instances et enregistrements"; $strings['Join'] = "Rejoindre"; -$strings['JoinMeeting'] = "Rejoindre la conférence"; -$strings['JoinURL'] = "URL pour rejoindre"; +$strings['JoinMeetingAsMyself'] = "Rejoindre la conférence en tant que moi-même"; $strings['JoinURLCopied'] = "URL pour rejoindre copiée"; $strings['JoinURLToSendToParticipants'] = "URL pour assister à la conférence (à envoyer aux participants)"; -$strings['JoinURLToShare'] = "URL pour rejoindre, à partager"; $strings['LiveMeetings'] = "Conférences en cours"; +$strings['LinkToFileWasCreatedInCourse'] = "A link to the file was added to the course"; $strings['MeetingDeleted'] = "Conférence effacée"; +$strings['MeetingsFound'] = "Conférences trouvées"; $strings['MeetingUpdated'] = "Conférence mise à jour"; $strings['NewMeetingCreated'] = "Nouvelle conférence créée"; $strings['Password'] = "Mot de passe"; -$strings['RecordingsWereDeleted'] = "Les enregistrements ont été supprimés"; -$strings['RecordingWasCopiedToCourse'] = "L'enregistrement a été copié dans le cours"; $strings['RecurringWithFixedTime'] = "Recurrent, à heure fixe"; $strings['RecurringWithNoFixedTime'] = "Recurrent, sans heure fixe"; $strings['RegisterAllCourseUsers'] = "Inscrire tous les utilisateurs du cours"; @@ -88,16 +87,15 @@ $strings['Session'] = "Session"; $strings['StartDate'] = "Date de début"; $strings['Started'] = "démarrée"; $strings['StartInstantMeeting'] = "Démarrer une conférence instantanée"; -$strings['StartMeeting'] = "démarrer la conférence"; +$strings['StartMeeting'] = "Démarrer la conférence"; $strings['StartTime'] = "Heure de début"; $strings['Topic'] = "Objet"; $strings['TopicAndAgenda'] = "Objet et ordre du jour"; -$strings['TotalSize'] = "Taille totale"; $strings['Type'] = "Type"; $strings['UpcomingMeeting'] = "Conférences à venir"; $strings['UpdateMeeting'] = "Mettre à jour la conférence"; $strings['UpdateRegisteredUserList'] = "Mettre à jour la liste des utilisateurs inscrits"; $strings['Y-m-d H:i'] = "d/m/Y à H\hi"; $strings['Waiting'] = "en attente"; -$strings['ZoomVideoconference'] = "Conférence vidéo Zoom"; +$strings['XRecordingOfMeetingXFromXDurationXDotX'] = "Enregistrement (%s) de la conférence %s de %s (%s).%s"; $strings['ZoomVideoconferences'] = "Conférences vidéo Zoom"; diff --git a/plugin/zoom/lib/API/JWTClient.php b/plugin/zoom/lib/API/JWTClient.php index 8074fa1211..1e718ba091 100755 --- a/plugin/zoom/lib/API/JWTClient.php +++ b/plugin/zoom/lib/API/JWTClient.php @@ -3,6 +3,7 @@ namespace Chamilo\PluginBundle\Zoom\API; +use DateTime; use Exception; use Firebase\JWT\JWT; @@ -294,7 +295,7 @@ class JWTClient * * @return RecordingMeeting the recordings for this meeting */ - public function getRecordings($instanceUUID) + public function getInstanceRecordings($instanceUUID) { return RecordingMeeting::fromJson( $this->send( @@ -304,6 +305,29 @@ class JWTClient ); } + /** + * Lists All Recordings. + * + * @param DateTime $startDate + * @param DateTime $endDate + * + * @throws Exception + * + * @return RecordingMeeting[] list of all recordings + */ + public function getRecordings($startDate, $endDate) + { + return $this->getFullList( + '/users/me/recordings', + RecordingList::class, + 'meetings', + [ + 'from' => $startDate->format('Y-m-d'), + 'to' => $endDate->format('Y-m-d'), + ] + ); + } + /** * Deletes a meetings recordings. * @@ -316,6 +340,23 @@ class JWTClient $this->send('DELETE', 'meetings/'.$this->doubleEncode($instanceUUID).'/recordings', ['action' => 'delete']); } + /** + * Deletes a meeting instance recording file. + * + * @param int $meetingId + * @param string $fileId + * + * @throws Exception + */ + public function deleteRecordingFile($meetingId, $fileId) + { + $this->send( + 'DELETE', + "/meetings/$meetingId/recordings/$fileId", + ['action' => 'delete'] + ); + } + /** * Retrieves information on participants from a past meeting. * @@ -334,6 +375,19 @@ class JWTClient ); } + /** + * Builds the recording file download URL with the access_token query parameter + * @see RecordingFile::$download_url + * + * @param $recordingFile RecordingFile + * + * @return string full URL + */ + public function getRecordingFileDownloadURL($recordingFile) + { + return $recordingFile->download_url.'?access_token='.$this->token; + } + /** * Retrieves a full list of items using one or more API calls to the Zoom server. * diff --git a/plugin/zoom/lib/API/RecordingList.php b/plugin/zoom/lib/API/RecordingList.php new file mode 100644 index 0000000000..b52b99ff35 --- /dev/null +++ b/plugin/zoom/lib/API/RecordingList.php @@ -0,0 +1,36 @@ +meetings = []; + } + + /** + * @inheritDoc + */ + public function itemClass($propertyName) + { + if ('meetings' === $propertyName) { + return RecordingMeeting::class; + } + throw new Exception("No such array property $propertyName"); + } +} diff --git a/plugin/zoom/lib/API/RecordingMeeting.php b/plugin/zoom/lib/API/RecordingMeeting.php index 2841b038ea..c221e59749 100644 --- a/plugin/zoom/lib/API/RecordingMeeting.php +++ b/plugin/zoom/lib/API/RecordingMeeting.php @@ -51,7 +51,7 @@ class RecordingMeeting /** * RecordingMeeting constructor. */ - protected function __construct() + public function __construct() { $this->recording_files = []; } diff --git a/plugin/zoom/lib/File.php b/plugin/zoom/lib/File.php new file mode 100644 index 0000000000..3f04945a43 --- /dev/null +++ b/plugin/zoom/lib/File.php @@ -0,0 +1,31 @@ +formattedFileSize = format_file_size($instance->file_size); + + return $instance; + } +} diff --git a/plugin/zoom/lib/Recording.php b/plugin/zoom/lib/Recording.php new file mode 100644 index 0000000000..9f84de0970 --- /dev/null +++ b/plugin/zoom/lib/Recording.php @@ -0,0 +1,71 @@ +recording_files as $file) { + $newRecordingFiles[] = File::fromRecordingFile($file); + } + $instance->recording_files = $newRecordingFiles; + + $instance->startDateTime = new DateTime($instance->start_time); + $instance->startDateTime->setTimezone(new DateTimeZone(date_default_timezone_get())); + $instance->formattedStartTime = $instance->startDateTime->format(get_lang('Y-m-d H:i')); + + $now = new DateTime(); + $later = new DateTime(); + $later->add(new DateInterval('PT'.$instance->duration.'M')); + $instance->durationInterval = $later->diff($now); + $instance->formattedDuration = $instance->durationInterval->format(get_lang('DurationFormat')); + + return $instance; + } + + /** + * {@inheritdoc} + */ + public function itemClass($propertyName) + { + if ('recording_files' === $propertyName) { + return File::class; + } + return parent::itemClass($propertyName); + } +} diff --git a/plugin/zoom/lib/zoom_plugin.class.php b/plugin/zoom/lib/zoom_plugin.class.php index 4d76ea3407..8bc2cb9a60 100755 --- a/plugin/zoom/lib/zoom_plugin.class.php +++ b/plugin/zoom/lib/zoom_plugin.class.php @@ -8,10 +8,11 @@ use Chamilo\PluginBundle\Zoom\API\MeetingInstance; use Chamilo\PluginBundle\Zoom\API\MeetingSettings; use Chamilo\PluginBundle\Zoom\API\ParticipantListItem; use Chamilo\PluginBundle\Zoom\API\PastMeeting; -use Chamilo\PluginBundle\Zoom\API\RecordingMeeting; use Chamilo\PluginBundle\Zoom\CourseMeeting; use Chamilo\PluginBundle\Zoom\CourseMeetingInfoGet; use Chamilo\PluginBundle\Zoom\CourseMeetingListItem; +use Chamilo\PluginBundle\Zoom\File; +use Chamilo\PluginBundle\Zoom\Recording; use Chamilo\PluginBundle\Zoom\UserMeetingRegistrant; use Chamilo\PluginBundle\Zoom\UserMeetingRegistrantListItem; @@ -277,17 +278,62 @@ class ZoomPlugin extends Plugin } /** - * @see JWTClient::getRecordings() + * Retrieves an instance's recording. * - * @param string $instanceUUID + * @param string $instanceUUID instance UUID * * @throws Exception on API error * - * @return RecordingMeeting the recordings of the meeting + * @return Recording the recording of the meeting + */ + public function getInstanceRecording($instanceUUID) + { + return Recording::fromRecodingMeeting($this->jwtClient()->getInstanceRecordings($instanceUUID)); + } + + /** + * Retrieves all recordings. + * + * @param DateTime $startDate start date + * @param DateTime $endDate end date + * + * @throws Exception + * + * @return Recording[] all recordings + */ + public function getRecordings($startDate, $endDate) + { + $recordings = []; + foreach ($this->jwtClient()->getRecordings($startDate, $endDate) as $recording) { + $recordings[] = Recording::fromRecodingMeeting($recording); + } + + return $recordings; + } + + /** + * Retrieves a meetings instances' recordings. + * + * @param CourseMeetingInfoGet $meeting + * + * @throws Exception + * + * @return Recording[] meeting instances' recordings */ - public function getRecordings($instanceUUID) + public function getMeetingRecordings($meeting) { - return $this->jwtClient()->getRecordings($instanceUUID); + $interval = new DateInterval('P1M'); + $startDate = clone $meeting->startDateTime; + $startDate->sub($interval); + $endDate = clone $meeting->startDateTime; + $endDate->add($interval); + $recordings = []; + foreach ($this->getRecordings($startDate, $endDate) as $recording) { + if ($recording->id == $meeting->id) { + $recordings[] = $recording; + } + } + return $recordings; } /** @@ -393,6 +439,97 @@ class ZoomPlugin extends Plugin $this->removeRegistrants($meetingId, $registrantsToRemove); } + /** + * Adds to the meeting course documents a link to a meeting instance recording file. + * + * @param CourseMeetingInfoGet $meeting + * @param File $file + * @param string $name + * + * @throws Exception + */ + public function createLinkToFileInCourse($meeting, $file, $name) + { + $courseInfo = api_get_course_info_by_id($meeting->courseId); + if (empty($courseInfo)) { + throw new Exception('This meeting is not linked to a valid course'); + } + $path = '/zoom_meeting_recording_file_'.$file->id.'.'.$file->file_type; + $docId = DocumentManager::addCloudLink($courseInfo, $path, $file->play_url, $name); + if (!$docId) { + throw new Exception( + DocumentManager::cloudLinkExists($courseInfo, $path, $file->play_url) + ? get_lang('UrlAlreadyExists') + : get_lang('ErrorAddCloudLink') + ); + } + } + + /** + * Copies a recording file to a meeting's course. + * + * @param CourseMeetingInfoGet $meeting + * @param File $file + * @param string $name + * + * @throws Exception + */ + public function copyFileToCourse($meeting, $file, $name) + { + $courseInfo = api_get_course_info_by_id($meeting->courseId); + if (empty($courseInfo)) { + throw new Exception('This meeting is not linked to a valid course'); + } + $tmpFile = tmpfile(); + if (false === $tmpFile) { + throw new Exception('tmpfile() returned false'); + } + $curl = curl_init($this->jwtClient()->getRecordingFileDownloadURL($file)); + if (false === $curl) { + throw new Exception('Could not init curl: '.curl_error($curl)); + } + if (!curl_setopt_array( + $curl, + [ + CURLOPT_FILE => $tmpFile, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 120, + ] + )) { + throw new Exception("Could not set curl options: ".curl_error($curl)); + } + if (false === curl_exec($curl)) { + throw new Exception("curl_exec failed: ".curl_error($curl)); + } + $newPath = handle_uploaded_document( + $courseInfo, + [ + 'name' => $name, + 'tmp_name' => stream_get_meta_data($tmpFile)['uri'], + 'size' => filesize(stream_get_meta_data($tmpFile)['uri']), + 'from_file' => true, + 'type' => $file->file_type, + ], + '/', + api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/document', + api_get_user_id(), + 0, + null, + 0, + '', + true, + false, + null, + $meeting->sessionId, + true + ); + fclose($tmpFile); + if (false === $newPath) { + throw new Exception('could not handle uploaded document'); + } + } + /** * Deletes a meeting instance's recordings. * @@ -400,11 +537,24 @@ class ZoomPlugin extends Plugin * * @throws Exception */ - public function deleteRecordings($instanceUUID) + public function deleteInstanceRecordings($instanceUUID) { $this->jwtClient()->deleteRecordings($instanceUUID); } + /** + * Deletes a meeting instance recording file. + * + * @param int $meetingId + * @param string $fileId + * + * @throws Exception + */ + public function deleteFile($meetingId, $fileId) + { + $this->jwtClient()->deleteRecordingFile($meetingId, $fileId); + } + /** * Caches and returns the JWT client instance, initialized with plugin settings. * diff --git a/plugin/zoom/meeting.php b/plugin/zoom/meeting.php index a0d0de8c6e..8fd0f541d7 100755 --- a/plugin/zoom/meeting.php +++ b/plugin/zoom/meeting.php @@ -101,8 +101,6 @@ if ($plugin->userIsConferenceManager()) { if ($plugin->get('enableParticipantRegistration') && MeetingSettings::APPROVAL_TYPE_NO_REGISTRATION_REQUIRED != $meeting->settings->approval_type) { - $tpl->assign('enableParticipantRegistration', true); - $registerParticipantForm = new FormValidator('registerParticipantForm', 'post', $_SERVER['REQUEST_URI']); $userIdSelect = $registerParticipantForm->addSelect('userIds', get_lang('RegisteredUsers')); $userIdSelect->setMultiple(true); @@ -155,83 +153,86 @@ if ($plugin->userIsConferenceManager()) { && 'cloud' === $meeting->settings->auto_recording // && 'finished' === $meeting->status ) { - $instances = []; - foreach ($plugin->getEndedMeetingInstances($meeting->id) as $instance) { - // $instance->instanceDetails = $plugin->getPastMeetingInstanceDetails($instance->uuid); - try { - $instance->recordings = $plugin->getRecordings($instance->uuid); - } catch (Exception $exception) { - Display::addFlash( - Display::return_message($exception->getMessage(), 'error') - ); + $recordings = $plugin->getMeetingRecordings($meeting); + $fileForm = new FormValidator('fileForm', 'post', $_SERVER['REQUEST_URI']); + $fileIdSelect = $fileForm->addSelect('fileIds', get_lang('Files')); + $fileIdSelect->setMultiple(true); + foreach ($recordings as &$recording) { + // $recording->instanceDetails = $plugin->getPastMeetingInstanceDetails($instance->uuid); + $options = []; + foreach ($recording->recording_files as $file) { + $options[] = [ + 'text' => sprintf("%s.%s (%s)", $file->recording_type, $file->file_type, $file->formattedFileSize), + 'value' => $file->id + ]; } - foreach ($instance->recordings->recording_files as &$file) { - $copyToCourseForm = new FormValidator( - 'copyToCourseForm'.$file->id, - 'post', - $_SERVER['REQUEST_URI'] - ); - $copyToCourseForm->addButtonCopy(get_lang('CopyRecordingToCourse')); - if ($copyToCourseForm->validate()) { - try { - $plugin->copyRecordingToCourse($meeting, $file); - Display::addFlash( - Display::return_message(get_lang('RecordingWasCopiedToCourse'), 'confirm') - ); - } catch (Exception $exception) { - Display::addFlash( - Display::return_message($exception->getMessage(), 'error') + $fileIdSelect->addOptGroup( + $options, + sprintf("%s (%s)", $recording->formattedStartTime, $recording->formattedDuration) + ); + } + $actionRadio = $fileForm->addRadio( + 'action', + get_lang('Action'), + [ + 'CreateLinkInCourse' => get_lang('CreateLinkInCourse'), + 'CopyToCourse' => get_lang('CopyToCourse'), + 'DeleteFile' => get_lang('DeleteFile'), + ] + ); + $fileForm->addButtonUpdate(get_lang('DoIt')); + if ($fileForm->validate()) { + foreach ($recordings as $recording) { + foreach ($recording->recording_files as $file) { + if (in_array($file->id, $fileIdSelect->getValue())) { + $name = sprintf( + get_lang('XRecordingOfMeetingXFromXDurationXDotX'), + $file->recording_type, + $meeting->id, + $recording->formattedStartTime, + $recording->formattedDuration, + $file->file_type ); + if ('CreateLinkInCourse' === $actionRadio->getValue()) { + try { + $plugin->createLinkToFileInCourse($meeting, $file, $name); + Display::addFlash( + Display::return_message(get_lang('LinkToFileWasCreatedInCourse'), 'success') + ); + } catch (Exception $exception) { + Display::addFlash( + Display::return_message($exception->getMessage(), 'error') + ); + } + } elseif ('CopyToCourse' === $actionRadio->getValue()) { + try { + $plugin->copyFileToCourse($meeting, $file, $name); + Display::addFlash( + Display::return_message(get_lang('FileWasCopiedToCourse'), 'confirm') + ); + } catch (Exception $exception) { + Display::addFlash( + Display::return_message($exception->getMessage(), 'error') + ); + } + } elseif ('DeleteFile' === $actionRadio->getValue()) { + try { + $plugin->deleteFile($meeting->id, $file->id); + Display::addFlash( + Display::return_message(get_lang('FileWasDeleted'), 'confirm') + ); + } catch (Exception $exception) { + Display::addFlash( + Display::return_message($exception->getMessage(), 'error') + ); + } + } } } - $file->copyToCourseForm = $copyToCourseForm->returnForm(); - } - - $copyAllRecordingsToCourseForm = new FormValidator( - 'copyAllRecordingsToCourseForm'.$instance->uuid, - 'post', - $_SERVER['REQUEST_URI'] - ); - $copyAllRecordingsToCourseForm->addButtonCopy(get_lang('CopyAllRecordingsToCourse')); - if ($copyAllRecordingsToCourseForm->validate()) { - try { - $plugin->copyAllRecordingsToCourse($instance->uuid); - Display::addFlash( - Display::return_message(get_lang('AllRecordingsWereCopiedToCourse'), 'confirm') - ); - } catch (Exception $exception) { - Display::addFlash( - Display::return_message($exception->getMessage(), 'error') - ); - } } - $instance->copyAllRecordingsToCourseForm = $copyAllRecordingsToCourseForm->returnForm(); - - $deleteRecordingsForm = new FormValidator( - 'deleteRecordingsForm'.$instance->uuid, - 'post', - $_SERVER['REQUEST_URI'] - ); - $deleteRecordingsForm->addButtonSend(get_lang('DeleteRecordings')); - if ($deleteRecordingsForm->validate()) { - try { - $plugin->deleteRecordings($instance->uuid); - Display::addFlash( - Display::return_message(get_lang('RecordingsWereDeleted'), 'confirm') - ); - } catch (Exception $exception) { - Display::addFlash( - Display::return_message($exception->getMessage(), 'error') - ); - } - } - $instance->deleteRecordingsForm = $deleteRecordingsForm->returnForm(); - - // $instance->participants = $plugin->getParticipants($instance->uuid); - - $instances[] = $instance; } - $tpl->assign('instances', $instances); + $tpl->assign('recordings', $recordings); + $tpl->assign('fileForm', $fileForm->returnForm()); } } elseif (MeetingSettings::APPROVAL_TYPE_NO_REGISTRATION_REQUIRED != $meeting->settings->approval_type) { $userId = api_get_user_id(); diff --git a/plugin/zoom/start.php b/plugin/zoom/start.php index 02d8341756..5ee0bb571b 100755 --- a/plugin/zoom/start.php +++ b/plugin/zoom/start.php @@ -16,7 +16,7 @@ $logInfo = [ Event::registerLog($logInfo); -$tool_name = get_lang('ZoomVideoconference'); +$tool_name = get_lang('ZoomVideoconferences'); $tpl = new Template($tool_name); $plugin = ZoomPlugin::create(); diff --git a/plugin/zoom/view/admin.tpl b/plugin/zoom/view/admin.tpl index 6b22aaaebe..00745df5e0 100644 --- a/plugin/zoom/view/admin.tpl +++ b/plugin/zoom/view/admin.tpl @@ -1,11 +1,15 @@ {{ search_form }} + + {% if recordings %} + + {% endif %} @@ -16,6 +20,30 @@ + {% if recordings %} + + {% endif %} {% endfor %} -
{{ 'MeetingsFound'|get_lang }}
{{ 'StartTime'|get_lang }} {{ 'Course'|get_lang }} {{ 'Session'|get_lang }} {{ 'Topic'|get_lang }}{{ 'Recordings'|get_lang }}
{{ meeting.course ? meeting.course.title : '-' }} {{ meeting.session ? meeting.session.name : '-' }} {{ meeting.topic }} + {% for recording in recordings %} + {% if recording.id == meeting.id %} +
+
+ {{ recording.formattedStartTime }} + ({{ recording.formattedDuration }}) +
+
+
    + {% for file in recording.recording_files %} +
  • + {{ file.recording_type }}.{{ file.file_type }} + ({{ file.formattedFileSize }}) +
  • + {% endfor %} +
+
+
+ {% endif %} + {% endfor %} +
{{ 'Details'|get_lang }} @@ -24,4 +52,4 @@
+ \ No newline at end of file diff --git a/plugin/zoom/view/meeting.tpl b/plugin/zoom/view/meeting.tpl index 7165ceb01a..806a4a5d86 100644 --- a/plugin/zoom/view/meeting.tpl +++ b/plugin/zoom/view/meeting.tpl @@ -1,23 +1,8 @@

{{ meeting.typeName }} {{ meeting.id }} ({{ meeting.statusName }})

-

{{ meeting.topic }}

-{% if meeting.agenda %} -
{{ meeting.agenda| nl2br }}
-{% endif %} - - -{% if meeting.type == 2 or meeting.type == 8 %} -
-
{{ 'StartTime'|get_lang }}
-
{{ meeting.formattedStartTime }}
- -
{{ 'Duration'|get_lang }}
-
{{ meeting.formattedDuration }}
-
-{% endif %} {% if isConferenceManager and meeting.status == 'waiting' %}

- + {{ 'StartMeeting'|get_lang }}

@@ -25,8 +10,8 @@ {% if currentUserJoinURL %}

- - {{ 'JoinMeeting'|get_lang }} + + {{ 'JoinMeetingAsMyself'|get_lang }}

{% endif %} @@ -34,101 +19,60 @@ {% if meeting.settings.approval_type == 2 %}

{% endif %} -{% if instances %} -

{{ 'InstancesAndRecordings'|get_lang }}

-{% for instance in instances %} -
-

{{ instance.start_time }} ({{ instance.recordings.duration }} minutes)

- - {{ instance.recordings.recording_count }} recordings - {{ instance.deleteRecordingsForm }} - - - {% for file in instance.recordings.recording_files %} - - - - - - {% endfor %} - - - - -
{{ file.file_type }} - - - Play {{file.recording_type}} - - - Download {{ file.file_size }} bytes - - {{ file.copyToCourseForm }} -
- {{ 'TotalSize'|get_lang }} {{ instance.recordings.total_size }} bytes - - {{ instance.copyAllRecordingsToCourseForm }} -
- {% if instance.participants %} -

{{ 'InstanceParticipants'|get_lang }}

- - {% endif %} -
-{% endfor %} -{% endif %} -{% if registrants and isConferenceManager %} +{% if isConferenceManager %} + +{{ editMeetingForm }} +{{ deleteMeetingForm }} +{{ registerParticipantForm }} +{{ fileForm }} +{% if registrants and meeting.settings.approval_type != 2 %} - - - - - + - - - +
  • + + {{ 'CopyJoinAsURL'|get_lang }} + + {{ registrant.fullName }} +
  • {% endfor %} -
    {{ 'RegisteredUsers'|get_lang }}{{ 'JoinURL'|get_lang }}
    - {{ registrant.fullName }} - - - {{ 'CopyJoinURL'|get_lang }} - -
    + +{% endif %} + {% else %} -

    - {{ 'JoinURLToSendToParticipants'|get_lang }} - {{meeting.join_url}} -

    + +

    {{ meeting.topic }}

    +{% if meeting.agenda %} +
    {{ meeting.agenda| nl2br }}
    {% endif %} -{% if isConferenceManager %} -{{ editMeetingForm }} -{{ deleteMeetingForm }} -{% if enableParticipantRegistration %} -{{ registerParticipantForm }} +{% if meeting.type == 2 or meeting.type == 8 %} +
    +
    {{ 'StartTime'|get_lang }}
    +
    {{ meeting.formattedStartTime }}
    + +
    {{ 'Duration'|get_lang }}
    +
    {{ meeting.formattedDuration }}
    +
    {% endif %} + {% endif %} +