Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 400 and 403] [Versions 401 and 403] [Versions 402 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Config all BigBlueButtonBN instances in this course.
  19   *
  20   * @package   mod_bigbluebuttonbn
  21   * @copyright 2010 onwards, Blindside Networks Inc
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   * @author    Jesus Federico  (jesus [at] blindsidenetworks [dt] com)
  24   * @author    Fred Dixon  (ffdixon [at] blindsidenetworks [dt] com)
  25   */
  26  
  27  use mod_bigbluebuttonbn\extension;
  28  use mod_bigbluebuttonbn\instance;
  29  use mod_bigbluebuttonbn\local\helpers\roles;
  30  use mod_bigbluebuttonbn\local\proxy\bigbluebutton_proxy;
  31  
  32  defined('MOODLE_INTERNAL') || die();
  33  global $CFG;
  34  require_once($CFG->dirroot . '/course/moodleform_mod.php');
  35  
  36  /**
  37   * Moodle class for mod_form.
  38   *
  39   * @copyright 2010 onwards, Blindside Networks Inc
  40   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  41   */
  42  class mod_bigbluebuttonbn_mod_form extends moodleform_mod {
  43  
  44      /**
  45       * @var array $formextensions extensions to this form
  46       */
  47      protected $formextensions = [];
  48      /**
  49       * Define (add) particular settings this activity can have.
  50       *
  51       * @return void
  52       * @throws moodle_exception
  53       */
  54      public function definition(): void {
  55          global $CFG, $DB, $PAGE;
  56          $mform = &$this->_form;
  57  
  58          // Validates if the BigBlueButton server is running.
  59          $serverversion = bigbluebutton_proxy::get_server_version();
  60          if (is_null($serverversion)) {
  61              throw new moodle_exception('general_error_unable_connect',
  62                  'bigbluebuttonbn',
  63                  $CFG->wwwroot . '/admin/settings.php?section=modsettingbigbluebuttonbn',
  64                  \mod_bigbluebuttonbn\local\config::get('server_url')
  65              );
  66          }
  67          // UI configuration options.
  68          $cfg = \mod_bigbluebuttonbn\local\config::get_options();
  69  
  70          // Get only those that are allowed.
  71          $course = $this->_course;
  72          $context = context_course::instance($course->id);
  73          $bigbluebuttonbn = empty($this->get_current()->id) ? null : $this->get_current();
  74  
  75          $this->formextensions = extension::mod_form_addons_instances($mform, $bigbluebuttonbn, $this->get_suffix());
  76  
  77          $instancetyperofiles = $this->get_instance_type_profiles();
  78          $this->bigbluebuttonbn_mform_add_block_profiles($mform, $instancetyperofiles);
  79          // Data for participant selection.
  80          $participantlist = roles::get_participant_list($bigbluebuttonbn, $context);
  81          // Add block 'General'.
  82          $this->bigbluebuttonbn_mform_add_block_general($mform, $cfg);
  83          // Add block 'Room'.
  84          $this->bigbluebuttonbn_mform_add_block_room($mform, $cfg);
  85          // Add block 'Lock'.
  86          $this->bigbluebuttonbn_mform_add_block_locksettings($mform, $cfg);
  87          // Add block 'Preuploads'.
  88          $this->bigbluebuttonbn_mform_add_block_preuploads($mform, $cfg);
  89          // Add block 'Participant List'.
  90          $this->bigbluebuttonbn_mform_add_block_user_role_mapping($mform, $participantlist);
  91          // Add block 'Guest Access'.
  92          $this->bigbluebuttonbn_mform_add_block_guest_access($mform, $cfg, $this->current);
  93          // Add block 'Schedule'.
  94          $this->bigbluebuttonbn_mform_add_block_schedule($mform, $this->current);
  95          // Now add subplugins form elements.
  96          $this->add_subplugins_elements();
  97  
  98          // Add standard elements, common to all modules.
  99          $this->standard_coursemodule_elements();
 100          // Add standard buttons, common to all modules.
 101          $this->add_action_buttons();
 102  
 103          $jsvars = [
 104              'instanceTypeDefault' => array_keys($instancetyperofiles)[0],
 105          ];
 106  
 107          // Now add the instance type profiles to the form as a html hidden field.
 108          $mform->addElement('html', html_writer::div('', 'd-none', [
 109              'data-profile-types' => json_encode($instancetyperofiles),
 110              'data-participant-data' => json_encode(roles::get_participant_data($context, $bigbluebuttonbn)),
 111          ]));
 112  
 113          $PAGE->requires->js_call_amd('mod_bigbluebuttonbn/modform', 'init', [$jsvars]);
 114      }
 115  
 116      /**
 117       * Get instance type profile.
 118       *
 119       * @return array|array[]
 120       * @throws moodle_exception
 121       */
 122      protected function get_instance_type_profiles() {
 123          // Add profile data here instead of passing it by parameters.
 124          $context = context_course::instance($this->_course->id);
 125          $instancetyperofiles = bigbluebutton_proxy::get_instance_type_profiles_create_allowed(
 126              has_capability('mod/bigbluebuttonbn:addinstancewithmeeting', $context),
 127              has_capability('mod/bigbluebuttonbn:addinstancewithrecording', $context)
 128          );
 129          // If none is allowed, fail and return.
 130          if (empty($instancetyperofiles)) {
 131              global $CFG;
 132              // Also check module context for those that are allowed.
 133              $contextm = context_module::instance($this->_cm->id);
 134              $instancetyperofiles = bigbluebutton_proxy::get_instance_type_profiles_create_allowed(
 135                  has_capability('mod/bigbluebuttonbn:addinstancewithmeeting', $contextm),
 136                  has_capability('mod/bigbluebuttonbn:addinstancewithrecording', $contextm)
 137              );
 138              // If still none is allowed, fail and return.
 139              if (empty($instancetyperofiles)) {
 140                  throw new moodle_exception('general_error_not_allowed_to_create_instances', 'bigbluebuttonbn',
 141                      $CFG->wwwroot . '/admin/settings.php?section=modsettingbigbluebuttonbn');
 142              }
 143          }
 144          return $instancetyperofiles;
 145      }
 146  
 147      /**
 148       * Prepare the attachment for being stored.
 149       *
 150       * @param array|null $defaultvalues
 151       * @return void
 152       */
 153      public function data_preprocessing(&$defaultvalues) {
 154          parent::data_preprocessing($defaultvalues);
 155  
 156          $suffix = $this->get_suffix();
 157          $completionattendanceenabledel = 'completionattendanceenabled' . $suffix;
 158          $completionattendanceel = 'completionattendance' . $suffix;
 159  
 160          // Completion: tick by default if completion attendance settings is set to 1 or more.
 161          $defaultvalues[$completionattendanceenabledel] = 0;
 162          if (!empty($defaultvalues[$completionattendanceel])) {
 163              $defaultvalues[$completionattendanceenabledel] = 1;
 164          }
 165          // Check if we are Editing an existing instance.
 166          if ($this->current->instance) {
 167              // Pre-uploaded presentation: copy existing files into draft area.
 168              try {
 169                  $draftitemid = file_get_submitted_draft_itemid('presentation');
 170                  file_prepare_draft_area($draftitemid, $this->context->id, 'mod_bigbluebuttonbn', 'presentation', 0,
 171                      ['subdirs' => 0, 'maxbytes' => 0, 'maxfiles' => 1, 'mainfile' => true]
 172                  );
 173                  $defaultvalues['presentation'] = $draftitemid;
 174              } catch (Exception $e) {
 175                  debugging('Presentation could not be loaded: ' . $e->getMessage(), DEBUG_DEVELOPER);
 176                  return;
 177              }
 178              // Completion: tick if completion attendance settings is set to 1 or more.
 179              $defaultvalues[$completionattendanceenabledel] = 0;
 180              if (!empty($this->current->{$completionattendanceel})) {
 181                  $defaultvalues[$completionattendanceenabledel] = 1;
 182              }
 183          }
 184          foreach ($this->formextensions as $formextension) {
 185              $formextension->data_preprocessing($defaultvalues);
 186          }
 187      }
 188  
 189      /**
 190       * Validates the data processed by the form.
 191       *
 192       * @param mixed $data
 193       * @param array $files
 194       * @return array
 195       */
 196      public function validation($data, $files) {
 197          $errors = parent::validation($data, $files);
 198          if (isset($data['openingtime']) && isset($data['closingtime'])) {
 199              if ($data['openingtime'] != 0 && $data['closingtime'] != 0 &&
 200                  $data['closingtime'] < $data['openingtime']) {
 201                  $errors['closingtime'] = get_string('bbbduetimeoverstartingtime', 'bigbluebuttonbn');
 202              }
 203          }
 204          if (isset($data['voicebridge'])) {
 205              if (!bigbluebutton_proxy::is_voicebridge_number_unique($data['instance'], $data['voicebridge'])) {
 206                  $errors['voicebridge'] = get_string('mod_form_field_voicebridge_notunique_error', 'bigbluebuttonbn');
 207              }
 208          }
 209          $additionalsubpluginerrors = [];
 210          foreach ($this->formextensions as $formextension) {
 211              $additionalsubpluginerrors = array_merge($additionalsubpluginerrors, $formextension->validation($data, $files));
 212          }
 213          return array_merge($errors, $additionalsubpluginerrors);
 214      }
 215  
 216      /**
 217       * Add elements for setting the custom completion rules.
 218       *
 219       * @return array List of added element names, or names of wrapping group elements.
 220       * @category completion
 221       */
 222      public function add_completion_rules(): array {
 223          $mform = $this->_form;
 224          if (!(boolean) \mod_bigbluebuttonbn\local\config::get('meetingevents_enabled')) {
 225              return [];
 226          }
 227  
 228          $suffix = $this->get_suffix();
 229  
 230          // Elements for completion by Attendance.
 231          $attendance['rulelabel'] = get_string('completionattendance', 'bigbluebuttonbn');
 232          $completionattendanceenabledel = 'completionattendanceenabled' . $suffix;
 233          $completionattendanceel = 'completionattendance' . $suffix;
 234          $completionattendanceunitel = 'completionattendanceunit' . $suffix;
 235          $attendance['group'] = [
 236              $mform->createElement('advcheckbox', $completionattendanceenabledel, '', $attendance['rulelabel'] . '&nbsp;'),
 237              $mform->createElement('text', $completionattendanceel, 'minutes', ['size' => 3]),
 238          ];
 239          $mform->setType($completionattendanceel, PARAM_INT);
 240          $completionattendancegroupel = 'completionattendancegroup' . $suffix;
 241          $mform->addGroup($attendance['group'], $completionattendancegroupel, '', ' ', false);
 242          $completionel = 'completion' . $suffix;
 243          $mform->hideIf($completionattendancegroupel, $completionel, 'neq', COMPLETION_AGGREGATION_ANY);
 244          $mform->hideIf($completionattendanceel, $completionattendanceenabledel, 'notchecked');
 245  
 246          // Elements for completion by Engagement.
 247          $engagement['chatlabel'] = get_string('completionengagementchats', 'bigbluebuttonbn');
 248          $engagement['talklabel'] = get_string('completionengagementtalks', 'bigbluebuttonbn');
 249          $engagement['raisehand'] = get_string('completionengagementraisehand', 'bigbluebuttonbn');
 250          $engagement['pollvotes'] = get_string('completionengagementpollvotes', 'bigbluebuttonbn');
 251          $engagement['emojis'] = get_string('completionengagementemojis', 'bigbluebuttonbn');
 252  
 253          $completionengagementchatsel = 'completionengagementchats' . $suffix;
 254          $completionengagementtalksel = 'completionengagementtalks' . $suffix;
 255          $completionengagementraisehandel = 'completionengagementraisehand' . $suffix;
 256          $completionengagementpollvotesel = 'completionengagementpollvotes' . $suffix;
 257          $completionengagementemojisel = 'completionengagementemojis' . $suffix;
 258          $engagement['group'] = [
 259              $mform->createElement('advcheckbox', $completionengagementchatsel, '', $engagement['chatlabel'] . '&nbsp;&nbsp;'),
 260              $mform->createElement('advcheckbox', $completionengagementtalksel, '', $engagement['talklabel'] . '&nbsp;&nbsp;'),
 261              $mform->createElement('advcheckbox', $completionengagementraisehandel, '', $engagement['raisehand'] . '&nbsp;&nbsp;'),
 262              $mform->createElement('advcheckbox', $completionengagementpollvotesel, '', $engagement['pollvotes'] . '&nbsp;&nbsp;'),
 263              $mform->createElement('advcheckbox', $completionengagementemojisel, '', $engagement['emojis'] . '&nbsp;&nbsp;'),
 264          ];
 265          $completionengagementgroupel = 'completionengagementgroup' . $suffix;
 266          $mform->addGroup($engagement['group'], $completionengagementgroupel, '', ' ', false);
 267          $mform->addGroupRule($completionattendancegroupel, [
 268              $completionattendanceel => [
 269                  [null, 'numeric', null, 'client']
 270              ]
 271          ]);
 272          $mform->hideIf($completionengagementgroupel, $completionel, 'neq', COMPLETION_AGGREGATION_ANY);
 273  
 274          $completionrules = [$completionattendancegroupel, $completionengagementgroupel];
 275          foreach ($this->formextensions as $formextension) {
 276              $completionrules = array_merge($completionrules, $formextension->add_completion_rules());
 277          }
 278          return $completionrules;
 279      }
 280  
 281      /**
 282       * Called during validation to see whether some module-specific completion rules are selected.
 283       *
 284       * @param array $data Input data not yet validated.
 285       * @return bool True if one or more rules is enabled, false if none are.
 286       */
 287      public function completion_rule_enabled($data) {
 288          $suffix = $this->get_suffix();
 289          $rules = [
 290              'completionattendanceenabled',
 291              'completionattendance',
 292              'completionengagementchats',
 293              'completionengagementtalks',
 294              'completionengagementraisehand',
 295              'completionengagementpollvotes',
 296              'completionengagementemojis'
 297          ];
 298          $enabled = array_reduce($rules, function($carry, $rule) use ($data, $suffix) {
 299              return $carry || !empty($data[$rule . $suffix]);
 300          }, false);
 301  
 302          foreach ($this->formextensions as $formextension) {
 303              $enabled = $enabled || $formextension->completion_rule_enabled($data);
 304          }
 305          return $enabled;
 306      }
 307  
 308      /**
 309       * Allows module to modify the data returned by form get_data().
 310       * This method is also called in the bulk activity completion form.
 311       *
 312       * Only available on moodleform_mod.
 313       *
 314       * @param stdClass $data the form data to be modified.
 315       */
 316      public function data_postprocessing($data) {
 317          parent::data_postprocessing($data);
 318          // Turn off completion settings if the checkboxes aren't ticked.
 319          if (!empty($data->completionunlocked)) {
 320              $suffix = $this->get_suffix();
 321              $completion = $data->{'completion' . $suffix};
 322              $autocompletion = !empty($completion) && $completion == COMPLETION_TRACKING_AUTOMATIC;
 323              if (empty($data->{'completionattendanceenabled' . $suffix}) || !$autocompletion) {
 324                  $data->{'completionattendance' . $suffix} = 0;
 325              }
 326          }
 327          foreach ($this->formextensions as $formextension) {
 328              $formextension->data_postprocessing($data);
 329          }
 330      }
 331  
 332      /**
 333       * Function for showing the block for selecting profiles.
 334       *
 335       * @param MoodleQuickForm $mform
 336       * @param array $profiles
 337       * @return void
 338       */
 339      private function bigbluebuttonbn_mform_add_block_profiles(MoodleQuickForm &$mform, array $profiles): void {
 340          if ((boolean) \mod_bigbluebuttonbn\local\config::recordings_enabled()) {
 341              $mform->addElement('select', 'type', get_string('mod_form_field_instanceprofiles', 'bigbluebuttonbn'),
 342                  bigbluebutton_proxy::get_instance_profiles_array($profiles));
 343              $mform->addHelpButton('type', 'mod_form_field_instanceprofiles', 'bigbluebuttonbn');
 344          }
 345      }
 346  
 347      /**
 348       * Function for showing the block for general settings.
 349       *
 350       * @param MoodleQuickForm $mform
 351       * @param array $cfg
 352       * @return void
 353       */
 354      private function bigbluebuttonbn_mform_add_block_general(MoodleQuickForm &$mform, array $cfg): void {
 355          global $CFG;
 356          $mform->addElement('header', 'general', get_string('mod_form_block_general', 'bigbluebuttonbn'));
 357          $mform->addElement('text', 'name', get_string('mod_form_field_name', 'bigbluebuttonbn'),
 358              'maxlength="64" size="32"');
 359          $mform->setType('name', empty($CFG->formatstringstriptags) ? PARAM_CLEANHTML : PARAM_TEXT);
 360          $mform->addRule('name', null, 'required', null, 'client');
 361          $this->standard_intro_elements(get_string('mod_form_field_intro', 'bigbluebuttonbn'));
 362          $mform->setAdvanced('introeditor');
 363          $mform->setAdvanced('showdescription');
 364      }
 365  
 366      /**
 367       * Function for showing details of the room settings for the room.
 368       *
 369       * @param MoodleQuickForm $mform
 370       * @param array $cfg
 371       * @return void
 372       */
 373      private function bigbluebuttonbn_mform_add_block_room_room(MoodleQuickForm &$mform, array $cfg): void {
 374          $field = ['type' => 'hidden', 'name' => 'welcome', 'data_type' => PARAM_INT,
 375              'description_key' => null];
 376          if ($cfg['welcome_editable']) {
 377              $field['type'] = 'textarea';
 378              $field['data_type'] = PARAM_CLEANHTML;
 379              $field['description_key'] = 'mod_form_field_welcome';
 380              $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 381                  $field['description_key'], $cfg['welcome_default'], ['wrap' => 'virtual', 'rows' => 5, 'cols' => '60']);
 382          }
 383          $field = ['type' => 'hidden', 'name' => 'voicebridge', 'data_type' => PARAM_INT,
 384              'description_key' => null];
 385          if ($cfg['voicebridge_editable']) {
 386              $field['type'] = 'text';
 387              $field['data_type'] = PARAM_TEXT;
 388              $field['description_key'] = 'mod_form_field_voicebridge';
 389              $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 390                  $field['description_key'], 0, ['maxlength' => 4, 'size' => 6],
 391                  ['message' => get_string('mod_form_field_voicebridge_format_error', 'bigbluebuttonbn'),
 392                      'type' => 'numeric', 'rule' => '####', 'validator' => 'server']
 393              );
 394          } else {
 395              $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 396                  $field['description_key'], 0, ['maxlength' => 4, 'size' => 6]);
 397          }
 398          $field = ['type' => 'hidden', 'name' => 'wait', 'data_type' => PARAM_INT, 'description_key' => null];
 399          if ($cfg['waitformoderator_editable']) {
 400              $field['type'] = 'checkbox';
 401              $field['description_key'] = 'mod_form_field_wait';
 402          }
 403          $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 404              $field['description_key'], $cfg['waitformoderator_default']);
 405          $field = ['type' => 'hidden', 'name' => 'userlimit', 'data_type' => PARAM_INT, 'description_key' => null];
 406          if ($cfg['userlimit_editable']) {
 407              $field['type'] = 'text';
 408              $field['data_type'] = PARAM_TEXT;
 409              $field['description_key'] = 'mod_form_field_userlimit';
 410          }
 411          $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 412              $field['description_key'], $cfg['userlimit_default']);
 413          $field = ['type' => 'hidden', 'name' => 'record', 'data_type' => PARAM_INT, 'description_key' => null];
 414          if ($cfg['recording_editable']) {
 415              $field['type'] = 'checkbox';
 416              $field['description_key'] = 'mod_form_field_record';
 417          }
 418          $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 419              $field['description_key'], $cfg['recording_default']);
 420  
 421          // Record all from start and hide button.
 422          $field = ['type' => 'hidden', 'name' => 'recordallfromstart', 'data_type' => PARAM_INT, 'description_key' => null];
 423          if ($cfg['recording_all_from_start_editable']) {
 424              $field['type'] = 'checkbox';
 425              $field['description_key'] = 'mod_form_field_recordallfromstart';
 426          }
 427          $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 428              $field['description_key'], $cfg['recording_all_from_start_default']);
 429  
 430          $field = ['type' => 'hidden', 'name' => 'recordhidebutton', 'data_type' => PARAM_INT, 'description_key' => null];
 431          if ($cfg['recording_hide_button_editable']) {
 432              $field['type'] = 'checkbox';
 433              $field['description_key'] = 'mod_form_field_recordhidebutton';
 434          }
 435          $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 436              $field['description_key'], $cfg['recording_hide_button_default']);
 437  
 438          $mform->disabledIf('recordallfromstart', 'record');
 439          $mform->disabledIf('recordhidebutton', 'record');
 440          $mform->hideIf('recordhidebutton', 'recordallfromstart', 'checked');
 441          // End Record all from start and hide button.
 442  
 443          $field = ['type' => 'hidden', 'name' => 'muteonstart', 'data_type' => PARAM_INT, 'description_key' => null];
 444          if ($cfg['muteonstart_editable']) {
 445              $field['type'] = 'checkbox';
 446              $field['description_key'] = 'mod_form_field_muteonstart';
 447          }
 448          $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 449              $field['description_key'], $cfg['muteonstart_default']);
 450  
 451      }
 452  
 453      /**
 454       * Function for showing details of the lock settings for the room.
 455       *
 456       * @param MoodleQuickForm $mform
 457       * @param array $cfg
 458       * @return void
 459       */
 460      private function bigbluebuttonbn_mform_add_block_locksettings(MoodleQuickForm &$mform, array $cfg): void {
 461          $mform->addElement('header', 'lock', get_string('mod_form_locksettings', 'bigbluebuttonbn'));
 462  
 463          $locksettings = false;
 464  
 465          $field = ['type' => 'hidden', 'name' => 'disablecam', 'data_type' => PARAM_INT, 'description_key' => null];
 466          if ($cfg['disablecam_editable']) {
 467              $field['type'] = 'checkbox';
 468              $field['description_key'] = 'mod_form_field_disablecam';
 469              $locksettings = true;
 470          }
 471          $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 472                  $field['description_key'], $cfg['disablecam_default']);
 473  
 474          $field = ['type' => 'hidden', 'name' => 'disablemic', 'data_type' => PARAM_INT, 'description_key' => null];
 475          if ($cfg['disablemic_editable']) {
 476              $field['type'] = 'checkbox';
 477              $field['description_key'] = 'mod_form_field_disablemic';
 478              $locksettings = true;
 479          }
 480          $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 481                  $field['description_key'], $cfg['disablemic_default']);
 482  
 483          $field = ['type' => 'hidden', 'name' => 'disableprivatechat', 'data_type' => PARAM_INT, 'description_key' => null];
 484          if ($cfg['disableprivatechat_editable']) {
 485              $field['type'] = 'checkbox';
 486              $field['description_key'] = 'mod_form_field_disableprivatechat';
 487              $locksettings = true;
 488          }
 489          $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 490                  $field['description_key'], $cfg['disableprivatechat_default']);
 491  
 492          $field = ['type' => 'hidden', 'name' => 'disablepublicchat', 'data_type' => PARAM_INT, 'description_key' => null];
 493          if ($cfg['disablepublicchat_editable']) {
 494              $field['type'] = 'checkbox';
 495              $field['description_key'] = 'mod_form_field_disablepublicchat';
 496              $locksettings = true;
 497          }
 498          $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 499                  $field['description_key'], $cfg['disablepublicchat_default']);
 500  
 501          $field = ['type' => 'hidden', 'name' => 'disablenote', 'data_type' => PARAM_INT, 'description_key' => null];
 502          if ($cfg['disablenote_editable']) {
 503              $field['type'] = 'checkbox';
 504              $field['description_key'] = 'mod_form_field_disablenote';
 505              $locksettings = true;
 506          }
 507          $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 508                  $field['description_key'], $cfg['disablenote_default']);
 509  
 510          $field = ['type' => 'hidden', 'name' => 'hideuserlist', 'data_type' => PARAM_INT, 'description_key' => null];
 511          if ($cfg['hideuserlist_editable']) {
 512              $field['type'] = 'checkbox';
 513              $field['description_key'] = 'mod_form_field_hideuserlist';
 514              $locksettings = true;
 515          }
 516          $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 517                  $field['description_key'], $cfg['hideuserlist_default']);
 518  
 519          // Output message if no settings.
 520          if (!$locksettings) {
 521              $field = ['type' => 'static', 'name' => 'no_locksettings',
 522                      'defaultvalue' => get_string('mod_form_field_nosettings', 'bigbluebuttonbn')];
 523              $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], null, null,
 524                      $field['defaultvalue']);
 525          }
 526      }
 527  
 528      /**
 529       * Function for showing details of the recording settings for the room.
 530       *
 531       * @param MoodleQuickForm $mform
 532       * @param array $cfg
 533       * @return void
 534       */
 535      private function bigbluebuttonbn_mform_add_block_room_recordings(MoodleQuickForm &$mform, array $cfg): void {
 536          $recordingsettings = false;
 537          $field = ['type' => 'hidden', 'name' => 'recordings_deleted', 'data_type' => PARAM_INT,
 538              'description_key' => null];
 539          if ($cfg['recordings_deleted_editable']) {
 540              $field['type'] = 'checkbox';
 541              $field['description_key'] = 'mod_form_field_recordings_deleted';
 542              $recordingsettings = true;
 543          }
 544          $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 545              $field['description_key'], $cfg['recordings_deleted_default']);
 546          $field = ['type' => 'hidden', 'name' => 'recordings_imported', 'data_type' => PARAM_INT,
 547              'description_key' => null];
 548          if ($cfg['importrecordings_enabled'] && $cfg['recordings_imported_editable']) {
 549              $field['type'] = 'checkbox';
 550              $field['description_key'] = 'mod_form_field_recordings_imported';
 551              $recordingsettings = true;
 552          }
 553          $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 554              $field['description_key'], $cfg['recordings_imported_default']);
 555          $field = ['type' => 'hidden', 'name' => 'recordings_preview', 'data_type' => PARAM_INT,
 556              'description_key' => null];
 557          if ($cfg['recordings_preview_editable']) {
 558              $field['type'] = 'checkbox';
 559              $field['description_key'] = 'mod_form_field_recordings_preview';
 560              $recordingsettings = true;
 561          }
 562          $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], $field['data_type'],
 563              $field['description_key'], $cfg['recordings_preview_default']);
 564  
 565          if (!$recordingsettings) {
 566              $field = ['type' => 'static', 'name' => 'no_recordings',
 567                  'defaultvalue' => get_string('mod_form_field_nosettings', 'bigbluebuttonbn')];
 568              $this->bigbluebuttonbn_mform_add_element($mform, $field['type'], $field['name'], null, null,
 569                  $field['defaultvalue']);
 570          }
 571      }
 572  
 573      /**
 574       * Function for showing the block for room settings.
 575       *
 576       * @param MoodleQuickForm $mform
 577       * @param array $cfg
 578       * @return void
 579       */
 580      private function bigbluebuttonbn_mform_add_block_room(MoodleQuickForm &$mform, array $cfg) {
 581          if ($cfg['voicebridge_editable'] || $cfg['waitformoderator_editable'] ||
 582              $cfg['userlimit_editable'] || $cfg['recording_editable'] || $cfg['muteonstart_editable']) {
 583              $mform->addElement('header', 'room', get_string('mod_form_block_room', 'bigbluebuttonbn'));
 584              $this->bigbluebuttonbn_mform_add_block_room_room($mform, $cfg);
 585          }
 586          if ($cfg['recordings_deleted_editable'] ||
 587              $cfg['recordings_imported_editable'] || $cfg['recordings_preview_editable']) {
 588              $mform->addElement('header', 'recordings', get_string('mod_form_block_recordings', 'bigbluebuttonbn'));
 589              $this->bigbluebuttonbn_mform_add_block_room_recordings($mform, $cfg);
 590          }
 591      }
 592  
 593      /**
 594       * Function for showing the block for preuploaded presentation.
 595       *
 596       * @param MoodleQuickForm $mform
 597       * @param array $cfg
 598       * @return void
 599       */
 600      private function bigbluebuttonbn_mform_add_block_preuploads(MoodleQuickForm &$mform, array $cfg): void {
 601          if ($cfg['preuploadpresentation_editable']) {
 602              $mform->addElement('header', 'preuploadpresentation',
 603                  get_string('mod_form_block_presentation', 'bigbluebuttonbn'));
 604              $mform->setExpanded('preuploadpresentation');
 605              $filemanageroptions = [];
 606              $filemanageroptions['accepted_types'] = '*';
 607              $filemanageroptions['maxbytes'] = 0;
 608              $filemanageroptions['subdirs'] = 0;
 609              $filemanageroptions['maxfiles'] = 1;
 610              $filemanageroptions['mainfile'] = true;
 611              $mform->addElement('filemanager', 'presentation', get_string('selectfiles'),
 612                  null, $filemanageroptions);
 613          }
 614      }
 615  
 616      /**
 617       * Function for showing the block for setting participant roles.
 618       *
 619       * @param MoodleQuickForm $mform
 620       * @param array $participantlist
 621       * @return void
 622       */
 623      private function bigbluebuttonbn_mform_add_block_user_role_mapping(MoodleQuickForm &$mform, array $participantlist): void {
 624          global $OUTPUT;
 625          $participantselection = roles::get_participant_selection_data();
 626          $mform->addElement('header', 'permissions', get_string('mod_form_block_participants', 'bigbluebuttonbn'));
 627          $mform->setExpanded('permissions');
 628          $mform->addElement('hidden', 'participants', json_encode($participantlist));
 629          $mform->setType('participants', PARAM_TEXT);
 630          $selectiontype = new single_select(new moodle_url(qualified_me()),
 631              'bigbluebuttonbn_participant_selection_type',
 632              $participantselection['type_options'],
 633              $participantselection['type_selected']);
 634          $selectionparticipants = new single_select(new moodle_url(qualified_me()),
 635              'bigbluebuttonbn_participant_selection',
 636              $participantselection['options'],
 637              $participantselection['selected']);
 638          $action = new single_button(new moodle_url(qualified_me()),
 639              get_string('mod_form_field_participant_list_action_add', 'bigbluebuttonbn'),
 640              'post',
 641              single_button::BUTTON_SECONDARY,
 642              ['name' => 'bigbluebuttonbn_participant_selection_add']
 643          );
 644          $pformcontext = [
 645              'selectionType' => $selectiontype->export_for_template($OUTPUT),
 646              'selectionParticipant' => $selectionparticipants->export_for_template($OUTPUT),
 647              'action' => $action->export_for_template($OUTPUT),
 648          ];
 649          $html = $OUTPUT->render_from_template('mod_bigbluebuttonbn/participant_form', $pformcontext);
 650          $mform->addElement('static', 'static_participant_list',
 651              get_string('mod_form_field_participant_list', 'bigbluebuttonbn'), $html);
 652      }
 653  
 654      /**
 655       * Function to add guest acces settings to the instance
 656       *
 657       * @param MoodleQuickForm $mform
 658       * @param array $cfg
 659       * @param stdClass $current
 660       * @return void
 661       * @throws coding_exception
 662       */
 663      private function bigbluebuttonbn_mform_add_block_guest_access(MoodleQuickForm $mform, array $cfg, stdClass $current) {
 664          if (!empty($cfg['guestaccess_enabled'])) {
 665              $mform->addElement('header', 'guestaccess', get_string('mod_form_block_guestaccess', 'bigbluebuttonbn'));
 666              $mform->setExpanded('guestaccess');
 667              $mform->addElement('advcheckbox', 'guestallowed',
 668                  get_string('mod_form_field_guestallowed', 'bigbluebuttonbn'));
 669              $mform->addElement('advcheckbox', 'mustapproveuser',
 670                  get_string('mod_form_field_mustapproveuser', 'bigbluebuttonbn'));
 671              $mform->hideIf('mustapproveuser', 'guestallowed');
 672              if (!empty($this->_cm)) {
 673                  $instance = instance::get_from_cmid($this->_cm->id);
 674                  \mod_bigbluebuttonbn\form\guest_add::add_meeting_links_elements($mform);
 675                  $mform->setDefault('guestjoinurl', $instance->get_guest_access_url());
 676                  $mform->setDefault('guestpassword', $instance->get_guest_access_password());
 677                  $mform->hideIf('guestjoinurl', 'guestallowed');
 678                  $mform->hideIf('guestpassword', 'guestallowed');
 679              }
 680          } else {
 681              $mform->addElement('hidden', 'guestallowed', 0);
 682              $mform->addElement('hidden', 'mustapproveuser', 0);
 683          }
 684          $mform->setType('guestallowed', PARAM_BOOL);
 685          $mform->setType('mustapproveuser', PARAM_BOOL);
 686          $mform->setDefault('guestallowed', 0);
 687          $mform->setDefault('mustapproveuser', 1);
 688      }
 689  
 690      /**
 691       * Function for showing the block for integration with the calendar.
 692       *
 693       * @param MoodleQuickForm $mform
 694       * @param stdClass $activity
 695       * @return void
 696       */
 697      private function bigbluebuttonbn_mform_add_block_schedule(MoodleQuickForm &$mform, stdClass &$activity) {
 698          $mform->addElement('header', 'schedule', get_string('mod_form_block_schedule', 'bigbluebuttonbn'));
 699          if (!empty($activity->openingtime) || !empty($activity->closingtime)) {
 700              $mform->setExpanded('schedule');
 701          }
 702          $mform->addElement('date_time_selector', 'openingtime',
 703              get_string('mod_form_field_openingtime', 'bigbluebuttonbn'), ['optional' => true]);
 704          $mform->setDefault('openingtime', 0);
 705          $mform->addElement('date_time_selector', 'closingtime',
 706              get_string('mod_form_field_closingtime', 'bigbluebuttonbn'), ['optional' => true]);
 707          $mform->setDefault('closingtime', 0);
 708      }
 709  
 710      /**
 711       * Function for showing an element.
 712       *
 713       * @param MoodleQuickForm $mform
 714       * @param string $type
 715       * @param string $name
 716       * @param string|null $datatype
 717       * @param string|null $descriptionkey
 718       * @param mixed|null $defaultvalue
 719       * @param array|null $options
 720       * @param array|null $rule
 721       * @return void
 722       */
 723      private function bigbluebuttonbn_mform_add_element(MoodleQuickForm &$mform, string $type, string $name, ?string $datatype,
 724          ?string $descriptionkey = "", $defaultvalue = null, ?array $options = null, ?array $rule = null): void {
 725          $datatype = $datatype ?? 'hidden';
 726          if ($type === 'hidden' || $type === 'static') {
 727              $mform->addElement($type, $name, $defaultvalue);
 728              $mform->setType($name, $datatype);
 729              return;
 730          }
 731          if ($descriptionkey) {
 732              $mform->addElement($type, $name, get_string($descriptionkey, 'bigbluebuttonbn'), $options);
 733              if (get_string_manager()->string_exists($descriptionkey . '_help', 'bigbluebuttonbn')) {
 734                  $mform->addHelpButton($name, $descriptionkey, 'bigbluebuttonbn');
 735              }
 736          }
 737          if (!empty($rule)) {
 738              $mform->addRule($name, $rule['message'], $rule['type'], $rule['rule'], $rule['validator']);
 739          }
 740          $mform->setDefault($name, $defaultvalue);
 741          $mform->setType($name, $datatype);
 742      }
 743  
 744      /**
 745       * Definition after data
 746       *
 747       * Here just to tweak form group in completion that should not be frozen. This avoid
 748       * unwanted warnings.
 749       */
 750      public function definition_after_data() {
 751          parent::definition_after_data();
 752          foreach ($this->formextensions as $formextension) {
 753              $formextension->definition_after_data();
 754          }
 755      }
 756  
 757      /**
 758       * Add subplugins form elements
 759       * @return void
 760       */
 761      private function add_subplugins_elements() {
 762          foreach ($this->formextensions as $formextension) {
 763              $formextension->add_fields();
 764          }
 765      }
 766  }