diff --git a/plugin/zoom/Entity/Meeting.php b/plugin/zoom/Entity/Meeting.php index 72b7de925d..f2995f385e 100644 --- a/plugin/zoom/Entity/Meeting.php +++ b/plugin/zoom/Entity/Meeting.php @@ -245,7 +245,31 @@ class Meeting */ public function getRegistrants() { - return $this->registrants; + return $this->registrants->filter(function (Registrant $registrant) { + return !$registrant instanceof Presenter; + }); + } + + /** + * @return ArrayCollection + */ + public function getPresenters(): ArrayCollection + { + return $this->registrants->filter(function (Registrant $registrant) { + return $registrant instanceof Presenter; + }); + } + + public function hasUserAsPresenter(User $user): bool + { + $presenters = $this->getPresenters(); + + $criteria = Criteria::create(); + $criteria->where( + Criteria::expr()->eq('user', $user) + ); + + return $presenters->matching($criteria)->count() > 0; } /** diff --git a/plugin/zoom/Entity/Presenter.php b/plugin/zoom/Entity/Presenter.php new file mode 100644 index 0000000000..21b417fae4 --- /dev/null +++ b/plugin/zoom/Entity/Presenter.php @@ -0,0 +1,38 @@ +id); + } + + /** + * @ORM\PostLoad() + * + * @throws Exception + */ + public function postLoad() + { + parent::postLoad(); + } + + /** + * @ORM\PreFlush() + */ + public function preFlush() + { + parent::preFlush(); + } +} diff --git a/plugin/zoom/Entity/Registrant.php b/plugin/zoom/Entity/Registrant.php index ce30d70cf7..f65bdc7875 100644 --- a/plugin/zoom/Entity/Registrant.php +++ b/plugin/zoom/Entity/Registrant.php @@ -23,6 +23,9 @@ use Exception; * } * ) * @ORM\HasLifecycleCallbacks + * @ORM\InheritanceType("SINGLE_TABLE") + * @ORM\DiscriminatorColumn(name="type", type="string") + * @ORM\DiscriminatorMap({"registrant" = "Chamilo\PluginBundle\Zoom\Registrant", "presenter" = "Chamilo\PluginBundle\Zoom\Presenter"}) */ class Registrant { diff --git a/plugin/zoom/lang/english.php b/plugin/zoom/lang/english.php index 7d956f6c7f..5cfe0af28f 100755 --- a/plugin/zoom/lang/english.php +++ b/plugin/zoom/lang/english.php @@ -21,6 +21,8 @@ $strings[ZoomPlugin::SETTING_CLIENT_SECRET.'_help'] = 'For a Server-to-Server OA $strings[ZoomPlugin::SETTING_SECRET_TOKEN] = 'Secret token'; $strings[ZoomPlugin::SETTING_SECRET_TOKEN.'_help'] = 'For a Server-to-Server OAuth application type'; $strings['enableParticipantRegistration'] = 'Enable participant registration'; +$strings['enablePresenter'] = 'Enable presenter'; +$strings['enablePresenter_help'] = 'It requires that Enable participant registration settings is enabled.'; $strings['enableCloudRecording'] = 'Automatic recording type'; $strings['enableGlobalConference'] = 'Enable global conference'; $strings['enableGlobalConferencePerUser'] = 'Enable global conference per user'; @@ -132,6 +134,7 @@ $strings['RecurringWithNoFixedTime'] = "Recurring with no fixed time"; $strings['RegisterAllCourseUsers'] = "Register all course users"; $strings['RegisteredUserListWasUpdated'] = "Registered user list updated"; $strings['RegisteredUsers'] = "Registered users"; +$strings['RegisteredPresenters'] = "Registered presenters"; $strings['RegisterNoUser'] = "Register no user"; $strings['RegisterTheseGroupMembers'] = "Register these group members"; $strings['ScheduleAMeeting'] = "Schedule a meeting"; @@ -185,3 +188,4 @@ $strings['WebinarDeleted'] = "Webinar deleted"; $strings['UrlForSelfRegistration'] = "URL for self registration"; $strings['RegisterMeToConference'] = "Register me to conference"; $strings['UnregisterMeToConference'] = "Unregister me to conference"; +$strings['Presenters'] = "Presenters"; diff --git a/plugin/zoom/lang/spanish.php b/plugin/zoom/lang/spanish.php index 7e2f8100dc..3ebb6ce9cd 100644 --- a/plugin/zoom/lang/spanish.php +++ b/plugin/zoom/lang/spanish.php @@ -9,6 +9,8 @@ $strings['tool_enable'] = 'Herramienta activada'; $strings['apiKey'] = "Clave API (API Key)"; $strings['apiSecret'] = "Código secreto de API (API Secret)"; $strings['enableParticipantRegistration'] = "Activar la inscripción de participantes"; +$strings['enablePresenter'] = 'Activar presentadores'; +$strings['enablePresenter_help'] = 'Require que It requires that Enable participant registration settings is enabled.'; $strings['enableCloudRecording'] = "Tipo de grabación automática"; $strings['enableGlobalConference'] = "Activar las conferencias globales"; $strings['enableGlobalConferencePerUser'] = "Activar las conferencias globales por usuario"; @@ -119,6 +121,7 @@ $strings['RecurringWithNoFixedTime'] = "Recurrente, sin hora fija"; $strings['RegisterAllCourseUsers'] = "Inscribir todos los usuarios del curso"; $strings['RegisteredUserListWasUpdated'] = "Lista de usuarios inscritos actualizada"; $strings['RegisteredUsers'] = "Usuarios inscritos"; +$strings['RegisteredPresenters'] = "Presentadores registrados"; $strings['RegisterNoUser'] = "No inscribir ningún usuario"; $strings['RegisterTheseGroupMembers'] = "Inscribir los miembros de estos grupos"; $strings['ScheduleAMeeting'] = "Programar una conferencia"; @@ -168,3 +171,4 @@ $strings['WebinarDeleted'] = "Seminario web borrado"; $strings['UrlForSelfRegistration'] = "URL para auto registro"; $strings['RegisterMeToConference'] = "Registrarme a la conferencia"; $strings['UnregisterMeToConference'] = "Cancelar registro a la conferencia"; +$strings['Presenters'] = "Presentadores"; diff --git a/plugin/zoom/lib/ZoomPlugin.php b/plugin/zoom/lib/ZoomPlugin.php index 29fa5c1bc2..65db1d7398 100644 --- a/plugin/zoom/lib/ZoomPlugin.php +++ b/plugin/zoom/lib/ZoomPlugin.php @@ -19,6 +19,7 @@ use Chamilo\PluginBundle\Zoom\API\WebinarSettings; use Chamilo\PluginBundle\Zoom\Meeting; use Chamilo\PluginBundle\Zoom\MeetingActivity; use Chamilo\PluginBundle\Zoom\MeetingRepository; +use Chamilo\PluginBundle\Zoom\Presenter; use Chamilo\PluginBundle\Zoom\Recording; use Chamilo\PluginBundle\Zoom\RecordingRepository; use Chamilo\PluginBundle\Zoom\Registrant; @@ -71,6 +72,7 @@ class ZoomPlugin extends Plugin self::SETTING_CLIENT_SECRET => 'text', self::SETTING_SECRET_TOKEN => 'text', 'enableParticipantRegistration' => 'boolean', + 'enablePresenter' => 'boolean', 'enableCloudRecording' => [ 'type' => 'select', 'options' => [ @@ -623,6 +625,60 @@ class ZoomPlugin extends Plugin return $form; } + public function getRegisterPresenterForm(Meeting $meeting): FormValidator + { + $form = new FormValidator('register_presenter', 'post', $_SERVER['REQUEST_URI']); + + $presenterIdSelect = $form->addSelect('presenterIds', $this->get_lang('RegisteredPresenters')); + $presenterIdSelect->setMultiple(true); + + $form->addButtonSend($this->get_lang('UpdateRegisteredUserList')); + + $users = $meeting->getRegistrableUsers(); + + foreach ($users as $user) { + $presenterIdSelect->addOption( + api_get_person_name($user->getFirstname(), $user->getLastname()), + $user->getId() + ); + } + + if ($form->validate()) { + $selectedPresenterIds = $form->getSubmitValue('presenterIds') ?: []; + $selectedPresenters = []; + + foreach ($users as $user) { + if (in_array($user->getId(), $selectedPresenterIds)) { + $selectedPresenters[] = $user; + } + } + + try { + $this->updatePresenterList($meeting, $selectedPresenters); + + Display::addFlash( + Display::return_message($this->get_lang('RegisteredUserListWasUpdated'), 'confirm') + ); + } catch (Exception $exception) { + Display::addFlash( + Display::return_message($exception->getMessage(), 'error') + ); + } + } + + $registeredPresenterIds = []; + + foreach ($meeting->getPresenters() as $registrant) { + if ($registrant instanceof Presenter) { + $registeredPresenterIds[] = $registrant->getUser()->getId(); + } + } + + $presenterIdSelect->setSelected($registeredPresenterIds); + + return $form; + } + /** * Generates a meeting recording files management form. * Takes action on validation. @@ -1250,6 +1306,16 @@ class ZoomPlugin extends Plugin return true; } + $currentUser = api_get_user_entity(api_get_user_id()); + + if ('true' === $this->get('enableParticipantRegistration') + && 'true' === $this->get('enablePresenter') + && $currentUser + && $meeting->hasUserAsPresenter($currentUser) + ) { + return true; + } + return $meeting->isUserMeeting() && $meeting->getUser()->getId() == api_get_user_id(); } @@ -1559,6 +1625,32 @@ class ZoomPlugin extends Plugin return $failedUsers; } + /** + * @param Meeting $meeting + * @param array $users + * + * @throws OptimisticLockException + * @throws \Doctrine\ORM\ORMException + * + * @return array + */ + public function registerPresenters(Meeting $meeting, array $users): array + { + $failedUsers = []; + + foreach ($users as $user) { + try { + $this->registerUser($meeting, $user, false, true); + } catch (Exception $exception) { + $failedUsers[$user->getId()] = $exception->getMessage(); + } + } + + Database::getManager()->flush(); + + return $failedUsers; + } + /** * Removes registrants from a meeting. * @@ -1626,13 +1718,55 @@ class ZoomPlugin extends Plugin $this->unregister($meeting, $registrantsToRemove); } + private function updatePresenterList($meeting, $users) + { + /** @var array $presenters */ + $presenters = $meeting->getPresenters(); + + $presenterToAdd = []; + + foreach ($users as $user) { + $foundPresenter = false; + + foreach ($presenters as $presenter) { + if ($presenter->getUser() === $user) { + $foundPresenter = true; + + break; + } + } + + if (!$foundPresenter) { + $presenterToAdd[] = $user; + } + } + + $registrantsToRemove = []; + + foreach ($presenters as $registrant) { + $found = false; + foreach ($users as $user) { + if ($registrant->getUser() === $user) { + $found = true; + break; + } + } + if (!$found) { + $registrantsToRemove[] = $registrant; + } + } + + $this->registerPresenters($meeting, $presenterToAdd); + $this->unregister($meeting, $registrantsToRemove); + } + /** * @throws Exception * @throws OptimisticLockException * * @return Registrant */ - private function registerUser(Meeting $meeting, User $user, $andFlush = true) + private function registerUser(Meeting $meeting, User $user, $andFlush = true, bool $isPresenter = false) { if (empty($user->getEmail())) { throw new Exception($this->get_lang('CannotRegisterWithoutEmailAddress')); @@ -1652,7 +1786,13 @@ class ZoomPlugin extends Plugin ); } - $registrantEntity = (new Registrant()) + $registrantEntity = new Registrant(); + + if ($isPresenter) { + $registrantEntity = new Presenter(); + } + + $registrantEntity ->setMeeting($meeting) ->setUser($user) ->setMeetingRegistrant($meetingRegistrant) diff --git a/plugin/zoom/meeting.php b/plugin/zoom/meeting.php index 3d61dd0db3..c521fd2367 100755 --- a/plugin/zoom/meeting.php +++ b/plugin/zoom/meeting.php @@ -3,6 +3,7 @@ /* For license terms, see /license.txt */ use Chamilo\PluginBundle\Zoom\Meeting; +use Chamilo\PluginBundle\Zoom\Registrant; use Chamilo\PluginBundle\Zoom\Webinar; require_once __DIR__.'/config.php'; @@ -65,11 +66,20 @@ if ($plugin->userIsConferenceManager($meeting)) { $tpl->assign('deleteMeetingForm', $plugin->getDeleteMeetingForm($meeting, $returnURL)->returnForm()); } - if (false === $meeting->isGlobalMeeting() && false == $meeting->isCourseMeeting()) { - if ('true' === $plugin->get('enableParticipantRegistration') && $meeting->requiresRegistration()) { + $pluginEnableParticipantRegistration = 'true' === $plugin->get('enableParticipantRegistration'); + + if ($pluginEnableParticipantRegistration && $meeting->requiresRegistration()) { + if (false === $meeting->isGlobalMeeting() + && false == $meeting->isCourseMeeting() + ) { $tpl->assign('registerParticipantForm', $plugin->getRegisterParticipantForm($meeting)->returnForm()); $tpl->assign('registrants', $meeting->getRegistrants()); } + + if ('true' === $plugin->get('enablePresenter') && !$meeting->isCourseMeeting()) { + $tpl->assign('registerPresenterForm', $plugin->getRegisterPresenterForm($meeting)->returnForm()); + $tpl->assign('presenters', $meeting->getPresenters()); + } } if (ZoomPlugin::RECORDING_TYPE_NONE !== $plugin->getRecordingSetting() && diff --git a/plugin/zoom/view/meeting.tpl b/plugin/zoom/view/meeting.tpl index 1aa12b3d35..b43c52f0f5 100644 --- a/plugin/zoom/view/meeting.tpl +++ b/plugin/zoom/view/meeting.tpl @@ -69,45 +69,68 @@
{{ registerParticipantForm }} {% endif %} + + {% if registerPresenterForm %} + {{ registerPresenterForm }} + {% endif %} + {{ fileForm }} - {# {% if registrants and meeting.meetingInfoGet.settings.approval_type != 2 %}#} - {% if registrants.count > 0 %} - -

{{ 'Users' | get_lang }}

-
- - {% for registrant in registrants %} - - - - - {% endfor %} -
- {{ registrant.fullName }} - -{# {% if registrant.joinUrl %}#} -{# #} -{# {{ 'CopyJoinAsURL'|get_plugin_lang('ZoomPlugin') }}#} -{# #} -{# {% else %}#} -{# #} -{# {{ 'JoinURLNotAvailable'|get_plugin_lang('ZoomPlugin') }}#} -{# #} -{# {% endif %}#} -
- {% endif %} + +

{{ 'Users' | get_lang }}

+
+ + {% for registrant in registrants %} + + + + + {% endfor %} +
+ {{ registrant.fullName }} + + {# {% if registrant.joinUrl %}#} + {# #} + {# {{ 'CopyJoinAsURL'|get_plugin_lang('ZoomPlugin') }}#} + {# #} + {# {% else %}#} + {# #} + {# {{ 'JoinURLNotAvailable'|get_plugin_lang('ZoomPlugin') }}#} + {# #} + {# {% endif %}#} +
+ {% endif %} + + {% else %} {% include 'zoom/view/meeting_details.tpl' %} {% endif %}