Skip to content

Commit fa4b551

Browse files
committed
Plugin: Zoom: Add option to enable presenters for meetings - refs BT#21354
1 parent ba0184c commit fa4b551

File tree

8 files changed

+287
-41
lines changed

8 files changed

+287
-41
lines changed

plugin/zoom/Entity/Meeting.php

+25-1
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,31 @@ public function getSession()
245245
*/
246246
public function getRegistrants()
247247
{
248-
return $this->registrants;
248+
return $this->registrants->filter(function (Registrant $registrant) {
249+
return !$registrant instanceof Presenter;
250+
});
251+
}
252+
253+
/**
254+
* @return ArrayCollection<int, Presenter>
255+
*/
256+
public function getPresenters(): ArrayCollection
257+
{
258+
return $this->registrants->filter(function (Registrant $registrant) {
259+
return $registrant instanceof Presenter;
260+
});
261+
}
262+
263+
public function hasUserAsPresenter(User $user): bool
264+
{
265+
$presenters = $this->getPresenters();
266+
267+
$criteria = Criteria::create();
268+
$criteria->where(
269+
Criteria::expr()->eq('user', $user)
270+
);
271+
272+
return $presenters->matching($criteria)->count() > 0;
249273
}
250274

251275
/**

plugin/zoom/Entity/Presenter.php

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
/* For licensing terms, see /license.txt */
4+
5+
namespace Chamilo\PluginBundle\Zoom;
6+
7+
use Doctrine\ORM\Mapping as ORM;
8+
use Exception;
9+
10+
/**
11+
* @ORM\Entity()
12+
* @ORM\HasLifecycleCallbacks()
13+
*/
14+
class Presenter extends Registrant
15+
{
16+
public function __toString()
17+
{
18+
return sprintf('Presenter %d', $this->id);
19+
}
20+
21+
/**
22+
* @ORM\PostLoad()
23+
*
24+
* @throws Exception
25+
*/
26+
public function postLoad()
27+
{
28+
parent::postLoad();
29+
}
30+
31+
/**
32+
* @ORM\PreFlush()
33+
*/
34+
public function preFlush()
35+
{
36+
parent::preFlush();
37+
}
38+
}

