Merge branch 'MDL-62564-integration-master-1' of git://github.com/mihailges/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             // Creation method.
171             $data->creationmethod = tool_helper::get_request_creation_method_string($record->creationmethod);
172             // Comments.
173             $data->comments = $record->comments;
174             // The DPO's comment about this request.
175             $data->dpocomment = $record->dpocomment;
176             // The date and time this request was lodged.
177             $data->timecreated = transform::datetime($record->timecreated);
178             $contextdatatowrite[] = $data;
179         }
181         // User context / Privacy and policies / Data requests.
182         $subcontext = [
183             get_string('privacyandpolicies', 'admin'),
184             get_string('datarequests', 'tool_dataprivacy'),
185         ];
186         writer::with_context($context)->export_data($subcontext, (object)$contextdatatowrite);
188         // Write generic module intro files.
189         helper::export_context_files($context, $user);
190     }
192     /**
193      * Delete all data for all users in the specified context.
194      *
195      * @param context $context The specific context to delete data for.
196      */
197     public static function delete_data_for_all_users_in_context(context $context) {
198     }
200     /**
201      * Delete all user data for the specified user, in the specified contexts.
202      *
203      * @param   approved_contextlist $contextlist The approved contexts and user information to delete information for.
204      */
205     public static function delete_data_for_user(approved_contextlist $contextlist) {
206     }
208     /**
209      * Delete multiple users within a single context.
210      *
211      * @param   approved_userlist    $userlist The approved context and user information to delete information for.
212      *
213      */
214     public static function delete_data_for_users(approved_userlist $userlist) {
215     }
217     /**
218      * Export all user preferences for the plugin.
219      *
220      * @param   int $userid The userid of the user whose data is to be exported.
221      */
222     public static function export_user_preferences(int $userid) {
223         $preffilter = get_user_preferences(tool_helper::PREF_REQUEST_FILTERS, null, $userid);
224         if ($preffilter !== null) {
225             $filters = json_decode($preffilter);
226             $descriptions = [];
227             foreach ($filters as $filter) {
228                 list($category, $value) = explode(':', $filter);
229                 $option = new stdClass();
230                 switch($category) {
231                     case tool_helper::FILTER_TYPE:
232                         $option->category = get_string('requesttype', 'tool_dataprivacy');
233                         $option->name = tool_helper::get_shortened_request_type_string($value);
234                         break;
235                     case tool_helper::FILTER_STATUS:
236                         $option->category = get_string('requeststatus', 'tool_dataprivacy');
237                         $option->name = tool_helper::get_request_status_string($value);
238                         break;
239                     case tool_helper::FILTER_CREATION:
240                         $option->category = get_string('requestcreation', 'tool_dataprivacy');
241                         $option->name = tool_helper::get_request_creation_method_string($value);
242                         break;
243                 }
244                 $descriptions[] = get_string('filteroption', 'tool_dataprivacy', $option);
245             }
246             // Export the filter preference as comma-separated values and text descriptions.
247             $values = implode(', ', $filters);
248             $descriptionstext = implode(', ', $descriptions);
249             writer::export_user_preference('tool_dataprivacy', tool_helper::PREF_REQUEST_FILTERS, $values, $descriptionstext);
250         }
252         $prefperpage = get_user_preferences(tool_helper::PREF_REQUEST_PERPAGE, null, $userid);
253         if ($prefperpage !== null) {
254             writer::export_user_preference('tool_dataprivacy', tool_helper::PREF_REQUEST_PERPAGE, $prefperpage,
255                 get_string('privacy:metadata:preference:tool_dataprivacy_request-perpage', 'tool_dataprivacy'));
256         }
257     }