Plugin: Zoom: Add option to enable presenters for meetings - refs BT#21354

pull/5124/head
Angel Fernando Quiroz Campos 2 years ago
parent ba0184cd13
commit fa4b551e52
  1. 26
      plugin/zoom/Entity/Meeting.php
  2. 38
      plugin/zoom/Entity/Presenter.php
  3. 3
      plugin/zoom/Entity/Registrant.php
  4. 4
      plugin/zoom/lang/english.php
  5. 4
      plugin/zoom/lang/spanish.php
  6. 144
      plugin/zoom/lib/ZoomPlugin.php
  7. 14
      plugin/zoom/meeting.php
  8. 95
      plugin/zoom/view/meeting.tpl

@ -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<int, Presenter>
*/
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;
}
/**

@ -0,0 +1,38 @@
<?php
/* For licensing terms, see /license.txt */
namespace Chamilo\PluginBundle\Zoom;
use Doctrine\ORM\Mapping as ORM;
use Exception;
/**
* @ORM\Entity()
* @ORM\HasLifecycleCallbacks()
*/
class Presenter extends Registrant
{
public function __toString()
{
return sprintf('Presenter %d', $this->id);
}
/**
* @ORM\PostLoad()
*
* @throws Exception
*/
public function postLoad()
{
parent::postLoad();
}
/**
* @ORM\PreFlush()
*/
public function preFlush()
{
parent::preFlush();
}
}

@ -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
{

@ -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 <i>Enable participant registration</i> 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";

@ -9,6 +9,8 @@ $strings['tool_enable'] = 'Herramienta activada';
$strings['apiKey'] = "Clave API (<em>API Key</em>)";
$strings['apiSecret'] = "Código secreto de API (<em>API Secret</em>)";
$strings['enableParticipantRegistration'] = "Activar la inscripción de participantes";
$strings['enablePresenter'] = 'Activar presentadores';
$strings['enablePresenter_help'] = 'Require que It requires that <i>Enable participant registration</i> 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";

@ -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<User> $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<Registrant> $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)

@ -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() &&

@ -69,45 +69,68 @@
<hr>
{{ registerParticipantForm }}
{% endif %}
{% if registerPresenterForm %}
{{ registerPresenterForm }}
{% endif %}
{{ fileForm }}
{# {% if registrants and meeting.meetingInfoGet.settings.approval_type != 2 %}#}
{% if registrants.count > 0 %}
<script>
function copyJoinURL(event, url) {
event.target.textContent = '{{ 'CopyingJoinURL'|get_plugin_lang('ZoomPlugin')|escape }}';
navigator.clipboard.writeText(url).then(
function() {
event.target.textContent = '{{ 'JoinURLCopied'|get_plugin_lang('ZoomPlugin')|escape }}';
}, function() {
event.target.textContent = '{{ 'CouldNotCopyJoinURL'|get_plugin_lang('ZoomPlugin')|escape }}' + ' ' + url;
<div class="row">
<div class="col-m6">
{% if presenters %}
<h3>{{ 'Presenters'|get_plugin_lang('ZoomPlugin') }}</h3>
<table class="table">
{% for presenter in presenters %}
<tr>
<td>
{{ presenter.fullName }}
</td>
</tr>
{% endfor %}
</table>
{% endif %}
</div>
<div class="col-m6">
{# {% if registrants and meeting.meetingInfoGet.settings.approval_type != 2 %}#}
{% if registrants.count > 0 %}
<script>
function copyJoinURL(event, url) {
event.target.textContent = '{{ 'CopyingJoinURL'|get_plugin_lang('ZoomPlugin')|escape }}';
navigator.clipboard.writeText(url).then(
function() {
event.target.textContent = '{{ 'JoinURLCopied'|get_plugin_lang('ZoomPlugin')|escape }}';
}, function() {
event.target.textContent = '{{ 'CouldNotCopyJoinURL'|get_plugin_lang('ZoomPlugin')|escape }}' + ' ' + url;
}
);
}
);
}
</script>
<h3>{{ 'Users' | get_lang }}</h3>
<br />
<table class="table">
{% for registrant in registrants %}
<tr>
<td>
{{ registrant.fullName }}
</td>
<td>
{# {% if registrant.joinUrl %}#}
{# <a class="btn btn-primary" onclick="copyJoinURL(event, '{{ registrant.joinUrl }}')">#}
{# {{ 'CopyJoinAsURL'|get_plugin_lang('ZoomPlugin') }}#}
{# </a>#}
{# {% else %}#}
{# <a class="btn btn-primary disabled" >#}
{# {{ 'JoinURLNotAvailable'|get_plugin_lang('ZoomPlugin') }}#}
{# </a>#}
{# {% endif %}#}
</td>
</tr>
{% endfor %}
</table>
{% endif %}
</script>
<h3>{{ 'Users' | get_lang }}</h3>
<br />
<table class="table">
{% for registrant in registrants %}
<tr>
<td>
{{ registrant.fullName }}
</td>
<td>
{# {% if registrant.joinUrl %}#}
{# <a class="btn btn-primary" onclick="copyJoinURL(event, '{{ registrant.joinUrl }}')">#}
{# {{ 'CopyJoinAsURL'|get_plugin_lang('ZoomPlugin') }}#}
{# </a>#}
{# {% else %}#}
{# <a class="btn btn-primary disabled" >#}
{# {{ 'JoinURLNotAvailable'|get_plugin_lang('ZoomPlugin') }}#}
{# </a>#}
{# {% endif %}#}
</td>
</tr>
{% endfor %}
</table>
{% endif %}
</div>
</div>
{% else %}
{% include 'zoom/view/meeting_details.tpl' %}
{% endif %}

Loading…
Cancel
Save