AutorÃa | Ultima modificación | Ver Log |
<?php// This file is part of the Zoom plugin for Moodle - http://moodle.org///// Moodle is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// Moodle is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with Moodle. If not, see <http://www.gnu.org/licenses/>./*** The main zoom configuration form** It uses the standard core Moodle formslib. For more info about them, please* visit: http://docs.moodle.org/en/Development:lib/formslib.php** @package mod_zoom* @copyright 2015 UC Regents* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/defined('MOODLE_INTERNAL') || die();require_once($CFG->dirroot . '/course/moodleform_mod.php');require_once($CFG->dirroot . '/mod/zoom/lib.php');require_once($CFG->dirroot . '/mod/zoom/locallib.php');/*** Module instance settings form*/class mod_zoom_mod_form extends moodleform_mod {/*** Helper property for showing the scheduling privilege options.** @var bool*/private $showschedulingprivilege;/*** Defines forms elements*/public function definition() {global $PAGE, $USER, $OUTPUT;// We don't do anything custom with completion data, so avoid doing any unnecessary work.$completionpagetypes = ['course-defaultcompletion' => 'Edit completion default settings (Moodle >= 4.3)','course-editbulkcompletion' => 'Edit completion settings in bulk for a single course','course-editdefaultcompletion' => 'Edit completion default settings (Moodle < 4.3)',];if (isset($completionpagetypes[$PAGE->pagetype])) {return;}$config = get_config('zoom');$PAGE->requires->js_call_amd("mod_zoom/form", 'init');$isnew = empty($this->_cm);$zoomuserid = zoom_get_user_id(false);// If creating a new instance, but the Zoom user does not exist.if ($isnew && $zoomuserid === false) {// Assume user is using Zoom for the first time.$errstring = 'zoomerr_usernotfound';// After they set up their account, the user should continue to the page they were on.$nexturl = $PAGE->url;zoom_fatal_error($errstring, 'mod_zoom', $nexturl, $config->zoomurl);}// Array of emails and proper names of Moodle users in this course that// can add Zoom meetings, and the user can schedule.$scheduleusers = [];$canschedule = false;if ($zoomuserid !== false) {// Get the array of users they can schedule.$canschedule = zoom_webservice()->get_schedule_for_users($zoomuserid);}if (!empty($canschedule)) {// Add the current user.$canschedule[$zoomuserid] = new stdClass();$canschedule[$zoomuserid]->email = $USER->email;// If the activity exists and the current user is not the current host.if (!$isnew && $zoomuserid !== $this->current->host_id) {// Get intersection of current host's schedulers and $USER's schedulers to prevent zoom errors.$currenthostschedulers = zoom_webservice()->get_schedule_for_users($this->current->host_id);if (!empty($currenthostschedulers)) {// Since this is the second argument to array_intersect_key,// the entry from $canschedule will be used, so we can just// use true to avoid a service call.$currenthostschedulers[$this->current->host_id] = true;}$canschedule = array_intersect_key($canschedule, $currenthostschedulers);}// Get list of users who can add Zoom activities in this context.$moodleusers = get_enrolled_users($this->context, 'mod/zoom:addinstance', 0, 'u.*', 'lastname');// Check each potential host to see if they are a valid host.foreach ($canschedule as $zoomuserinfo) {$zoomemail = strtolower($zoomuserinfo->email);if (isset($scheduleusers[$zoomemail])) {continue;}if ($zoomemail === strtolower($USER->email)) {$scheduleusers[$zoomemail] = get_string('scheduleforself', 'zoom');continue;}foreach ($moodleusers as $muser) {if ($zoomemail === strtolower($muser->email)) {$scheduleusers[$zoomemail] = fullname($muser);break;}}}}if (!$isnew) {try {zoom_webservice()->get_meeting_webinar_info($this->current->meeting_id, $this->current->webinar);} catch (\mod_zoom\webservice_exception $error) {// If the meeting can't be found, offer to recreate the meeting on Zoom.if (zoom_is_meeting_gone_error($error)) {$errstring = 'zoomerr_meetingnotfound';$param = zoom_meetingnotfound_param($this->_cm->id);$nexturl = "/mod/zoom/view.php?id=" . $this->_cm->id;zoom_fatal_error($errstring, 'mod_zoom', $nexturl, $param, "meeting/get : $error");} else {throw $error;}}}// If the current editing user has the host saved in the db for this meeting on their list// of people that they can schedule for, allow them to change the host, otherwise don't.$allowschedule = false;if (!$isnew) {// Only need to check if there are scheduling options available.if (!empty($scheduleusers)) {try {$founduser = zoom_get_user($this->current->host_id);if ($founduser && array_key_exists($founduser->email, $scheduleusers)) {$allowschedule = true;}} catch (moodle_exception $error) {// Don't need to throw an error, just leave allowschedule as false.$allowschedule = false;}}} else {$allowschedule = true;}// Start of form definition.$mform = $this->_form;// Adding the "general" fieldset, where all the common settings are showed.$mform->addElement('header', 'general', get_string('general', 'form'));// Add title (stored in database as 'name').$mform->addElement('text', 'name', get_string('title', 'zoom'), ['size' => '64']);$mform->setType('name', PARAM_TEXT);$mform->addRule('name', null, 'required', null, 'client');$mform->addRule('name', get_string('maximumchars', '', 200), 'maxlength', 200, 'client');// Add description 'intro' and 'introformat'.$this->standard_intro_elements();// Adding the "schedule" fieldset, where all settings relating to date and time are shown.$mform->addElement('header', 'schedule', get_string('schedule', 'mod_zoom'));$mform->setExpanded('schedule');// Add date/time. Validation in validation().$starttimeoptions = ['step' => 5,'defaulttime' => time() + 3600,];$mform->addElement('date_time_selector', 'start_time', get_string('start_time', 'zoom'), $starttimeoptions);// Start time needs to be enabled/disabled based on recurring checkbox as well recurrence_type.// Moved this control to javascript, rather than using disabledIf.// Add duration.$mform->addElement('duration', 'duration', get_string('duration', 'zoom'), ['optional' => false]);// Validation in validation(). Default to one hour.$mform->setDefault('duration', ['number' => 1, 'timeunit' => 3600]);// Duration needs to be enabled/disabled based on recurring checkbox as well recurrence_type.// Moved this control to javascript, rather than using disabledIf.// Add recurring widget.$mform->addElement('advcheckbox','recurring',get_string('recurringmeeting', 'zoom'),get_string('recurringmeetingthisis', 'zoom'));$mform->setDefault('recurring', $config->defaultrecurring);$mform->addHelpButton('recurring', 'recurringmeeting', 'zoom');// Add options for recurring meeting.$recurrencetype = [ZOOM_RECURRINGTYPE_DAILY => get_string('recurrence_option_daily', 'zoom'),ZOOM_RECURRINGTYPE_WEEKLY => get_string('recurrence_option_weekly', 'zoom'),ZOOM_RECURRINGTYPE_MONTHLY => get_string('recurrence_option_monthly', 'zoom'),ZOOM_RECURRINGTYPE_NOTIME => get_string('recurrence_option_no_time', 'zoom'),];$mform->addElement('select', 'recurrence_type', get_string('recurrencetype', 'zoom'), $recurrencetype);// If the defaultrecurring option is active, set default recurrence_type to be No Fixed Time.if ($config->defaultrecurring == 1) {$mform->setDefault('recurrence_type', ZOOM_RECURRINGTYPE_NOTIME);}$mform->hideif('recurrence_type', 'recurring', 'notchecked');// Repeat Interval options.$options = [];for ($i = 1; $i <= 90; $i++) {$options[$i] = $i;}$group = [];$group[] = $mform->createElement('select', 'repeat_interval', '', $options);$htmlspantextstart = '<span class="repeat_interval" id="interval_';$htmlspantextend = '</span>';$group[] = $mform->createElement('html', $htmlspantextstart . 'daily">' . get_string('day', 'zoom') . $htmlspantextend);$group[] = $mform->createElement('html', $htmlspantextstart . 'weekly">' . get_string('week', 'zoom') . $htmlspantextend);$group[] = $mform->createElement('html', $htmlspantextstart . 'monthly">' . get_string('month', 'zoom') . $htmlspantextend);$mform->addGroup($group, 'repeat_group', get_string('repeatinterval', 'zoom'), null, false);$mform->hideif('repeat_group', 'recurrence_type', 'eq', ZOOM_RECURRINGTYPE_NOTIME);$mform->hideif('repeat_group', 'recurring', 'notchecked');// Weekly options.$weekdayoptions = zoom_get_weekday_options();$group = [];foreach ($weekdayoptions as $key => $weekday) {$weekdayid = 'weekly_days_' . $key;$attributes = [];$group[] = $mform->createElement('advcheckbox', $weekdayid, '', $weekday, null, [0, $key]);}$mform->addGroup($group, 'weekly_days_group', get_string('occurson', 'zoom'), ' ', false);$mform->hideif('weekly_days_group', 'recurrence_type', 'noteq', ZOOM_RECURRINGTYPE_WEEKLY);$mform->hideif('weekly_days_group', 'recurring', 'notchecked');if (!empty($this->current->weekly_days)) {$weekdaynumbers = explode(',', $this->current->weekly_days);foreach ($weekdaynumbers as $daynumber) {$weekdayid = 'weekly_days_' . $daynumber;$mform->setDefault($weekdayid, $daynumber);}}// Monthly options.$monthoptions = [];for ($i = 1; $i <= 31; $i++) {$monthoptions[$i] = $i;}$monthlyweekoptions = zoom_get_monthweek_options();$group = [];$group[] = $mform->createElement('radio','monthly_repeat_option','',get_string('day', 'calendar'),ZOOM_MONTHLY_REPEAT_OPTION_DAY);$group[] = $mform->createElement('select', 'monthly_day', '', $monthoptions);$group[] = $mform->createElement('static', 'month_day_text', '', get_string('month_day_text', 'zoom'));$group[] = $mform->createElement('radio', 'monthly_repeat_option', '', '', ZOOM_MONTHLY_REPEAT_OPTION_WEEK);$group[] = $mform->createElement('select', 'monthly_week', '', $monthlyweekoptions);$group[] = $mform->createElement('select', 'monthly_week_day', '', $weekdayoptions);$group[] = $mform->createElement('static', 'month_week_day_text', '', get_string('month_day_text', 'zoom'));$mform->addGroup($group, 'monthly_day_group', get_string('occurson', 'zoom'), null, false);$mform->hideif('monthly_day_group', 'recurrence_type', 'noteq', ZOOM_RECURRINGTYPE_MONTHLY);$mform->hideif('monthly_day_group', 'recurring', 'notchecked');$mform->setDefault('monthly_repeat_option', ZOOM_MONTHLY_REPEAT_OPTION_DAY);// End date option.$maxoptions = [];for ($i = 1; $i <= 50; $i++) {$maxoptions[$i] = $i;}$group = [];$group[] = $mform->createElement('radio','end_date_option','',get_string('end_date_option_by', 'zoom'),ZOOM_END_DATE_OPTION_BY);$group[] = $mform->createElement('date_selector', 'end_date_time', '');$group[] = $mform->createElement('radio','end_date_option','',get_string('end_date_option_after', 'zoom'),ZOOM_END_DATE_OPTION_AFTER);$group[] = $mform->createElement('select', 'end_times', '', $maxoptions);$group[] = $mform->createElement('static', 'end_times_text', '', get_string('end_date_option_occurrences', 'zoom'));$mform->addGroup($group, 'radioenddate', get_string('enddate', 'zoom'), null, false);$mform->hideif('radioenddate', 'recurring', 'notchecked');$mform->hideif('radioenddate', 'recurrence_type', 'eq', ZOOM_RECURRINGTYPE_NOTIME);// Set default option for end date to be "By".$mform->setDefault('end_date_option', ZOOM_END_DATE_OPTION_BY);// Set default end_date_time to be 1 week in the future.$mform->setDefault('end_date_time', strtotime('+1 week'));// Supplementary feature: Webinars.// Only show if the admin did not disable this feature completely.if ($config->showwebinars != ZOOM_WEBINAR_DISABLE) {// If we are creating a new instance.if ($isnew) {// Check if the user has a webinar license.$userfeatures = zoom_get_user_settings($zoomuserid)->feature;$haswebinarlicense = !empty($userfeatures->webinar) || !empty($userfeatures->zoom_events);// Only show if the admin always wants to show this widget or// if the admin wants to show this widget conditionally and the user has a valid license.if ($config->showwebinars == ZOOM_WEBINAR_ALWAYSSHOW ||($config->showwebinars == ZOOM_WEBINAR_SHOWONLYIFLICENSE && $haswebinarlicense)) {// Add webinar option, disabled if the user cannot create webinars.$webinarattr = null;if (!$haswebinarlicense) {$webinarattr = ['disabled' => true, 'group' => null];}$mform->addElement('advcheckbox','webinar',get_string('webinar', 'zoom'),get_string('webinarthisis', 'zoom'),$webinarattr);$mform->setDefault('webinar', $config->webinardefault);$mform->addHelpButton('webinar', 'webinar', 'zoom');}} else if ($this->current->webinar) {$mform->addElement('static','webinaralreadyset',get_string('webinar', 'zoom'),get_string('webinar_already_true', 'zoom'));} else {$mform->addElement('static','webinaralreadyset',get_string('webinar', 'zoom'),get_string('webinar_already_false', 'zoom'));}}// Add tracking fields, if configured in Moodle AND Zoom.$defaulttrackingfields = zoom_clean_tracking_fields();foreach ($defaulttrackingfields as $key => $defaulttrackingfield) {$configname = 'tf_' . $key . '_field';if (!empty($config->$configname)) {$mform->addElement('text', $key, $defaulttrackingfield);$mform->setType($key, PARAM_TEXT);$rvprop = 'tf_' . $key . '_recommended_values';if (!empty($config->$rvprop)) {$mform->addElement('static',$key . '_recommended_values',null,get_string('trackingfields_recommendedvalues', 'mod_zoom') . $config->$rvprop);}$requiredproperty = 'tf_' . $key . '_required';if (!empty($config->$requiredproperty)) {$mform->addRule($key, null, 'required', null, 'client');}}}// Add show widget.$mform->addElement('advcheckbox','show_schedule',get_string('showschedule', 'zoom'),get_string('showscheduleonview', 'zoom'));$mform->setDefault('show_schedule', $config->defaultshowschedule);$mform->addHelpButton('show_schedule', 'showschedule', 'zoom');// Add registration widget.$registrationoptions = [ZOOM_REGISTRATION_OFF => get_string('no'),ZOOM_REGISTRATION_AUTOMATIC => get_string('registration_text', 'mod_zoom'),];$mform->addElement('select', 'registration', get_string('registration', 'mod_zoom'), $registrationoptions);$mform->setDefault('registration', $config->defaultregistration);$mform->addHelpButton('registration', 'registration', 'mod_zoom');$mform->hideIf('registration', 'recurrence_type', 'eq', ZOOM_RECURRINGTYPE_NOTIME);// Adding the "breakout rooms" fieldset.$mform->addElement('header', 'breakoutrooms', get_string('breakoutrooms', 'mod_zoom'));$mform->setExpanded('breakoutrooms');$courseid = $this->current->course;$context = context_course::instance($courseid);$groups = groups_get_all_groups($courseid);$participants = get_enrolled_users($context);// Getting Course participants.$courseparticipants = [];foreach ($participants as $participant) {$courseparticipants[] = ['participantid' => $participant->id,'participantname' => fullname($participant) . ' <' . $participant->email . '>',];}// Getting Course groups.$coursegroups = [];foreach ($groups as $group) {$coursegroups[] = ['groupid' => $group->id, 'groupname' => $group->name];}// Building meeting breakout rooms template data.$templatedata = ['rooms' => [],'roomscount' => 0,'roomtoclone' => ['toclone' => 'toclone','courseparticipants' => $courseparticipants,'coursegroups' => $coursegroups,],];$currentinstance = $this->current->instance;if ($currentinstance) {$rooms = zoom_build_instance_breakout_rooms_array_for_view($currentinstance, $courseparticipants, $coursegroups);$templatedata['rooms'] = $rooms;$templatedata['roomscount'] = count($rooms);}$mform->addElement('html', $OUTPUT->render_from_template('zoom/breakoutrooms_rooms', $templatedata));$mform->addElement('hidden', 'rooms', '');$mform->setType('rooms', PARAM_RAW);$mform->addElement('hidden', 'roomsparticipants', '');$mform->setType('roomsparticipants', PARAM_RAW);$mform->addElement('hidden', 'roomsgroups', '');$mform->setType('roomsgroups', PARAM_RAW);// Adding the "security" fieldset, where all settings relating to securing and protecting the meeting are shown.$mform->addElement('header', 'security', get_string('security', 'mod_zoom'));$mform->setExpanded('security');// Deals with password manager issues.if (isset($this->current->password)) {$this->current->meetingcode = $this->current->password;unset($this->current->password);}// Add password requirement prompt.$mform->addElement('advcheckbox','requirepasscode',get_string('password', 'zoom'),get_string('requirepasscode', 'zoom'));if (isset($this->current->meetingcode) && strval($this->current->meetingcode) === "") {$mform->setDefault('requirepasscode', 0);} else {$mform->setDefault('requirepasscode', 1);}$mform->addHelpButton('requirepasscode', 'requirepasscode', 'zoom');// Set default passcode and description from Zoom security settings.$securitysettings = zoom_get_meeting_security_settings($this->current->host_id ?? $zoomuserid);// Add password.$mform->addElement('text', 'meetingcode', get_string('setpasscode', 'zoom'), ['maxlength' => '10']);$mform->setType('meetingcode', PARAM_TEXT);// Check password uses valid characters.$regex = '/^[a-zA-Z0-9@_*-]{1,10}$/';$mform->addRule('meetingcode', get_string('err_invalid_password', 'mod_zoom'), 'regex', $regex, 'client');$mform->setDefault('meetingcode', zoom_create_default_passcode($securitysettings->meeting_password_requirement));$mform->hideIf('meetingcode', 'requirepasscode', 'notchecked');// Add passcode requirements note (use mform group trick from MDL-66251 to be able to conditionally hide this).$passwordrequirementsgroup = [];$passwordrequirementsgroup[] =& $mform->createElement('static','passwordrequirements','',zoom_create_passcode_description($securitysettings->meeting_password_requirement));$mform->addGroup($passwordrequirementsgroup, 'passwordrequirementsgroup', '', '', false);$mform->hideIf('passwordrequirementsgroup', 'requirepasscode', 'notchecked');// Supplementary feature: Encryption type.// Only show if the admin did not disable this feature completely.if ($config->showencryptiontype != ZOOM_ENCRYPTION_DISABLE) {// Check if the user can use e2e encryption.$e2eispossible = $securitysettings->end_to_end_encrypted_meetings;if ($config->showencryptiontype == ZOOM_ENCRYPTION_SHOWONLYIFPOSSIBLE && !$e2eispossible) {// If user cannot use e2e and option is not shown to user,// default to enhanced encryption.$mform->addElement('hidden', 'option_encryption_type', ZOOM_ENCRYPTION_TYPE_ENHANCED);} else if ($config->showencryptiontype == ZOOM_ENCRYPTION_ALWAYSSHOW ||($config->showencryptiontype == ZOOM_ENCRYPTION_SHOWONLYIFPOSSIBLE && $e2eispossible)) {// Only show if the admin always wants to show this widget or// if the admin wants to show this widget conditionally and the user can use e2e encryption.// Add encryption type option, disabled if the user can't use e2e encryption.$encryptionattr = null;$defaultencryptiontype = $config->defaultencryptiontypeoption;if (!$e2eispossible) {$encryptionattr = ['disabled' => true];$defaultencryptiontype = ZOOM_ENCRYPTION_TYPE_ENHANCED;}$mform->addGroup([$mform->createElement('radio','option_encryption_type','',get_string('option_encryption_type_enhancedencryption', 'zoom'),ZOOM_ENCRYPTION_TYPE_ENHANCED,$encryptionattr),$mform->createElement('radio','option_encryption_type','',get_string('option_encryption_type_endtoendencryption', 'zoom'),ZOOM_ENCRYPTION_TYPE_E2EE,$encryptionattr),], 'option_encryption_type_group', get_string('option_encryption_type', 'zoom'), null, false);$mform->setDefault('option_encryption_type', $defaultencryptiontype);$mform->addHelpButton('option_encryption_type_group', 'option_encryption_type', 'zoom');$mform->disabledIf('option_encryption_type_group', 'webinar', 'checked');}$mform->setType('option_encryption_type', PARAM_ALPHANUMEXT);}// Add waiting room widget.$mform->addElement('advcheckbox','option_waiting_room',get_string('option_waiting_room', 'zoom'),get_string('waitingroomenable', 'zoom'));$mform->addHelpButton('option_waiting_room', 'option_waiting_room', 'zoom');$mform->setDefault('option_waiting_room', $config->defaultwaitingroomoption);$mform->disabledIf('option_waiting_room', 'webinar', 'checked');// Add join before host widget.$mform->addElement('advcheckbox','option_jbh',get_string('option_jbh', 'zoom'),get_string('joinbeforehostenable', 'zoom'));$mform->setDefault('option_jbh', $config->defaultjoinbeforehost);$mform->addHelpButton('option_jbh', 'option_jbh', 'zoom');$mform->disabledIf('option_jbh', 'webinar', 'checked');// Add authenticated users widget.$mform->addElement('advcheckbox','option_authenticated_users',get_string('authentication', 'zoom'),get_string('option_authenticated_users', 'zoom'));$mform->setDefault('option_authenticated_users', $config->defaultauthusersoption);$mform->addHelpButton('option_authenticated_users', 'option_authenticated_users', 'zoom');// Add show widget.$mform->addElement('advcheckbox','show_security',get_string('showsecurity', 'zoom'),get_string('showsecurityonview', 'zoom'));$mform->setDefault('show_security', $config->defaultshowsecurity);$mform->addHelpButton('show_security', 'showsecurity', 'zoom');// Adding the "media" fieldset, where all settings relating to media streams in the meeting are shown.$mform->addElement('header', 'media', get_string('media', 'mod_zoom'));$mform->setExpanded('media');// Add host/participants video options.$mform->addGroup([$mform->createElement('radio', 'option_host_video', '', get_string('on', 'zoom'), true),$mform->createElement('radio', 'option_host_video', '', get_string('off', 'zoom'), false),], 'option_host_video_group', get_string('option_host_video', 'zoom'), null, false);$mform->setDefault('option_host_video', $config->defaulthostvideo);$mform->addHelpButton('option_host_video_group', 'option_host_video', 'zoom');$mform->disabledIf('option_host_video_group', 'webinar', 'checked');$mform->addGroup([$mform->createElement('radio', 'option_participants_video', '', get_string('on', 'zoom'), true),$mform->createElement('radio', 'option_participants_video', '', get_string('off', 'zoom'), false),], 'option_participants_video_group', get_string('option_participants_video', 'zoom'), null, false);$mform->setDefault('option_participants_video', $config->defaultparticipantsvideo);$mform->addHelpButton('option_participants_video_group', 'option_participants_video', 'zoom');$mform->disabledIf('option_participants_video_group', 'webinar', 'checked');// Add audio options.$mform->addGroup([$mform->createElement('radio', 'option_audio', '', get_string('audio_telephony', 'zoom'), ZOOM_AUDIO_TELEPHONY),$mform->createElement('radio', 'option_audio', '', get_string('audio_voip', 'zoom'), ZOOM_AUDIO_VOIP),$mform->createElement('radio', 'option_audio', '', get_string('audio_both', 'zoom'), ZOOM_AUDIO_BOTH),], 'option_audio_group', get_string('option_audio', 'zoom'), null, false);$mform->addHelpButton('option_audio_group', 'option_audio', 'zoom');$mform->setDefault('option_audio', $config->defaultaudiooption);// Add mute participants upon entry widget.$mform->addElement('advcheckbox','option_mute_upon_entry',get_string('audiodefault', 'mod_zoom'),get_string('option_mute_upon_entry', 'mod_zoom'));$mform->setDefault('option_mute_upon_entry', $config->defaultmuteuponentryoption);$mform->addHelpButton('option_mute_upon_entry', 'option_mute_upon_entry', 'mod_zoom');// Add autorecording option if enabled.$allowrecordingchangeoption = $config->allowrecordingchangeoption;if ($allowrecordingchangeoption) {// Add auto recording options according to user settings.$options = [ZOOM_AUTORECORDING_NONE => get_string('autorecording_none', 'mod_zoom'),];$hostuserid = $zoomuserid;if (!empty($this->current->host_id)) {$hostuserid = $this->current->host_id;}if (!empty($hostuserid)) {$recordingsettings = zoom_get_user_settings($hostuserid)->recording;}if (!empty($recordingsettings->local_recording)) {$options[ZOOM_AUTORECORDING_LOCAL] = get_string('autorecording_local', 'mod_zoom');}if (!empty($recordingsettings->cloud_recording)) {$options[ZOOM_AUTORECORDING_CLOUD] = get_string('autorecording_cloud', 'mod_zoom');}if ($config->recordingoption === ZOOM_AUTORECORDING_USERDEFAULT) {$defaultsetting = $recordingsettings->auto_recording;} else {$defaultsetting = $config->recordingoption;}$mform->addElement('select', 'option_auto_recording', get_string('option_auto_recording', 'mod_zoom'), $options);$mform->setDefault('option_auto_recording', $defaultsetting);$mform->addHelpButton('option_auto_recording', 'option_auto_recording', 'mod_zoom');}// Add show widget.$mform->addElement('advcheckbox','show_media',get_string('showmedia', 'zoom'),get_string('showmediaonview', 'zoom'));$mform->setDefault('show_media', $config->defaultshowmedia);$mform->addHelpButton('show_media', 'showmedia', 'zoom');// Check if there is any setting to be shown in the "host" fieldset.$showschedulingprivilege = ($config->showschedulingprivilege != ZOOM_SCHEDULINGPRIVILEGE_DISABLE) &&count($scheduleusers) > 1 && $allowschedule; // Check if the size is greater than 1 because// we add the editing/creating user by default.$this->showschedulingprivilege = $showschedulingprivilege;$showalternativehosts = ($config->showalternativehosts != ZOOM_ALTERNATIVEHOSTS_DISABLE);if ($showschedulingprivilege || $showalternativehosts) {// Adding the "host" fieldset, where all settings relating to defining the meeting host are shown.$mform->addElement('header', 'host', get_string('host', 'mod_zoom'));$mform->setExpanded('host');// Supplementary feature: Alternative hosts.// Only show if the admin did not disable this feature completely.if ($showalternativehosts) {// Explain alternativehosts.$mform->addElement('static', 'hostintro', '', get_string('hostintro', 'zoom'));// If the admin wants to show the plain input field.if ($config->showalternativehosts == ZOOM_ALTERNATIVEHOSTS_INPUTFIELD) {// Add alternative hosts.$mform->addElement('text', 'alternative_hosts', get_string('alternative_hosts', 'zoom'), ['size' => '64']);$mform->setType('alternative_hosts', PARAM_TEXT);$mform->addHelpButton('alternative_hosts', 'alternative_hosts', 'zoom');// If the admin wants to show the user picker.} else if ($config->showalternativehosts == ZOOM_ALTERNATIVEHOSTS_PICKER) {// Get selectable alternative host users based on the capability.$alternativehostschoices = zoom_get_selectable_alternative_hosts_list($this->context);// Create autocomplete widget.$alternativehostsoptions = ['multiple' => true,'showsuggestions' => true,'placeholder' => get_string('alternative_hosts_picker_placeholder', 'zoom'),'noselectionstring' => get_string('alternative_hosts_picker_noneselected', 'zoom'),];$mform->addElement('autocomplete','alternative_hosts_picker',get_string('alternative_hosts', 'zoom'),$alternativehostschoices,$alternativehostsoptions);$mform->setType('alternative_hosts_picker', PARAM_EMAIL);$mform->addHelpButton('alternative_hosts_picker', 'alternative_hosts_picker', 'zoom');}}// Supplementary feature: Scheduling privilege.// Only show if the admin did not disable this feature completely and if current user is able to use it.if ($showschedulingprivilege) {if ($allowrecordingchangeoption) {$PAGE->requires->js_call_amd('mod_zoom/scheduleforchooser', 'init');$mform->addElement('select', 'schedule_for', get_string('schedulefor', 'mod_zoom'), $scheduleusers, ['data-scheduleforchooser-field' => 'selector',]);} else {$mform->addElement('select', 'schedule_for', get_string('schedulefor', 'mod_zoom'), $scheduleusers);}$mform->setType('schedule_for', PARAM_EMAIL);if (!$isnew) {$mform->disabledIf('schedule_for', 'change_schedule_for');$mform->addElement('checkbox', 'change_schedule_for', get_string('changehost', 'zoom'));$mform->setDefault('schedule_for', strtolower(zoom_get_user($this->current->host_id)->email));} else {$mform->setDefault('schedule_for', strtolower(zoom_get_api_identifier($USER)));}$mform->addHelpButton('schedule_for', 'schedulefor', 'zoom');if ($allowrecordingchangeoption) {// Button to update auto recording options based on the user permissions in Zoom (will be hidden by JavaScript).$mform->registerNoSubmitButton('updateautorecordingoptions');$mform->addElement('submit','updateautorecordingoptions',get_string('autorecordingoptionsupdate', 'mod_zoom'),['data-scheduleforchooser-field' => 'updateButton','class' => 'd-none',]);}}}// Adding option for Recording Visiblity by default.if (!empty($config->viewrecordings)) {$mform->addElement('header', 'recording', get_string('recording', 'mod_zoom'));$mform->addElement('advcheckbox','recordings_visible_default',get_string('recordingvisibility', 'mod_zoom'),get_string('yes'));$mform->setDefault('recordings_visible_default', 1);$mform->addHelpButton('recordings_visible_default', 'recordingvisibility', 'mod_zoom');}// Add meeting id.$mform->addElement('hidden', 'meeting_id', -1);$mform->setType('meeting_id', PARAM_ALPHANUMEXT);// Add host id (will error if user does not have an account on Zoom).$mform->addElement('hidden', 'host_id', zoom_get_user_id());$mform->setType('host_id', PARAM_ALPHANUMEXT);// Add standard grading elements.$this->standard_grading_coursemodule_elements();$mform->setDefault('grade', false);// Add standard elements, common to all modules.$this->standard_coursemodule_elements();$this->apply_admin_defaults();// Add standard buttons, common to all modules.$this->add_action_buttons();}/*** Add standard_grading_coursemodule_elements with grading for field.* @return void*/public function standard_grading_coursemodule_elements() {parent::standard_grading_coursemodule_elements();$mform = $this->_form;$itemnumber = 0;$component = "mod_{$this->_modname}";$gradefieldname = \core_grades\component_gradeitems::get_field_name_for_itemnumber($component, $itemnumber, 'grade');$options = ['entry' => get_string('gradingentry', 'mod_zoom'), // All credit upon entry.'period' => get_string('gradingperiod', 'mod_zoom'), // Credit according to attend duration.];$mform->addElement('select', 'grading_method', get_string('gradingmethod', 'mod_zoom'), $options);$mform->setDefault('grading_method', get_config('zoom', 'gradingmethod'));$mform->addHelpButton('grading_method', 'gradingmethod', 'zoom');$mform->hideIf('grading_method', "{$gradefieldname}[modgrade_type]", 'eq', 'none');}/*** Fill in the current page data for this course.*/public function definition_after_data() {parent::definition_after_data();// Get config.$config = get_config('zoom');if (!$config->allowrecordingchangeoption) {return;}$mform = $this->_form;if ($this->showschedulingprivilege) {$scheduleelement =& $mform->getElement('schedule_for');$values = $scheduleelement->getValue();if (empty($values)) {return;}$scheduleforuser = current($values);$zoomuser = zoom_get_user($scheduleforuser);$zoomuserid = $zoomuser->id;} else if (!empty($this->current->host_id)) {$zoomuserid = $this->current->host_id;} else {$zoomuserid = zoom_get_user_id(false);}$recordingelement =& $mform->getElement('option_auto_recording');$recordingelement->removeOptions();// Add auto recording options according to user settings.$options = [ZOOM_AUTORECORDING_NONE => get_string('autorecording_none', 'mod_zoom'),];if ($zoomuserid !== false) {$recordingsettings = zoom_get_user_settings($zoomuserid)->recording;}if (!empty($recordingsettings->local_recording)) {$options[ZOOM_AUTORECORDING_LOCAL] = get_string('autorecording_local', 'mod_zoom');}if (!empty($recordingsettings->cloud_recording)) {$options[ZOOM_AUTORECORDING_CLOUD] = get_string('autorecording_cloud', 'mod_zoom');}$recordingelement->load($options);}/*** Allows module to modify the data returned by form get_data().* This method is also called in the bulk activity completion form.** Only available on moodleform_mod.** @param stdClass $data the form data to be modified.*/public function data_postprocessing($data) {global $DB;parent::data_postprocessing($data);// Get config.$config = get_config('zoom');// If the admin did show the alternative hosts user picker.if ($config->showalternativehosts == ZOOM_ALTERNATIVEHOSTS_PICKER) {// If there was at least one alternative host selected, process these users.if (count($data->alternative_hosts_picker) > 0) {// Populate the alternative_hosts field with a concatenated string of email addresses.// This is done as this is the format which Zoom expects and alternative_hosts is the field to store the data// in mod_zoom.// The alternative host user picker is just an add-on to help teachers to fill this field.$data->alternative_hosts = implode(',', $data->alternative_hosts_picker);// If there wasn't any alternative host selected.} else {$data->alternative_hosts = '';}// Unfortunately, the host is not only able to add alternative hosts in Moodle with the user picker.// He is also able to add any alternative host with an email address in Zoom directly.// Thus, we have to get the latest list of alternative hosts from the DB again now,// identify the users who were not selectable at all in this form and append them to the list// of selected alternative hosts.// Get latest list of alternative hosts from the DB.$result = $DB->get_field('zoom', 'alternative_hosts', ['meeting_id' => $data->meeting_id], IGNORE_MISSING);// Proceed only if there is a field of alternative hosts already.if ($result !== false) {$alternativehostsdb = zoom_get_alternative_host_array_from_string($result);// Get selectable alternative host users based on the capability.$alternativehostschoices = zoom_get_selectable_alternative_hosts_list($this->context);// Iterate over the latest list of alternative hosts from the DB.foreach ($alternativehostsdb as $ah) {// If the existing alternative host would not have been selectable.if (!array_key_exists($ah, $alternativehostschoices)) {// Add the alternative host to the alternative_hosts field.if ($data->alternative_hosts == '') {$data->alternative_hosts = $ah;} else {$data->alternative_hosts .= ',' . $ah;}}}}}// Add some postprocessing around the recurrence settings.if ($data->recurring) {// If "No fixed time" meeting selected, dont need repeat_interval and other options.if ($data->recurrence_type == ZOOM_RECURRINGTYPE_NOTIME) {unset($data->repeat_interval);// Unset end_times and end_date.unset($data->end_date_option);unset($data->end_times);unset($data->end_date_time);}// If weekly recurring is not selected, unset weekly options.if ($data->recurrence_type != ZOOM_RECURRINGTYPE_WEEKLY) {// Unset the weekly fields.$data = zoom_remove_weekly_options($data);}// If monthly recurring is not selected, unset monthly options.if ($data->recurrence_type != ZOOM_RECURRINGTYPE_MONTHLY) {// Unset the weekly fields.$data = zoom_remove_monthly_options($data);}}// Make sure registration is not enabled for No Fixed Time recurring meetings.if ($data->recurring && $data->recurrence_type == ZOOM_RECURRINGTYPE_NOTIME) {if (isset($data->registration) && $data->registration == ZOOM_REGISTRATION_AUTOMATIC) {$data->registration = ZOOM_REGISTRATION_OFF;}}}/*** Allows module to modify data returned by get_moduleinfo_data() or prepare_new_moduleinfo_data() before calling set_data()* This method is also called in the bulk activity completion form.** Only available on moodleform_mod.** @param array $defaultvalues passed by reference*/public function data_preprocessing(&$defaultvalues) {global $DB;parent::data_preprocessing($defaultvalues);// Get config.$config = get_config('zoom');// If the admin wants to show the alternative hosts user picker.if ($config->showalternativehosts == ZOOM_ALTERNATIVEHOSTS_PICKER) {// If there is at least one alternative host set.if (isset($defaultvalues['alternative_hosts']) && strlen($defaultvalues['alternative_hosts']) > 0) {// Populate the alternative_hosts_picker field with an exploded array of email addresses.// This is done as alternative_hosts is the field to store the data in mod_zoom and// the alternative host user picker is just an add-on to help teachers to fill this field.// At this point, the alternative_hosts field might also contain users who are not selectable in the user picker// as they aren't a member of the course or do not have a Moodle account.// This does not matter as user picker default values which don't have a corresponding autocomplete suggestion// will be simply ignored.// When the form is submitted, these non-selectable alternative hosts will be added again in data_postprocessing().// According to the documentation, the Zoom API separates the email addresses with commas,// but we also want to deal with semicolon-separated lists just in case.$defaultvalues['alternative_hosts_picker'] = zoom_get_alternative_host_array_from_string($defaultvalues['alternative_hosts']);}}if ($config->defaulttrackingfields !== '') {// Populate modedit form fields with previously saved values.$defaulttrackingfields = zoom_clean_tracking_fields();$tfrows = $DB->get_records('zoom_meeting_tracking_fields', ['meeting_id' => $defaultvalues['id']]);foreach ($tfrows as $tfrow) {$tfkey = $tfrow->tracking_field;if (!empty($defaulttrackingfields[$tfkey])) {$defaultvalues[$tfkey] = $tfrow->value;}}}}/*** More validation on form data.* See documentation in lib/formslib.php.** @param array $data* @param array $files* @return array*/public function validation($data, $files) {global $CFG, $USER;$errors = parent::validation($data, $files);$config = get_config('zoom');// Only check for scheduled meetings.if (empty($data['recurring'])) {// Make sure start date is in the future.if ($data['start_time'] < time() && $data['meeting_id'] < 0) {$errors['start_time'] = get_string('err_start_time_past', 'zoom');}// Make sure duration is positive and no more than 150 hours.if ($data['duration'] <= 0) {$errors['duration'] = get_string('err_duration_nonpositive', 'zoom');} else if ($data['duration'] > 150 * 60 * 60) {$errors['duration'] = get_string('err_duration_too_long', 'zoom');}} else if ($data['recurring'] == 1 && $data['recurrence_type'] != ZOOM_RECURRINGTYPE_NOTIME) {// Make sure start date time (first potential date of next meeting) is in the future.if ($data['start_time'] < time() && $data['meeting_id'] < 0) {$errors['start_time'] = get_string('err_start_time_past_recurring', 'zoom');}// Make sure duration is positive and no more than 150 hours.if ($data['duration'] <= 0) {$errors['duration'] = get_string('err_duration_nonpositive', 'zoom');} else if ($data['duration'] > 150 * 60 * 60) {$errors['duration'] = get_string('err_duration_too_long', 'zoom');}}if (!empty($data['requirepasscode']) && empty($data['meetingcode'])) {$errors['meetingcode'] = get_string('err_password_required', 'mod_zoom');}if (isset($data['schedule_for']) && strtolower($data['schedule_for']) !== strtolower(zoom_get_api_identifier($USER))) {$zoomuserid = zoom_get_user_id();$scheduleusers = zoom_webservice()->get_schedule_for_users($zoomuserid);$scheduleok = false;foreach ($scheduleusers as $zuser) {if (strtolower($zuser->email) === strtolower($data['schedule_for'])) {// Found a matching email address in the Zoom users list.$scheduleok = true;break;}}if (!$scheduleok) {$errors['schedule_for'] = get_string('invalidscheduleuser', 'mod_zoom');}}// Supplementary feature: Alternative hosts.// Only validate if the admin did not disable this feature completely.if ($config->showalternativehosts != ZOOM_ALTERNATIVEHOSTS_DISABLE) {// If the admin did show the plain input field.if ($config->showalternativehosts == ZOOM_ALTERNATIVEHOSTS_INPUTFIELD) {// Check if the listed alternative hosts are valid users on Zoom.$alternativehosts = zoom_get_alternative_host_array_from_string($data['alternative_hosts']);foreach ($alternativehosts as $alternativehost) {if (!(zoom_get_user($alternativehost))) {$errors['alternative_hosts'] = get_string('zoomerr_alternativehostusernotfound', 'zoom', $alternativehost);break;}}// If the admin did show the user picker.} else if ($config->showalternativehosts == ZOOM_ALTERNATIVEHOSTS_PICKER) {// Check if the picked alternative hosts are valid users on Zoom.foreach ($data['alternative_hosts_picker'] as $alternativehost) {if (!(zoom_get_user($alternativehost))) {$errors['alternative_hosts_picker'] =get_string('zoomerr_alternativehostusernotfound', 'zoom', $alternativehost);break;}}}}// Supplementary feature: Encryption type.// Only validate if the admin did not disable this feature completely.if ($config->showencryptiontype != ZOOM_ENCRYPTION_DISABLE) {// Check if given encryption type is valid.if ($data['option_encryption_type'] !== ZOOM_ENCRYPTION_TYPE_ENHANCED &&$data['option_encryption_type'] !== ZOOM_ENCRYPTION_TYPE_E2EE) {// This will not happen unless the user tampered with the form.// Because of this, we skip adding this string to the language pack.$errors['option_encryption_type_group'] = 'The submitted encryption type is not valid.';}}// Add validation for recurring meeting.if ($data['recurring'] == 1) {if ($data['recurrence_type'] == ZOOM_RECURRINGTYPE_WEEKLY) {$weekdaynumbers = [];for ($i = 1; $i <= 7; $i++) {$key = 'weekly_days_' . $i;if (!empty($data[$key])) {$weekdaynumbers[] = $i;}}if (empty($weekdaynumbers)) {$errors['weekly_days_group'] = get_string('err_weekly_days', 'zoom');}// For weekly, maximum is 12 weeks.if ($data['repeat_interval'] > 12) {$errors['repeat_group'] = get_string('err_repeat_weekly_interval', 'zoom');}}if ($data['recurrence_type'] == ZOOM_RECURRINGTYPE_MONTHLY) {// For monthly, max is 3 months.if ($data['repeat_interval'] > 3) {$errors['repeat_group'] = get_string('err_repeat_monthly_interval', 'zoom');}}if ($data['recurrence_type'] != ZOOM_RECURRINGTYPE_NOTIME && $data['end_date_option'] == ZOOM_END_DATE_OPTION_BY) {if ($data['end_date_time'] < time()) {$errors['radioenddate'] = get_string('err_end_date', 'zoom');}if ($data['end_date_time'] < $data['start_time']) {$errors['radioenddate'] = get_string('err_end_date_before_start', 'zoom');}}}return $errors;}}