plugin/zoom/Entity/Registrant.php

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
* }
2424
* )
2525
* @ORM\HasLifecycleCallbacks
26+
* @ORM\InheritanceType("SINGLE_TABLE")
27+
* @ORM\DiscriminatorColumn(name="type", type="string")
28+
* @ORM\DiscriminatorMap({"registrant" = "Chamilo\PluginBundle\Zoom\Registrant", "presenter" = "Chamilo\PluginBundle\Zoom\Presenter"})
2629
*/
2730
class Registrant
2831
{

plugin/zoom/lang/english.php

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
$strings[ZoomPlugin::SETTING_SECRET_TOKEN] = 'Secret token';
2222
$strings[ZoomPlugin::SETTING_SECRET_TOKEN.'_help'] = 'For a Server-to-Server OAuth application type';
2323
$strings['enableParticipantRegistration'] = 'Enable participant registration';
24+
$strings['enablePresenter'] = 'Enable presenter';
25+
$strings['enablePresenter_help'] = 'It requires that <i>Enable participant registration</i> settings is enabled.';
2426
$strings['enableCloudRecording'] = 'Automatic recording type';
2527
$strings['enableGlobalConference'] = 'Enable global conference';
2628
$strings['enableGlobalConferencePerUser'] = 'Enable global conference per user';
@@ -132,6 +134,7 @@
132134
$strings['RegisterAllCourseUsers'] = "Register all course users";
133135
$strings['RegisteredUserListWasUpdated'] = "Registered user list updated";
134136
$strings['RegisteredUsers'] = "Registered users";
137+
$strings['RegisteredPresenters'] = "Registered presenters";
135138
$strings['RegisterNoUser'] = "Register no user";
136139
$strings['RegisterTheseGroupMembers'] = "Register these group members";
137140
$strings['ScheduleAMeeting'] = "Schedule a meeting";
@@ -185,3 +188,4 @@
185188
$strings['UrlForSelfRegistration'] = "URL for self registration";
186189
$strings['RegisterMeToConference'] = "Register me to conference";
187190
$strings['UnregisterMeToConference'] = "Unregister me to conference";
191+
$strings['Presenters'] = "Presenters";

plugin/zoom/lang/spanish.php

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
$strings['apiKey'] = "Clave API (<em>API Key</em>)";
1010
$strings['apiSecret'] = "Código secreto de API (<em>API Secret</em>)";
1111
$strings['enableParticipantRegistration'] = "Activar la inscripción de participantes";
12+
$strings['enablePresenter'] = 'Activar presentadores';
13+
$strings['enablePresenter_help'] = 'Require que It requires that <i>Enable participant registration</i> settings is enabled.';
1214
$strings['enableCloudRecording'] = "Tipo de grabación automática";
1315
$strings['enableGlobalConference'] = "Activar las conferencias globales";
1416
$strings['enableGlobalConferencePerUser'] = "Activar las conferencias globales por usuario";
@@ -119,6 +121,7 @@
119121
$strings['RegisterAllCourseUsers'] = "Inscribir todos los usuarios del curso";
120122
$strings['RegisteredUserListWasUpdated'] = "Lista de usuarios inscritos actualizada";
121123
$strings['RegisteredUsers'] = "Usuarios inscritos";
124+
$strings['RegisteredPresenters'] = "Presentadores registrados";
122125
$strings['RegisterNoUser'] = "No inscribir ningún usuario";
123126
$strings['RegisterTheseGroupMembers'] = "Inscribir los miembros de estos grupos";
124127
$strings['ScheduleAMeeting'] = "Programar una conferencia";
@@ -168,3 +171,4 @@
168171
$strings['UrlForSelfRegistration'] = "URL para auto registro";
169172
$strings['RegisterMeToConference'] = "Registrarme a la conferencia";
170173
$strings['UnregisterMeToConference'] = "Cancelar registro a la conferencia";
174+
$strings['Presenters'] = "Presentadores";

plugin/zoom/lib/ZoomPlugin.php

+142-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Chamilo\PluginBundle\Zoom\Meeting;
2020
use Chamilo\PluginBundle\Zoom\MeetingActivity;
2121
use Chamilo\PluginBundle\Zoom\MeetingRepository;
22+
use Chamilo\PluginBundle\Zoom\Presenter;
2223
use Chamilo\PluginBundle\Zoom\Recording;
2324
use Chamilo\PluginBundle\Zoom\RecordingRepository;
2425
use Chamilo\PluginBundle\Zoom\Registrant;
@@ -71,6 +72,7 @@ public function __construct()
7172
self::SETTING_CLIENT_SECRET => 'text',
7273
self::SETTING_SECRET_TOKEN => 'text',
7374
'enableParticipantRegistration' => 'boolean',
75+
'enablePresenter' => 'boolean',
7476
'enableCloudRecording' => [
7577
'type' => 'select',
7678
'options' => [
@@ -623,6 +625,60 @@ public function getRegisterParticipantForm($meeting)
623625
return $form;
624626
}
625627

628+
public function getRegisterPresenterForm(Meeting $meeting): FormValidator
629+
{
630+
$form = new FormValidator('register_presenter', 'post', $_SERVER['REQUEST_URI']);
631+
632+
$presenterIdSelect = $form->addSelect('presenterIds', $this->get_lang('RegisteredPresenters'));
633+
$presenterIdSelect->setMultiple(true);
634+
635+
$form->addButtonSend($this->get_lang('UpdateRegisteredUserList'));
636+
637+
$users = $meeting->getRegistrableUsers();
638+
639+
foreach ($users as $user) {
640+
$presenterIdSelect->addOption(
641+
api_get_person_name($user->getFirstname(), $user->getLastname()),
642+
$user->getId()
643+
);
644+
}
645+
646+
if ($form->validate()) {
647+
$selectedPresenterIds = $form->getSubmitValue('presenterIds') ?: [];
648+
$selectedPresenters = [];
649+
650+
foreach ($users as $user) {
651+
if (in_array($user->getId(), $selectedPresenterIds)) {
652+
$selectedPresenters[] = $user;
653+
}
654+
}
655+
656+
try {
657+
$this->updatePresenterList($meeting, $selectedPresenters);
658+
659+
Display::addFlash(
660+
Display::return_message($this->get_lang('RegisteredUserListWasUpdated'), 'confirm')
661+
);
662+
} catch (Exception $exception) {
663+
Display::addFlash(
664+
Display::return_message($exception->getMessage(), 'error')
665+
);
666+
}
667+
}
668+
669+
$registeredPresenterIds = [];
670+
671+
foreach ($meeting->getPresenters() as $registrant) {
672+
if ($registrant instanceof Presenter) {
673+
$registeredPresenterIds[] = $registrant->getUser()->getId();
674+
}
675+
}
676+
677+
$presenterIdSelect->setSelected($registeredPresenterIds);
678+
679+
return $form;
680+
}
681+
626682
/**
627683
* Generates a meeting recording files management form.
628684
* Takes action on validation.
@@ -1250,6 +1306,16 @@ public function userIsConferenceManager($meeting)
12501306
return true;
12511307
}
12521308

1309+
$currentUser = api_get_user_entity(api_get_user_id());
1310+
1311+
if ('true' === $this->get('enableParticipantRegistration')
1312+
&& 'true' === $this->get('enablePresenter')
1313+
&& $currentUser
1314+
&& $meeting->hasUserAsPresenter($currentUser)
1315+
) {
1316+
return true;
1317+
}
1318+
12531319
return $meeting->isUserMeeting() && $meeting->getUser()->getId() == api_get_user_id();
12541320
}
12551321

@@ -1559,6 +1625,32 @@ public function registerUsers(Meeting $meeting, array $users)
15591625
return $failedUsers;
15601626
}
15611627

1628+
/**
1629+
* @param Meeting $meeting
1630+
* @param array<User> $users
1631+
*
1632+
* @throws OptimisticLockException
1633+
* @throws \Doctrine\ORM\ORMException
1634+
*
1635+
* @return array
1636+
*/
1637+
public function registerPresenters(Meeting $meeting, array $users): array
1638+
{
1639+
$failedUsers = [];
1640+
1641+
foreach ($users as $user) {
1642+
try {
1643+
$this->registerUser($meeting, $user, false, true);
1644+
} catch (Exception $exception) {
1645+
$failedUsers[$user->getId()] = $exception->getMessage();
1646+
}
1647+
}
1648+
1649+
Database::getManager()->flush();
1650+
1651+
return $failedUsers;
1652+
}
1653+
15621654
/**
15631655
* Removes registrants from a meeting.
15641656
*
@@ -1626,13 +1718,55 @@ private function updateRegistrantList($meeting, $users)
16261718
$this->unregister($meeting, $registrantsToRemove);
16271719
}
16281720

1721+
private function updatePresenterList($meeting, $users)
1722+
{
1723+
/** @var array<Registrant> $presenters */
1724+
$presenters = $meeting->getPresenters();
1725+
1726+
$presenterToAdd = [];
1727+
1728+
foreach ($users as $user) {
1729+
$foundPresenter = false;
1730+
1731+
foreach ($presenters as $presenter) {
1732+
if ($presenter->getUser() === $user) {
1733+
$foundPresenter = true;
1734+
1735+
break;
1736+
}
1737+
}
1738+
1739+
if (!$foundPresenter) {
1740+
$presenterToAdd[] = $user;
1741+
}
1742+
}
1743+
1744+
$registrantsToRemove = [];
1745+
1746+
foreach ($presenters as $registrant) {
1747+
$found = false;
1748+
foreach ($users as $user) {
1749+
if ($registrant->getUser() === $user) {
1750+
$found = true;
1751+
break;
1752+
}
1753+
}
1754+
if (!$found) {
1755+
$registrantsToRemove[] = $registrant;
1756+
}
1757+
}
1758+
1759+
$this->registerPresenters($meeting, $presenterToAdd);
1760+
$this->unregister($meeting, $registrantsToRemove);
1761+
}
1762+
16291763
/**
16301764
* @throws Exception
16311765
* @throws OptimisticLockException
16321766
*
16331767
* @return Registrant
16341768
*/
1635-
private function registerUser(Meeting $meeting, User $user, $andFlush = true)
1769+
private function registerUser(Meeting $meeting, User $user, $andFlush = true, bool $isPresenter = false)
16361770
{
16371771
if (empty($user->getEmail())) {
16381772
throw new Exception($this->get_lang('CannotRegisterWithoutEmailAddress'));
@@ -1652,7 +1786,13 @@ private function registerUser(Meeting $meeting, User $user, $andFlush = true)
16521786
);
16531787
}
16541788

1655-
$registrantEntity = (new Registrant())
1789+
$registrantEntity = new Registrant();
1790+
1791+
if ($isPresenter) {
1792+
$registrantEntity = new Presenter();
1793+
}
1794+
1795+
$registrantEntity
16561796
->setMeeting($meeting)
16571797
->setUser($user)
16581798
->setMeetingRegistrant($meetingRegistrant)

plugin/zoom/meeting.php

+12-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
/* For license terms, see /license.txt */
44

55
use Chamilo\PluginBundle\Zoom\Meeting;
6+
use Chamilo\PluginBundle\Zoom\Registrant;
67
use Chamilo\PluginBundle\Zoom\Webinar;
78

89
require_once __DIR__.'/config.php';
@@ -65,11 +66,20 @@
6566
$tpl->assign('deleteMeetingForm', $plugin->getDeleteMeetingForm($meeting, $returnURL)->returnForm());
6667
}
6768

68-
if (false === $meeting->isGlobalMeeting() && false == $meeting->isCourseMeeting()) {
69-
if ('true' === $plugin->get('enableParticipantRegistration') && $meeting->requiresRegistration()) {
69+
$pluginEnableParticipantRegistration = 'true' === $plugin->get('enableParticipantRegistration');
70+
71+
if ($pluginEnableParticipantRegistration && $meeting->requiresRegistration()) {
72+
if (false === $meeting->isGlobalMeeting()
73+
&& false == $meeting->isCourseMeeting()
74+
) {
7075
$tpl->assign('registerParticipantForm', $plugin->getRegisterParticipantForm($meeting)->returnForm());
7176
$tpl->assign('registrants', $meeting->getRegistrants());
7277
}
78+
79+
if ('true' === $plugin->get('enablePresenter') && !$meeting->isCourseMeeting()) {
80+
$tpl->assign('registerPresenterForm', $plugin->getRegisterPresenterForm($meeting)->returnForm());
81+
$tpl->assign('presenters', $meeting->getPresenters());
82+
}
7383
}
7484

7585
if (ZoomPlugin::RECORDING_TYPE_NONE !== $plugin->getRecordingSetting() &&

0 commit comments

Comments
 (0)