+<?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_course
+ * @copyright 2018 Adrian Greeve <adrian@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core_course\privacy;
+
+defined('MOODLE_INTERNAL') || die();
+
+use \core_privacy\local\metadata\collection;
+use \core_privacy\local\request\contextlist;
+use \core_privacy\local\request\approved_contextlist;
+use \core_privacy\local\request\writer;
+use \core_privacy\local\request\transform;
+
+/**
+ * Privacy class for requesting user data.
+ *
+ * @package core_course
+ * @copyright 2018 Adrian Greeve <adrian@moodle.com>
+ * @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\context_aware_provider,
+ \core_privacy\local\request\plugin\provider,
+ \core_privacy\local\request\user_preference_provider {
+
+ /**
+ * Returns meta data about this system.
+ *
+ * @param collection $collection The initialised collection to add items to.
+ * @return collection A listing of user data stored through this system.
+ */
+ public static function get_metadata(collection $collection) : collection {
+ $collection->add_subsystem_link('core_completion', [], 'privacy:metadata:completionsummary');
+ $collection->add_user_preference('coursecat_management_perpage', 'privacy:perpage');
+ return $collection;
+ }
+
+ /**
+ * Get the list of contexts that contain user information for the specified user.
+ *
+ * @param int $userid The user to search.
+ * @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
+ */
+ public static function get_contexts_for_userid(int $userid) : contextlist {
+ list($join, $where, $params) = \core_completion\privacy\provider::get_course_completion_join_sql($userid, 'cc', 'c.id');
+ $sql = "SELECT ctx.id
+ FROM {context} ctx
+ JOIN {course} c ON ctx.instanceid = c.id AND ctx.contextlevel = :contextcourse
+ {$join}
+ WHERE {$where}";
+ $params['contextcourse'] = CONTEXT_COURSE;
+ $contextlist = new contextlist();
+ $contextlist->add_from_sql($sql, $params);
+ return $contextlist;
+ }
+
+ /**
+ * 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) {
+ global $DB;
+
+ // Get the course.
+ list($select, $params) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
+ $params['contextcourse'] = CONTEXT_COURSE;
+
+ $sql = "SELECT c.*
+ FROM {course} c
+ JOIN {context} ctx ON c.id = ctx.instanceid AND ctx.contextlevel = :contextcourse
+ WHERE ctx.id $select";
+
+ $courses = $DB->get_recordset_sql($sql, $params);
+ foreach ($courses as $course) {
+ $coursecompletion = \core_completion\privacy\provider::get_course_completion_info($contextlist->get_user(), $course);
+ writer::with_context(\context_course::instance($course->id))->export_data(
+ [get_string('privacy:completionpath', 'course')], (object) $coursecompletion);
+ }
+ $courses->close();
+ }
+
+ /**
+ * Exports course information based on the whole approved context list collection.
+ *
+ * @param \core_privacy\local\request\contextlist_collection $contextcollection The collection of approved context lists.
+ */
+ public static function export_complete_context_data(\core_privacy\local\request\contextlist_collection $completelist) {
+ global $DB;
+
+ $coursecontextids = $DB->get_records('context', ['contextlevel' => CONTEXT_COURSE], '', 'id, instanceid');
+
+ $courseids = [];
+ foreach ($completelist as $component) {
+ foreach ($component->get_contexts() as $context) {
+ if ($context->contextlevel == CONTEXT_USER
+ || $context->contextlevel == CONTEXT_SYSTEM
+ || $context->contextlevel == CONTEXT_COURSECAT) {
+ // Move onto the next context as these will not contain course contexts.
+ continue;
+ }
+ foreach ($coursecontextids as $contextid => $record) {
+ if (stripos($context->path, '/' . $contextid . '/') !== false) {
+ $courseids[$contextid] = $record->instanceid;
+ }
+ }
+ }
+ }
+ if (empty($courseids)) {
+ return;
+ }
+
+ // Export general data for these contexts.
+ list($sql, $params) = $DB->get_in_or_equal($courseids);
+ $sql = 'id ' . $sql;
+ $coursedata = $DB->get_records_select('course', $sql, $params);
+
+ foreach ($coursedata as $course) {
+ $context = \context_course::instance($course->id);
+ $data = (object) [
+ 'fullname' => $course->fullname,
+ 'shortname' => $course->shortname,
+ 'idnumber' => $course->idnumber,
+ 'summary' => writer::with_context($context)->rewrite_pluginfile_urls([], 'course', 'summary', 0, $course->summary),
+ 'format' => get_string('pluginname', 'format_' . $course->format),
+ 'startdate' => transform::datetime($course->startdate),
+ 'enddate' => transform::datetime($course->enddate)
+ ];
+ writer::with_context($context)
+ ->export_area_files([], 'course', 'summary', 0)
+ ->export_area_files([], 'course', 'overviewfiles', 0)
+ ->export_data([], $data);
+ }
+ }
+
+ /**
+ * Export all user preferences for the plugin.
+ *
+ * @param int $userid The userid of the user whose data is to be exported.
+ */
+ public static function export_user_preferences(int $userid) {
+ $perpage = get_user_preferences('coursecat_management_perpage', null, $userid);
+ if (isset($perpage)) {
+ writer::export_user_preference('core_course',
+ 'coursecat_management_perpage',
+ $perpage,
+ get_string('privacy:perpage', 'course')
+ );
+ }
+ }
+
+ /**
+ * Delete all data for all users in the specified context.
+ *
+ * @param context $context The specific context to delete data for.
+ */
+ public static function delete_data_for_all_users_in_context(\context $context) {
+ // Check what context we've been delivered.
+ if ($context->contextlevel == CONTEXT_COURSE) {
+ // Delete course completion data.
+ \core_completion\privacy\provider::delete_completion(null, $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) {
+ foreach ($contextlist as $context) {
+ if ($context->contextlevel == CONTEXT_COURSE) {
+ // Delete course completion data.
+ \core_completion\privacy\provider::delete_completion($contextlist->get_user(), $context->instanceid);
+ }
+ }
+ }
+}