Skip to content

Commit

Permalink
Merge branch 'ncstate-delta:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
fmido88 authored Sep 3, 2023
2 parents 7983941 + 802df30 commit 32fb3d7
Show file tree
Hide file tree
Showing 11 changed files with 219 additions and 36 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,26 @@ server is properly synchronized with the time servers.

## Changelog

v5.1.0

- Feature: Show activity date/time directly on course page #509 (thanks @cdipe)
- Regression: Auto recording was forced off by default #505 (thanks @emmarichardson)
- Introduced in v4.7.0 when adding automatic recording settings.
- Bugfix: Validate meeting name length using Zoom's 200 character limit #512 (thanks @lcollong)
- Bugfix: Resolve database inconsistencies #505 (thanks @fabianbatioja, @foxlapinou)
- Bugfix: Skip grading/completion during pre-registration #507 (thanks @tbeachy)
- Bugfix: Correct error message handling #503 (thanks @jwalits)
- Bugfix: Provide prescribed Promise parameters #499 (thanks @fmido88)

v5.0.0

- Backward incompatible: Drop support for JWT authentication (thanks @aspark21)
- Zoom requires everyone to use Server-to-Server OAuth by September 1, 2023
- Backward incompatible: Require PHP 7.1+ (Moodle 3.7+) (thanks @rlaneIT)
- Backward incompatible: Drop Moodle 3.4 mobile support

v4.10.3

- Bugfix: Also use proxy settings for OAuth token request #494 (thanks @adnbes)
- Bugfix: Clean up exception handling to avoid notice #482 (thanks @andremenrath)
- Bugfix: Avoid course/activity completion form overhead #481 (thanks @phette23)
Expand Down
1 change: 0 additions & 1 deletion backup/moodle2/restore_zoom_stepslib.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ protected function process_zoom($data) {
$data->join_url = '';
$data->meeting_id = 0;
$data->exists_on_zoom = ZOOM_MEETING_EXPIRED;
$data->option_auto_recording = 'none';
}

$data->course = $this->get_courseid();
Expand Down
71 changes: 71 additions & 0 deletions classes/dates.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
// This file is part of 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/>.

