Merge branch 'MDL-63903-master' of https://github.com/snake/moodle
[moodle.git] / admin / tool / dataprivacy / classes / privacy / provider.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
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.
8 //
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.
13 //
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/>.
17 /**
18  * Privacy class for requesting user data.
19  *
20  * @package    tool_dataprivacy
21  * @copyright  2018 Jake Dallimore <jrhdallimore@gmail.com>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 namespace tool_dataprivacy\privacy;
26 defined('MOODLE_INTERNAL') || die();
28 use coding_exception;
29 use context;
30 use context_user;
31 use core_privacy\local\metadata\collection;
32 use core_privacy\local\request\approved_contextlist;
33 use \core_privacy\local\request\approved_userlist;
34 use core_privacy\local\request\contextlist;
35 use core_privacy\local\request\helper;
36 use core_privacy\local\request\transform;
37 use \core_privacy\local\request\userlist;
38 use core_privacy\local\request\writer;
39 use dml_exception;
40 use stdClass;
41 use tool_dataprivacy\api;
42 use tool_dataprivacy\local\helper as tool_helper;
44 /**
45  * Privacy class for requesting user data.
46  *
47  * @package    tool_dataprivacy
48  * @copyright  2018 Jake Dallimore <jrhdallimore@gmail.com>
49  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
50  */
51 class provider implements
52         // This tool stores user data.
53         \core_privacy\local\metadata\provider,
55         // This plugin is capable of determining which users have data within it.
56         \core_privacy\local\request\core_userlist_provider,
58         // This tool may provide access to and deletion of user data.
59         \core_privacy\local\request\plugin\provider,
61         // This plugin has some sitewide user preferences to export.
62         \core_privacy\local\request\user_preference_provider {
63     /**
64      * Returns meta data about this system.
65      *
66      * @param   collection $collection The initialised collection to add items to.
67      * @return  collection     A listing of user data stored through this system.
68      */
69     public static function get_metadata(collection $collection) : collection {
70         $collection->add_database_table(
71             'tool_dataprivacy_request',
72             [
73                 'comments' => 'privacy:metadata:request:comments',
74                 'userid' => 'privacy:metadata:request:userid',
75                 'requestedby' => 'privacy:metadata:request:requestedby',
76                 'dpocomment' => 'privacy:metadata:request:dpocomment',
77                 'timecreated' => 'privacy:metadata:request:timecreated'
78             ],
79             'privacy:metadata:request'
80         );
82         $collection->add_user_preference(tool_helper::PREF_REQUEST_FILTERS,
83             'privacy:metadata:preference:tool_dataprivacy_request-filters');
84         $collection->add_user_preference(tool_helper::PREF_REQUEST_PERPAGE,
85             'privacy:metadata:preference:tool_dataprivacy_request-perpage');
87         return $collection;
88     }
90     /**
91      * Get the list of contexts that contain user information for the specified user.
92      *
93      * @param   int $userid The user to search.
94      * @return  contextlist   $contextlist  The contextlist containing the list of contexts used in this plugin.
95      */
96     public static function get_contexts_for_userid(int $userid) : contextlist {
97         $sql = "SELECT id
98                   FROM {context}
99                  WHERE instanceid = :userid
100                        AND contextlevel = :contextlevel";
102         $contextlist = new contextlist();
103         $contextlist->set_component('tool_dataprivacy');
104         $contextlist->add_from_sql($sql, ['userid' => $userid, 'contextlevel' => CONTEXT_USER]);
105         return $contextlist;
106     }
108     /**
109      * Get the list of users who have data within a context.
110      *
111      * @param   userlist    $userlist   The userlist containing the list of users who have data in this context/plugin combination.
112      *
113      */
114     public static function get_users_in_context(userlist $userlist) {
115         $context = $userlist->get_context();
117         if (!is_a($context, \context_user::class)) {
118             return;
119         }
121         $params = [
122             'contextlevel' => CONTEXT_USER,
123             'contextid' => $context->id,
124         ];
126         $sql = "SELECT instanceid AS userid
127                   FROM {context}
128                  WHERE id = :contextid
129                        AND contextlevel = :contextlevel";
131         $userlist->add_from_sql('userid', $sql, $params);
132     }
134     /**
135      * Export all user data for the specified user, in the specified contexts.
136      *
137      * @param approved_contextlist $contextlist The approved contexts to export information for.
138      * @throws coding_exception
139      * @throws dml_exception
140      * @throws \moodle_exception
141      */
142     public static function export_user_data(approved_contextlist $contextlist) {
143         if (empty($contextlist->count())) {
144             return;
145         }
147         $user = $contextlist->get_user();
148         $datarequests = api::get_data_requests($user->id);
149         $context = context_user::instance($user->id);
150         $contextdatatowrite = [];
151         foreach ($datarequests as $request) {
152             $record = $request->to_record();
153             $data = new stdClass();
155             // The user ID that made the request/the request is made for.
156             if ($record->requestedby != $record->userid) {
157                 if ($user->id != $record->requestedby) {
158                     // This request is done by this user for another user.
159                     $data->userid = fullname($user);
160                 } else if ($user->id != $record->userid) {
161                     // This request was done by another user on behalf of this user.
162                     $data->requestedby = fullname($user);
163                 }
164             }
166             // Request type.
167             $data->type = tool_helper::get_shortened_request_type_string($record->type);
168             // Status.
169             $data->status = tool_helper::get_request_status_string($record->status);
170             // Comments.
171             $data->comments = $record->comments;
172             // The DPO's comment about this request.
173             $data->dpocomment = $record->dpocomment;
174             // The date and time this request was lodged.
175             $data->timecreated = transform::datetime($record->timecreated);
176             $contextdatatowrite[] = $data;
177         }
179         // User context / Privacy and policies / Data requests.
180         $subcontext = [
181             get_string('privacyandpolicies', 'admin'),
182             get_string('datarequests', 'tool_dataprivacy'),
183         ];
184         writer::with_context($context)->export_data($subcontext, (object)$contextdatatowrite);
186         // Write generic module intro files.
187         helper::export_context_files($context, $user);
188     }
190     /**
191      * Delete all data for all users in the specified context.
192      *
193      * @param context $context The specific context to delete data for.
194      */
195     public static function delete_data_for_all_users_in_context(context $context) {
196     }
198     /**
199      * Delete all user data for the specified user, in the specified contexts.
200      *
201      * @param   approved_contextlist $contextlist The approved contexts and user information to delete information for.
202      */
203     public static function delete_data_for_user(approved_contextlist $contextlist) {
204     }
206     /**
207      * Delete multiple users within a single context.
208      *
209      * @param   approved_userlist    $userlist The approved context and user information to delete information for.
210      *
211      */
212     public static function delete_data_for_users(approved_userlist $userlist) {
213     }
215     /**
216      * Export all user preferences for the plugin.
217      *
218      * @param   int $userid The userid of the user whose data is to be exported.
219      */
220     public static function export_user_preferences(int $userid) {
221         $preffilter = get_user_preferences(tool_helper::PREF_REQUEST_FILTERS, null, $userid);
222         if ($preffilter !== null) {
223             $filters = json_decode($preffilter);
224             $descriptions = [];
225             foreach ($filters as $filter) {
226                 list($category, $value) = explode(':', $filter);
227                 $option = new stdClass();
228                 switch($category) {
229                     case tool_helper::FILTER_TYPE:
230                         $option->category = get_string('requesttype', 'tool_dataprivacy');
231                         $option->name = tool_helper::get_shortened_request_type_string($value);
232                         break;
233                     case tool_helper::FILTER_STATUS:
234                         $option->category = get_string('requeststatus', 'tool_dataprivacy');
235                         $option->name = tool_helper::get_request_status_string($value);
236                         break;
237                 }
238                 $descriptions[] = get_string('filteroption', 'tool_dataprivacy', $option);
239             }
240             // Export the filter preference as comma-separated values and text descriptions.
241             $values = implode(', ', $filters);
242             $descriptionstext = implode(', ', $descriptions);
243             writer::export_user_preference('tool_dataprivacy', tool_helper::PREF_REQUEST_FILTERS, $values, $descriptionstext);
244         }
246         $prefperpage = get_user_preferences(tool_helper::PREF_REQUEST_PERPAGE, null, $userid);
247         if ($prefperpage !== null) {
248             writer::export_user_preference('tool_dataprivacy', tool_helper::PREF_REQUEST_PERPAGE, $prefperpage,
249                 get_string('privacy:metadata:preference:tool_dataprivacy_request-perpage', 'tool_dataprivacy'));
250         }
251     }