See Release Notes
Long Term Support Release
<?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/>. /** * Privacy class for requesting user data. * * @package core * @category privacy * @copyright 2018 Andrew Nicols <andrew@nicols.co.uk> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core\privacy; defined('MOODLE_INTERNAL') || die(); use core_privacy\local\metadata\collection; 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\userlist;> use core_privacy\local\request\writer;/** * Privacy class for requesting user data. * * @package core * @copyright 2018 Andrew Nicols <andrew@nicols.co.uk> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class provider implements \core_privacy\local\metadata\provider, \core_privacy\local\request\subsystem\provider, \core_privacy\local\request\core_userlist_provider { /** * Returns information about the user data stored in this component. * * @param collection $collection A list of information about this component * @return collection The collection object filled out with information about this component. */ public static function get_metadata(collection $collection) : collection {< // These tables are really data about site configuration and not user data.> // Except for moodlenet_share_progress, these tables are really data about site configuration and not user data.// The config_log includes information about which user performed a configuration change. // The value and oldvalue may contain sensitive information such as accounts for service passwords.. // This is not considered to be user data. $collection->add_database_table('config_log', [ 'userid' => 'privacy:metadata:config_log:userid', 'timemodified' => 'privacy:metadata:config_log:timemodified', 'plugin' => 'privacy:metadata:config_log:plugin', 'name' => 'privacy:metadata:config_log:name', 'value' => 'privacy:metadata:config_log:value', 'oldvalue' => 'privacy:metadata:config_log:oldvalue', ], 'privacy:metadata:config_log'); // The upgrade_log includes information about which user performed an upgrade. // This is not considered to be user data. $collection->add_database_table('upgrade_log', [ 'type' => 'privacy:metadata:upgrade_log:type', 'plugin' => 'privacy:metadata:upgrade_log:plugin', 'version' => 'privacy:metadata:upgrade_log:version', 'targetversion' => 'privacy:metadata:upgrade_log:targetversion', 'info' => 'privacy:metadata:upgrade_log:info', 'details' => 'privacy:metadata:upgrade_log:details', 'backtrace' => 'privacy:metadata:upgrade_log:backtrace', 'userid' => 'privacy:metadata:upgrade_log:userid', 'timemodified' => 'privacy:metadata:upgrade_log:timemodified', ], 'privacy:metadata:upgrade_log'); // The task_adhoc includes information about pending adhoc tasks, some of which may be run as a user. // These are removed as the task completes. $collection->add_database_table('task_adhoc', [ 'component' => 'privacy:metadata:task_adhoc:component', 'nextruntime' => 'privacy:metadata:task_adhoc:nextruntime', 'userid' => 'privacy:metadata:task_adhoc:userid', ], 'privacy:metadata:task_adhoc'); // The task_log table stores debugging data for tasks. // These are cleaned regularly and intended purely for debugging. $collection->add_database_table('task_log', [ 'component' => 'privacy:metadata:task_log:component', 'userid' => 'privacy:metadata:task_log:userid', ], 'privacy:metadata:task_log'); // The events_queue includes information about pending events tasks. // These are stored for short periods whilst being processed into other locations. $collection->add_database_table('events_queue', [ 'eventdata' => 'privacy:metadata:events_queue:eventdata', 'stackdump' => 'privacy:metadata:events_queue:stackdump', 'userid' => 'privacy:metadata:events_queue:userid', 'timecreated' => 'privacy:metadata:events_queue:timecreated', ], 'privacy:metadata:events_queue'); // The log table is defined in core but used in logstore_legacy. $collection->add_database_table('log', [ 'time' => 'privacy:metadata:log:time', 'userid' => 'privacy:metadata:log:userid', 'ip' => 'privacy:metadata:log:ip', 'action' => 'privacy:metadata:log:action', 'url' => 'privacy:metadata:log:url', 'info' => 'privacy:metadata:log:info' ], 'privacy:metadata:log'); // The oauth2_refresh_token stores refresh tokens, allowing ongoing access to select oauth2 services. // Such tokens are not considered to be user data. $collection->add_database_table('oauth2_refresh_token', [ 'timecreated' => 'privacy:metadata:oauth2_refresh_token:timecreated', 'timemodified' => 'privacy:metadata:oauth2_refresh_token:timemodified', 'userid' => 'privacy:metadata:oauth2_refresh_token:userid', 'issuerid' => 'privacy:metadata:oauth2_refresh_token:issuerid', 'token' => 'privacy:metadata:oauth2_refresh_token:token', 'scopehash' => 'privacy:metadata:oauth2_refresh_token:scopehash' ], 'privacy:metadata:oauth2_refresh_token');> // The moodlenet_share_progress includes details of an attempted share of a resource to MoodleNet. return $collection; > $collection->add_database_table('moodlenet_share_progress', [ } > 'type' => 'privacy:metadata:moodlenet_share_progress:type', > 'courseid' => 'privacy:metadata:moodlenet_share_progress:courseid', /** > 'cmid' => 'privacy:metadata:moodlenet_share_progress:cmid', * Get the list of contexts that contain user information for the specified user. > 'userid' => 'privacy:metadata:moodlenet_share_progress:userid', * > 'timecreated' => 'privacy:metadata:moodlenet_share_progress:timecreated', * @param int $userid The user to search. > 'resourceurl' => 'privacy:metadata:moodlenet_share_progress:resourceurl', * @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin. > 'status' => 'privacy:metadata:moodlenet_share_progress:status', */ > ], 'privacy:metadata:moodlenet_share_progress'); public static function get_contexts_for_userid(int $userid) : contextlist { > return new contextlist(); > // This resourceurl field is an external link from MoodleNet. } > $collection->add_external_location_link('moodlenet_share_progress', [ > 'resourceurl' => 'privacy:metadata:moodlenet_share_progress:resourceurl', /** > ], 'privacy:metadata:moodlenet_share_progress'); * Get the list of users who have data within a context. >< return new contextlist();> $contextlist = new contextlist(); > > // MoodleNet share progress uses the user context. > $sql = "SELECT ctx.id > FROM {context} ctx > JOIN {moodlenet_share_progress} msp ON ctx.instanceid = msp.userid > AND ctx.contextlevel = :contextlevel > WHERE msp.userid = :userid"; > $params = ['userid' => $userid, 'contextlevel' => CONTEXT_USER]; > $contextlist->add_from_sql($sql, $params); > > return $contextlist;* @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) {< // Don't add any user.> // Except for moodlenet_share_progress, don't add any users. > $context = $userlist->get_context(); > > // MoodleNet share progress uses the user context. > if ($context->contextlevel == CONTEXT_USER) { > // Get all distinct userids from the table. > $sql = "SELECT DISTINCT userid > FROM {moodlenet_share_progress} > WHERE userid = :userid"; > $params = ['userid' => $context->instanceid]; > $userlist->add_from_sql('userid', $sql, $params); > }} /** * Export all user data for the specified user, in the specified contexts. * * @param approved_contextlist $contextlist The approved contexts to export information for. */ public static function export_user_data(approved_contextlist $contextlist) {< // None of the core tables should be exported.> // Except for moodlenet_share_progress, none of the core tables should be exported. > global $DB; > > foreach ($contextlist as $context) { > // MoodleNet share progress uses the user context. > if ($context->contextlevel == CONTEXT_USER && $context->instanceid == $contextlist->get_user()->id) { > // Get the user's MoodleNet share progress data. > $sharedata = $DB->get_records('moodlenet_share_progress', ['userid' => $context->instanceid]); > $subcontext = get_string('privacy:metadata:moodlenet_share_progress', 'moodle'); > writer::with_context($context)->export_data([$subcontext], (object) $sharedata); > } > }} /** * Delete all data for all users in the specified context. *< * @param context $context The specific context to delete data for.> * @param \context $context The specific context to delete data for.*/ public static function delete_data_for_all_users_in_context(\context $context) {< // None of the the data from these tables should be deleted.> // Except for moodlenet_share_progress, none of the the data from these tables should be deleted. > global $DB; > > // MoodleNet share progress uses the user context. > if ($context->contextlevel == CONTEXT_USER) { > $DB->delete_records('moodlenet_share_progress', ['userid' => $context->instanceid]); > }} /** * 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) {< // None of the the data from these tables should be deleted.> // Except for moodlenet_share_progress, none of the the data from these tables should be deleted.// Note: Although it may be tempting to delete the adhoc task data, do not do so. // The delete process is run as an adhoc task.> global $DB; } > > foreach ($contextlist as $context) { /** > // MoodleNet share progress uses the user context. * Delete multiple users within a single context. > if ($context->contextlevel == CONTEXT_USER && $context->instanceid == $contextlist->get_user()->id) { * > $DB->delete_records('moodlenet_share_progress', ['userid' => $context->instanceid]); * @param approved_userlist $userlist The approved context and user information to delete information for. > } */ > }public static function delete_data_for_users(approved_userlist $userlist) {< // None of the the data from these tables should be deleted.> // Except for moodlenet_share_progress, none of the the data from these tables should be deleted.// Note: Although it may be tempting to delete the adhoc task data, do not do so. // The delete process is run as an adhoc task.> global $DB; } > } > $context = $userlist->get_context(); > > if (!in_array($context->instanceid, $userlist->get_userids())) { > return; > } > > // MoodleNet share progress uses the user context. > if ($context->contextlevel == CONTEXT_USER) { > $DB->delete_records('moodlenet_share_progress', ['userid' => $context->instanceid]); > }