AutorÃa | Ultima modificación | Ver Log |
<?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 class mod_zoom\privacy\provider** @package mod_zoom* @copyright 2018 UC Regents* @author Kubilay Agi* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/namespace mod_zoom\privacy;use context;use context_module;use core_privacy\local\metadata\collection;use core_privacy\local\metadata\provider as metadata_provider;use core_privacy\local\request\approved_contextlist;use core_privacy\local\request\approved_userlist;use core_privacy\local\request\contextlist;use core_privacy\local\request\core_userlist_provider;use core_privacy\local\request\helper;use core_privacy\local\request\plugin\provider as request_plugin_provider;use core_privacy\local\request\transform;use core_privacy\local\request\userlist;use core_privacy\local\request\writer;/*** Ad hoc task that performs the actions for approved data privacy requests.*/class provider implements core_userlist_provider, metadata_provider, request_plugin_provider {/*** Returns meta data about this system.** @param collection $coll The collection to add metadata to.* @return collection The array of metadata*/public static function get_metadata(collection $coll): collection {// Add all user data fields to the collection.$coll->add_database_table('zoom_meeting_participants', ['name' => 'privacy:metadata:zoom_meeting_participants:name','user_email' => 'privacy:metadata:zoom_meeting_participants:user_email','join_time' => 'privacy:metadata:zoom_meeting_participants:join_time','leave_time' => 'privacy:metadata:zoom_meeting_participants:leave_time','duration' => 'privacy:metadata:zoom_meeting_participants:duration',], 'privacy:metadata:zoom_meeting_participants');$coll->add_database_table('zoom_meeting_details',['topic' => 'privacy:metadata:zoom_meeting_details:topic'],'privacy:metadata:zoom_meeting_details');$coll->add_database_table('zoom_meeting_recordings_view',['userid' => 'privacy:metadata:zoom_meeting_view:userid'],'privacy:metadata:zoom_meeting_view');$coll->add_database_table('zoom_breakout_participants',['userid' => 'privacy:metadata:zoom_breakout_participants:userid'],'privacy:metadata:zoom_breakout_participants');return $coll;}/*** Get the list of contexts that contain user information for the specified user.** @param int $userid The user to search.* @return contextlist $contextlist The list of contexts used in this plugin.*/public static function get_contexts_for_userid(int $userid): contextlist {// Query the database for context IDs give a specific user ID and return these to the user.$contextlist = new contextlist();$sql = 'SELECT c.idFROM {context} cINNER JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevelINNER JOIN {modules} m ON m.id = cm.module AND m.name = :modnameINNER JOIN {zoom} z ON z.id = cm.instanceLEFT JOIN {zoom_meeting_details} zmd ON zmd.zoomid = z.idLEFT JOIN {zoom_meeting_participants} zmp ON zmp.detailsid = zmd.idLEFT JOIN {zoom_meeting_recordings} zmr ON zmr.zoomid = z.idLEFT JOIN {zoom_meeting_recordings_view} zmrv ON zmrv.recordingsid = zmr.idWHERE zmp.userid = :userid1 OR zmrv.userid = :userid2';$params = ['modname' => 'zoom','contextlevel' => CONTEXT_MODULE,'userid1' => $userid,'userid2' => $userid,];$contextlist->add_from_sql($sql, $params);return $contextlist;}/*** Get the list of users who have data within a context.** @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.*/public static function get_users_in_context(userlist $userlist) {$context = $userlist->get_context();if (!($context instanceof context_module)) {return;}$params = ['instanceid' => $context->instanceid,'modulename' => 'zoom',];$sql = "SELECT zmp.useridFROM {zoom_meeting_participants} zmpJOIN {zoom_meeting_details} zmd ON zmd.id = zmp.detailsidJOIN {zoom} z ON zmd.zoomid = z.idJOIN {modules} m ON m.name = :modulenameJOIN {course_modules} cm ON z.id = cm.instance AND m.id = cm.moduleWHERE cm.id = :instanceid";$userlist->add_from_sql('userid', $sql, $params);$sql = "SELECT zmrv.useridFROM {zoom_meeting_recordings_view} zmrvJOIN {zoom_meeting_recordings} zmr ON zmr.id = zmrv.recordingsidJOIN {zoom} z ON zmr.zoomid = z.idJOIN {modules} m ON m.name = :modulenameJOIN {course_modules} cm ON z.id = cm.instance AND m.id = cm.moduleWHERE cm.id = :instanceid";$userlist->add_from_sql('userid', $sql, $params);$sql = "SELECT zbp.useridFROM {zoom_breakout_participants} zbpJOIN {zoom_meeting_breakout_rooms} zmbr ON zbp.breakoutroomid = zmbr.idJOIN {zoom} z ON zmbr.zoomid = z.idJOIN {modules} m ON m.name = :modulenameJOIN {course_modules} cm ON z.id = cm.instance AND m.id = cm.moduleWHERE cm.id = :instanceid";$userlist->add_from_sql('userid', $sql, $params);}/*** Export all user data for the specified user, in the specified contexts, using the supplied exporter instance.** @param approved_contextlist $contextlist The approved contexts to export information for.* @link http://tandl.churchward.ca/2018/06/implementing-moodles-privacy-api-in.html*/public static function export_user_data(approved_contextlist $contextlist) {global $DB;if (empty($contextlist->count())) {return;}$user = $contextlist->get_user();[$contextsql, $contextparams] = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);$sql = "SELECT zmp.id,zmd.topic,zmp.name,zmp.user_email,zmp.join_time,zmp.leave_time,zmp.duration,cm.id AS cmidFROM {context} cINNER JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevelINNER JOIN {modules} m ON m.id = cm.module AND m.name = :modnameINNER JOIN {zoom} z ON z.id = cm.instanceINNER JOIN {zoom_meeting_details} zmd ON zmd.zoomid = z.idINNER JOIN {zoom_meeting_participants} zmp ON zmp.detailsid = zmd.idWHERE c.id $contextsqlAND zmp.userid = :useridORDER BY cm.id ASC";$params = ['modname' => 'zoom','contextlevel' => CONTEXT_MODULE,'userid' => $user->id,] + $contextparams;$participantinstances = $DB->get_recordset_sql($sql, $params);foreach ($participantinstances as $participantinstance) {$context = context_module::instance($participantinstance->cmid);$contextdata = helper::get_context_data($context, $user);$instancedata = ['topic' => $participantinstance->topic,'participant_name' => $participantinstance->name,'user_email' => $participantinstance->user_email,'join_time' => transform::datetime($participantinstance->join_time),'leave_time' => transform::datetime($participantinstance->leave_time),'duration' => $participantinstance->duration,];$contextdata = (object) array_merge((array) $contextdata, $instancedata);writer::with_context($context)->export_data([], $contextdata);}$participantinstances->close();$sql = "SELECT zmrv.id,zmr.name,zmrv.userid,zmrv.viewed,zmrv.timemodified,cm.id AS cmidFROM {context} cINNER JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevelINNER JOIN {modules} m ON m.id = cm.module AND m.name = :modnameINNER JOIN {zoom} z ON z.id = cm.instanceINNER JOIN {zoom_meeting_recordings} zmr ON zmr.zoomid = z.idINNER JOIN {zoom_meeting_recordings_view} zmrv ON zmrv.recordingsid = zmr.idWHERE c.id $contextsqlAND zmrv.userid = :useridORDER BY cm.id ASC";$params = ['modname' => 'zoom','contextlevel' => CONTEXT_MODULE,'userid' => $user->id,] + $contextparams;$recordingviewinstances = $DB->get_recordset_sql($sql, $params);foreach ($recordingviewinstances as $recordingviewinstance) {$context = context_module::instance($recordingviewinstance->cmid);$contextdata = helper::get_context_data($context, $user);$instancedata = ['recording_name' => $recordingviewinstance->name,'userid' => $recordingviewinstance->userid,'viewed' => $recordingviewinstance->viewed,'timemodified' => transform::datetime($recordingviewinstance->timemodified),];$contextdata = (object) array_merge((array) $contextdata, $instancedata);writer::with_context($context)->export_data([], $contextdata);}$recordingviewinstances->close();}/*** Delete all personal data for all users in the specified context.** @param context $context Context to delete data from.*/public static function delete_data_for_all_users_in_context(context $context) {global $DB;if (!($context instanceof context_module)) {return;}// We delete each participant entry manually because deletes do not cascade.if ($cm = get_coursemodule_from_id('zoom', $context->instanceid)) {$meetingdetails = $DB->get_records('zoom_meeting_details', ['zoomid' => $cm->instance]);foreach ($meetingdetails as $meetingdetail) {$DB->delete_records('zoom_meeting_participants', ['detailsid' => $meetingdetail->id]);}$DB->delete_records('zoom_meeting_details', ['zoomid' => $cm->instance]);$meetingrecordings = $DB->get_records('zoom_meeting_recordings', ['zoomid' => $cm->instance]);foreach ($meetingrecordings as $recording) {$DB->delete_records('zoom_meeting_recordings_view', ['recordingsid' => $recording->id]);}$DB->delete_records('zoom_meeting_recordings', ['zoomid' => $cm->instance]);$breakoutrooms = $DB->get_records('zoom_meeting_breakout_rooms', ['zoomid' => $cm->instance]);foreach ($breakoutrooms as $room) {$DB->delete_records('zoom_breakout_participants', ['breakoutroomid' => $room->id]);}$DB->delete_records('zoom_meeting_breakout_rooms', ['zoomid' => $cm->instance]);}}/*** Delete all user data for the specified user, in the specified contexts.** @param approved_contextlist $contextlist The approved contexts and user information to delete information for.*/public static function delete_data_for_user(approved_contextlist $contextlist) {global $DB;if (empty($contextlist->count())) {return;}$user = $contextlist->get_user();foreach ($contextlist->get_contexts() as $context) {if (!($context instanceof context_module)) {continue;}if ($cm = get_coursemodule_from_id('zoom', $context->instanceid)) {$meetingdetails = $DB->get_records('zoom_meeting_details', ['zoomid' => $cm->instance]);foreach ($meetingdetails as $meetingdetail) {$DB->delete_records('zoom_meeting_participants', ['detailsid' => $meetingdetail->id, 'userid' => $user->id]);}$meetingrecordings = $DB->get_records('zoom_meeting_recordings', ['zoomid' => $cm->instance]);foreach ($meetingrecordings as $recording) {$DB->delete_records('zoom_meeting_recordings_view', ['recordingsid' => $recording->id, 'userid' => $user->id]);}$breakoutrooms = $DB->get_records('zoom_meeting_breakout_rooms', ['zoomid' => $cm->instance]);foreach ($breakoutrooms as $room) {$DB->delete_records('zoom_breakout_participants', ['breakoutroomid' => $room->id, 'userid' => $user->id]);}}}}/*** Delete multiple users within a single context.** @param approved_userlist $userlist The approved context and user information to delete information for.*/public static function delete_data_for_users(approved_userlist $userlist) {global $DB;$context = $userlist->get_context();if (!($context instanceof context_module)) {return;}// Prepare SQL to gather all completed IDs.$userids = $userlist->get_userids();[$insql, $inparams] = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);$params = array_merge($inparams, ['contextid' => $context->id, 'modlevel' => CONTEXT_MODULE]);$sql = "SELECT zmd.idFROM {zoom_meeting_details} zmdJOIN {zoom} z ON zmd.zoomid = z.idJOIN {modules} m ON m.name = 'zoom'JOIN {course_modules} cm ON z.id = cm.instance AND m.id = cm.moduleJOIN {context} ctx ON ctx.instanceid = cm.id AND ctx.contextlevel = :modlevelWHERE ctx.id = :contextid";$DB->delete_records_select('zoom_meeting_participants', "userid $insql AND detailsid IN ($sql)", $params);$sql = "SELECT zmr.idFROM {zoom_meeting_recordings} zmrJOIN {zoom} z ON zmr.zoomid = z.idJOIN {modules} m ON m.name = 'zoom'JOIN {course_modules} cm ON z.id = cm.instance AND m.id = cm.moduleJOIN {context} ctx ON cm.id = ctx.instanceid AND ctx.contextlevel = :modlevelWHERE ctx.id = :contextid";$DB->delete_records_select('zoom_meeting_recordings_view', "userid $insql AND recordingsid IN ($sql)", $params);$sql = "SELECT zmbr.idFROM {zoom_meeting_breakout_rooms} zmbrJOIN {zoom} z ON zmbr.zoomid = z.idJOIN {modules} m ON m.name = 'zoom'JOIN {course_modules} cm ON z.id = cm.instance AND m.id = cm.moduleJOIN {context} ctx ON ctx.instanceid = cm.id AND ctx.contextlevel = :modlevelWHERE ctx.id = :contextid";$DB->delete_records_select('zoom_breakout_participants', "userid $insql AND breakoutroomid IN ($sql)", $params);}}