2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 * Privacy class for requesting user data.
20 * @package core_grading
21 * @copyright 2018 Sara Arjona <sara@moodle.com>
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 namespace core_grading\privacy
;
27 defined('MOODLE_INTERNAL') ||
die();
29 use \core_privacy\local\metadata\collection
;
30 use \core_privacy\local\request\approved_contextlist
;
31 use \core_privacy\local\request\contextlist
;
32 use \core_privacy\local\request\transform
;
33 use \core_privacy\local\request\writer
;
34 use \core_privacy\manager
;
37 * Privacy class for requesting user data.
39 * @copyright 2018 Sara Arjona <sara@moodle.com>
40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42 class provider
implements
43 \core_privacy\local\metadata\provider
,
44 \core_privacy\local\request\subsystem\provider
{
47 * Returns meta data about this system.
49 * @param collection $collection The initialised collection to add items to.
50 * @return collection A listing of user data stored through this system.
52 public static function get_metadata(collection
$collection) : collection
{
53 $collection->add_database_table('grading_definitions', [
54 'method' => 'privacy:metadata:grading_definitions:method',
55 'areaid' => 'privacy:metadata:grading_definitions:areaid',
56 'name' => 'privacy:metadata:grading_definitions:name',
57 'description' => 'privacy:metadata:grading_definitions:description',
58 'status' => 'privacy:metadata:grading_definitions:status',
59 'copiedfromid' => 'privacy:metadata:grading_definitions:copiedfromid',
60 'timecopied' => 'privacy:metadata:grading_definitions:timecopied',
61 'timecreated' => 'privacy:metadata:grading_definitions:timecreated',
62 'usercreated' => 'privacy:metadata:grading_definitions:usercreated',
63 'timemodified' => 'privacy:metadata:grading_definitions:timemodified',
64 'usermodified' => 'privacy:metadata:grading_definitions:usermodified',
65 'options' => 'privacy:metadata:grading_definitions:options',
66 ], 'privacy:metadata:grading_definitions');
68 $collection->add_database_table('grading_instances', [
69 'raterid' => 'privacy:metadata:grading_instances:raterid',
70 'rawgrade' => 'privacy:metadata:grading_instances:rawgrade',
71 'status' => 'privacy:metadata:grading_instances:status',
72 'feedback' => 'privacy:metadata:grading_instances:feedback',
73 'feedbackformat' => 'privacy:metadata:grading_instances:feedbackformat',
74 'timemodified' => 'privacy:metadata:grading_instances:timemodified',
75 ], 'privacy:metadata:grading_instances');
78 $collection->add_plugintype_link('gradingform', [], 'privacy:metadata:gradingformpluginsummary');
84 * Get the list of contexts that contain user information for the specified user.
86 * @param int $userid The user to search.
87 * @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
89 public static function get_contexts_for_userid(int $userid) : contextlist
{
90 $contextlist = new contextlist();
94 JOIN {grading_areas} a ON a.contextid = c.id
95 JOIN {grading_definitions} d ON d.areaid = a.id
96 LEFT JOIN {grading_instances} i ON i.definitionid = d.id AND i.raterid = :raterid
97 WHERE c.contextlevel = :contextlevel
98 AND (d.usercreated = :usercreated OR d.usermodified = :usermodified OR i.id IS NOT NULL)";
100 'usercreated' => $userid,
101 'usermodified' => $userid,
102 'raterid' => $userid,
103 'contextlevel' => CONTEXT_MODULE
105 $contextlist->add_from_sql($sql, $params);
111 * Export all user data for the specified user, in the specified contexts.
113 * @param approved_contextlist $contextlist The approved contexts to export information for.
115 public static function export_user_data(approved_contextlist
$contextlist) {
116 // Remove contexts different from MODULE.
117 $contexts = array_reduce($contextlist->get_contexts(), function($carry, $context) {
118 if ($context->contextlevel
== CONTEXT_MODULE
) {
124 if (empty($contexts)) {
128 $userid = $contextlist->get_user()->id
;
129 $subcontext = [get_string('gradingmethod', 'grading')];
130 foreach ($contexts as $context) {
131 // Export grading definitions created or modified on this context.
132 self
::export_definitions($context, $subcontext, $userid);
137 * Exports the data related to grading definitions within the specified context/subcontext.
139 * @param \context $context Context owner of the data.
140 * @param array $subcontext Subcontext owner of the data.
141 * @param int $userid The user whose information is to be exported.
143 protected static function export_definitions(\context
$context, array $subcontext, int $userid = 0) {
146 $join = "JOIN {grading_areas} a ON a.id = d.areaid
147 JOIN {context} c ON a.contextid = c.id AND c.contextlevel = :contextlevel";
148 $select = 'a.contextid = :contextid';
150 'contextlevel' => CONTEXT_MODULE
,
151 'contextid' => $context->id
154 if (!empty($userid)) {
155 $join .= ' LEFT JOIN {grading_instances} i ON i.definitionid = d.id AND i.raterid = :raterid';
156 $select .= ' AND (usercreated = :usercreated
157 OR usermodified = :usermodified OR i.id IS NOT NULL)';
158 $params['usercreated'] = $userid;
159 $params['usermodified'] = $userid;
160 $params['raterid'] = $userid;
163 $sql = "SELECT gd.id,
174 FROM {grading_definitions} d
178 JOIN {grading_definitions} gd ON gd.id = ids.id";
179 $definitions = $DB->get_recordset_sql($sql, $params);
181 foreach ($definitions as $definition) {
183 'method' => $definition->method
,
184 'name' => $definition->name
,
185 'description' => $definition->description
,
186 'timecreated' => transform
::datetime($definition->timecreated
),
187 'usercreated' => transform
::user($definition->usercreated
),
188 'timemodified' => transform
::datetime($definition->timemodified
),
189 'usermodified' => transform
::user($definition->usermodified
),
191 if (!empty($definition->timecopied
)) {
192 $tmpdata['timecopied'] = transform
::datetime($definition->timecopied
);
194 // Export gradingform information (if needed).
195 $instancedata = manager
::component_class_callback(
196 "gradingform_{$definition->method}",
197 gradingform_provider
::class,
198 'get_gradingform_export_data',
199 [$context, $definition, $userid]
201 if (null !== $instancedata) {
202 $tmpdata = array_merge($tmpdata, $instancedata);
205 $defdata[] = (object) $tmpdata;
207 // Export grading_instances information.
208 self
::export_grading_instances($context, $subcontext, $definition->id
, $userid);
210 $definitions->close();
212 if (!empty($defdata)) {
214 'definitions' => $defdata,
217 writer
::with_context($context)->export_data($subcontext, $data);
222 * Exports the data related to grading instances within the specified definition.
224 * @param \context $context Context owner of the data.
225 * @param array $subcontext Subcontext owner of the data.
226 * @param int $definitionid The definition ID whose grading instance information is to be exported.
227 * @param int $userid The user whose information is to be exported.
229 protected static function export_grading_instances(\context
$context, array $subcontext, int $definitionid, int $userid = 0) {
232 $params = ['definitionid' => $definitionid];
233 if (!empty($userid)) {
234 $params['raterid'] = $userid;
236 $instances = $DB->get_recordset('grading_instances', $params);
238 foreach ($instances as $instance) {
239 // TODO: Get the status name (instead of the ID).
241 'rawgrade' => $instance->rawgrade
,
242 'status' => $instance->status
,
243 'feedback' => $instance->feedback
,
244 'feedbackformat' => $instance->feedbackformat
,
245 'timemodified' => transform
::datetime($instance->timemodified
),
247 $instancedata[] = (object) $tmpdata;
251 if (!empty($instancedata)) {
253 'instances' => $instancedata,
256 writer
::with_context($context)->export_related_data($subcontext, 'gradinginstances', $data);
261 * Delete all use data which matches the specified $context.
263 * We never delete grading content.
265 * @param context $context A user context.
267 public static function delete_data_for_all_users_in_context(\context
$context) {
268 manager
::plugintype_class_callback(
270 gradingform_provider
::class,
271 'delete_gradingform_for_context',
277 * Delete all user data for the specified user, in the specified contexts.
279 * We never delete grading content.
281 * @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
283 public static function delete_data_for_user(approved_contextlist
$contextlist) {
284 manager
::plugintype_class_callback(
286 gradingform_provider
::class,
287 'delete_gradingform_for_userid',