/**
* Contains the class for fetching the important dates in mod_zoom for a given module instance and a user.
*
* @package mod_zoom
* @copyright 2021 Shamim Rezaie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

declare(strict_types=1);

namespace mod_zoom;

use core\activity_dates;

/**
* Class for fetching the important dates in mod_zoom for a given module instance and a user.
*
* @copyright 2021 Shamim Rezaie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class dates extends activity_dates {
/**
* Returns a list of important dates in mod_zoom
*
* @return array
*/
protected function get_dates(): array {
$starttime = $this->cm->customdata['start_time'] ?? null;
$duration = $this->cm->customdata['duration'] ?? null;
$now = time();
$dates = [];

if ($starttime) {
if ($duration && $starttime + $duration < $now) {
// Meeting has ended.
$dataid = 'end_date_time';
$labelid = 'activitydate:ended';
$meetimgtimestamp = $starttime + $duration;
} else {
// Meeting hasn't started / in progress, or without fixed time (doesn't have an end date or time).
$dataid = 'start_time';
$labelid = $starttime > $now ? 'activitydate:starts' : 'activitydate:started';
$meetimgtimestamp = $starttime;
}

$dates[] = [
'dataid' => $dataid,
'label' => get_string($labelid, 'mod_zoom'),
'timestamp' => $meetimgtimestamp,
];
}

return $dates;
}
}
42 changes: 21 additions & 21 deletions db/install.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="mod/zoom/db" VERSION="20221003" COMMENT="Zoom module"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
<XMLDB PATH="mod/zoom/db" VERSION="20230803" COMMENT="Zoom module"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="zoom" COMMENT="Zoom meetings and webinars">
Expand All @@ -20,16 +20,16 @@
<FIELD NAME="start_time" TYPE="int" LENGTH="12" NOTNULL="false" SEQUENCE="false" COMMENT="Meeting start time (Unix timestamp, seconds). For scheduled meeting only."/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="12" NOTNULL="false" SEQUENCE="false" COMMENT="Timestamp when the instance was last modified."/>
<FIELD NAME="recurring" TYPE="int" LENGTH="1" NOTNULL="false" DEFAULT="0" SEQUENCE="false" COMMENT="Is the meeting or webinar recurring?"/>
<FIELD NAME="recurrence_type" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false" COMMENT="Is the recurring meeting weekly, daily or monthly" />
<FIELD NAME="repeat_interval" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false" COMMENT="Specify the repeat interval of the meeting" />
<FIELD NAME="weekly_days" TYPE="char" LENGTH="14" NOTNULL="false" SEQUENCE="false" COMMENT="Specify the days for weekly recurring meetings" />
<FIELD NAME="monthly_day" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false" COMMENT="Specify the day for a recurring monthly meeting" />
<FIELD NAME="monthly_week" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false" COMMENT="Specify the week for a recurring monthly meeting" />
<FIELD NAME="monthly_week_day" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false" COMMENT="Specify a day of the week for a recurring monthly meeting" />
<FIELD NAME="monthly_repeat_option" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false" COMMENT="For UI purposes. To determine which monthly repeat option is chosen" />
<FIELD NAME="end_times" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false" COMMENT="The amount of times meeting should occur before its canceled" />
<FIELD NAME="end_date_time" TYPE="int" LENGTH="12" NOTNULL="false" SEQUENCE="false" COMMENT="The final date (Unix timestamp, seconds) of the meeting before its canceled" />
<FIELD NAME="end_date_option" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false" COMMENT="For UI purposes. To determine which end date option is chosen" />
<FIELD NAME="recurrence_type" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false" COMMENT="Is the recurring meeting weekly, daily or monthly"/>
<FIELD NAME="repeat_interval" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false" COMMENT="Specify the repeat interval of the meeting"/>
<FIELD NAME="weekly_days" TYPE="char" LENGTH="14" NOTNULL="false" SEQUENCE="false" COMMENT="Specify the days for weekly recurring meetings"/>
<FIELD NAME="monthly_day" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false" COMMENT="Specify the day for a recurring monthly meeting"/>
<FIELD NAME="monthly_week" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false" COMMENT="Specify the week for a recurring monthly meeting"/>
<FIELD NAME="monthly_week_day" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false" COMMENT="Specify a day of the week for a recurring monthly meeting"/>
<FIELD NAME="monthly_repeat_option" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false" COMMENT="For UI purposes. To determine which monthly repeat option is chosen"/>
<FIELD NAME="end_times" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false" COMMENT="The amount of times meeting should occur before its canceled"/>
<FIELD NAME="end_date_time" TYPE="int" LENGTH="12" NOTNULL="false" SEQUENCE="false" COMMENT="The final date (Unix timestamp, seconds) of the meeting before its canceled"/>
<FIELD NAME="end_date_option" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false" COMMENT="For UI purposes. To determine which end date option is chosen"/>
<FIELD NAME="webinar" TYPE="int" LENGTH="1" NOTNULL="false" DEFAULT="0" SEQUENCE="false" COMMENT="Is this a webinar?"/>
<FIELD NAME="duration" TYPE="int" LENGTH="6" NOTNULL="false" SEQUENCE="false" COMMENT="Meeting duration (seconds). For scheduled meeting only."/>
<FIELD NAME="timezone" TYPE="char" LENGTH="50" NOTNULL="false" SEQUENCE="false" COMMENT="Timezone to format start_time, like &quot;America/Los_Angeles&quot;. For scheduled meeting only."/>
Expand All @@ -45,12 +45,12 @@
<FIELD NAME="option_encryption_type" TYPE="char" LENGTH="20" NOTNULL="false" DEFAULT="enhanced_encryption" SEQUENCE="false" COMMENT="Meeting encryption type. Can be &quot;enhanced_encryption&quot;, &quot;e2ee&quot;"/>
<FIELD NAME="exists_on_zoom" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="Whether the meeting can be found on Zoom servers. Usually should be true, should only be false if API call returned that meeting can't be found."/>
<FIELD NAME="alternative_hosts" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="recordings_visible_default" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="Should the recordings for this meeting be visible by default" />
<FIELD NAME="show_schedule" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="Show Schedule heading in activity page" />
<FIELD NAME="show_security" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="Show Security heading in activity page" />
<FIELD NAME="show_media" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="Show Media heading in activity page" />
<FIELD NAME="option_auto_recording" TYPE="char" LENGTH="5" NOTNULL="true" DEFAULT="none" SEQUENCE="false" COMMENT="Auto record meeting." />
<FIELD NAME="registration" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="2" SEQUENCE="false" COMMENT="Force participants to register for the meeting/webinar" />
<FIELD NAME="recordings_visible_default" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="Should the recordings for this meeting be visible by default"/>
<FIELD NAME="show_schedule" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="Show Schedule heading in activity page"/>
<FIELD NAME="show_security" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="Show Security heading in activity page"/>
<FIELD NAME="show_media" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="Show Media heading in activity page"/>
<FIELD NAME="option_auto_recording" TYPE="char" LENGTH="5" NOTNULL="false" SEQUENCE="false" COMMENT="Auto record meeting."/>
<FIELD NAME="registration" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="2" SEQUENCE="false" COMMENT="Force participants to register for the meeting/webinar"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
Expand Down Expand Up @@ -125,8 +125,8 @@
<FIELD NAME="externalurl" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="Link to view the recording."/>
<FIELD NAME="passcode" TYPE="char" LENGTH="30" NOTNULL="false" SEQUENCE="false" COMMENT="Passcode to access the recording."/>
<FIELD NAME="recordingtype" TYPE="char" LENGTH="30" NOTNULL="true" SEQUENCE="false" COMMENT="Type of recording."/>
<FIELD NAME="recordingstart" TYPE="int" LENGTH="12" NOTNULL="true" SEQUENCE="false" />
<FIELD NAME="showrecording" TYPE="int" LENGTH="1" NOTNULL="true" SEQUENCE="false" DEFAULT="0" />
<FIELD NAME="recordingstart" TYPE="int" LENGTH="12" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="showrecording" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="12" NOTNULL="false" SEQUENCE="false" COMMENT="Timestamp when the record was created."/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="12" NOTNULL="false" SEQUENCE="false" COMMENT="Timestamp when the record was last modified."/>
</FIELDS>
Expand Down
33 changes: 29 additions & 4 deletions db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -735,19 +735,20 @@ function xmldb_zoom_upgrade($oldversion) {
$table = new xmldb_table('zoom');

// Define and conditionally add field show_schedule.
$field = new xmldb_field('show_schedule', XMLDB_TYPE_INTEGER, '1', null, null, null, '1', 'recordings_visible_default');
$field = new xmldb_field('show_schedule', XMLDB_TYPE_INTEGER, '1',
null, XMLDB_NOTNULL, null, '1', 'recordings_visible_default');
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}

