Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

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