Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
<?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]); > }