// Define and conditionally add field show_security.
$field = new xmldb_field('show_security', XMLDB_TYPE_INTEGER, '1', null, null, null, '1', 'show_schedule');
$field = new xmldb_field('show_security', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'show_schedule');
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}

// Define and conditionally add field show_media.
$field = new xmldb_field('show_media', XMLDB_TYPE_INTEGER, '1', null, null, null, '1', 'show_security');
$field = new xmldb_field('show_media', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'show_security');
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
Expand Down Expand Up @@ -830,7 +831,7 @@ function xmldb_zoom_upgrade($oldversion) {
$table = new xmldb_table('zoom');

// Define and conditionally add field registration.
$field = new xmldb_field('registration', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '2', 'option_auto_recording');
$field = new xmldb_field('registration', XMLDB_TYPE_INTEGER, '1', null, null, null, null, 'option_auto_recording');
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
Expand All @@ -839,5 +840,29 @@ function xmldb_zoom_upgrade($oldversion) {
upgrade_mod_savepoint(true, 2022102700, 'zoom');
}

if ($oldversion < 2023080202) {
// Issue #432: Inconsistency between the DB and schema, this is to verify everything matches.
// Verify show_schedule, show_security, and show_media are all set to NOTNULL.
// Verify option_auto_record is set to NOTNULL and defaults to "none".
$table = new xmldb_table('zoom');

// Launch change of nullability for show schedule.
$field = new xmldb_field('show_schedule', XMLDB_TYPE_INTEGER, '1',
null, XMLDB_NOTNULL, null, '1', 'recordings_visible_default');
$dbman->change_field_notnull($table, $field);

$field = new xmldb_field('show_security', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'show_schedule');
$dbman->change_field_notnull($table, $field);

$field = new xmldb_field('show_media', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'show_security');
$dbman->change_field_notnull($table, $field);

$field = new xmldb_field('option_auto_recording', XMLDB_TYPE_CHAR, '5', null, null, null, null, 'show_media');
$dbman->change_field_type($table, $field);

// Zoom savepoint reached.
upgrade_mod_savepoint(true, 2023080202, 'zoom');
}

return true;
}
3 changes: 3 additions & 0 deletions lang/en/zoom.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
$string['accountid'] = 'Zoom account ID';
$string['accountid_desc'] = '';
$string['actions'] = 'Actions';
$string['activitydate:starts'] = 'Starts: ';
$string['activitydate:started'] = 'Started: ';
$string['activitydate:ended'] = 'Ended: ';
$string['addparticipant'] = 'Add a participant';
$string['addparticipantgroup'] = 'Add a group of participants';
$string['addroom'] = 'Add a room';
Expand Down
66 changes: 63 additions & 3 deletions lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,6 @@ function populate_zoom_from_response(stdClass $zoom, stdClass $response) {
if (isset($response->settings->auto_recording)) {
$newzoom->option_auto_recording = $response->settings->auto_recording;
}
if (!isset($newzoom->option_auto_recording)) {
$newzoom->option_auto_recording = 'none';
}

return $newzoom;
}
Expand Down Expand Up @@ -1274,3 +1271,66 @@ function zoom_get_instance_breakout_rooms($zoomid) {

return $breakoutrooms;
}

/**
* Print zoom meeting date and time in the course listing page
*
* Given a course_module object, this function returns any "extra" information that may be needed
* when printing this activity in a course listing. See get_array_of_activities() in course/lib.php.
*
* @param stdClass $coursemodule The coursemodule object
* @return cached_cm_info An object on information that the courses will know about
*/
function zoom_get_coursemodule_info($coursemodule) {
global $DB;

$dbparams = array('id' => $coursemodule->instance);
$fields = 'id, intro, introformat, start_time, duration';
if (!$zoom = $DB->get_record('zoom', $dbparams, $fields)) {
return false;
}

$result = new cached_cm_info();

if ($coursemodule->showdescription) {
// Convert intro to html. Do not filter cached version, filters run at display time.
$result->content = format_module_intro('zoom', $zoom, $coursemodule->id, false);
}

// Populate some other values that can be used in calendar or on dashboard.
if ($zoom->start_time) {
$result->customdata['start_time'] = $zoom->start_time;
}

if ($zoom->duration) {
$result->customdata['duration'] = $zoom->duration;
}

return $result;
}

/**
* Sets dynamic information about a course module
*
* This function is called from cm_info when displaying the module
*
* @param cm_info $cm
*/
function zoom_cm_info_dynamic(cm_info $cm) {
global $CFG, $DB;

require_once($CFG->dirroot . '/mod/zoom/locallib.php');

if (method_exists($cm, 'override_customdata')) {
$moduleinstance = $DB->get_record('zoom', array('id' => $cm->instance), '*', MUST_EXIST);

// Get meeting state from Zoom.
list($inprogress, $available, $finished) = zoom_get_state($moduleinstance);

// For unfinished meetings, override start_time with the next occurrence.
// If this is a recurring meeting without fixed time, do not override - it will set start_time = 0.
if (!$finished && $moduleinstance->recurrence_type != 0) {
$cm->override_customdata('start_time', zoom_get_next_occurrence($moduleinstance));
}
}
}
Loading

0 comments on commit 32fb3d7

Please sign in to comment.