Differences Between: [Versions 401 and 402]
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/>. 16 17 namespace tiny_autosave\privacy; 18 19 use core_privacy\local\request\approved_contextlist; 20 use core_privacy\local\request\writer; 21 use core_privacy\local\metadata\collection; 22 use core_privacy\local\request\userlist; 23 use core_privacy\local\request\approved_userlist; 24 use stdClass; 25 26 /** 27 * Privacy Subsystem implementation for tiny_autosave. 28 * 29 * @package tiny_autosave 30 * @copyright 2022 Andrew Nicols <andrew@nicols.co.uk> 31 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 32 */ 33 class provider implements 34 // The tiny editor stores user provided data. 35 \core_privacy\local\metadata\provider, 36 37 // The tiny editor provides data directly to core. 38 \core_privacy\local\request\plugin\provider, 39 40 // The tiny editor is capable of determining which users have data within it. 41 \core_privacy\local\request\core_userlist_provider { 42 43 /** 44 * Returns information about how tiny_autosave stores its data. 45 * 46 * @param collection $collection The initialised collection to add items to. 47 * @return collection A listing of user data stored through this system. 48 */ 49 public static function get_metadata(collection $collection): collection { 50 // There isn't much point giving details about the pageid, etc. 51 $collection->add_database_table('tiny_autosave', [ 52 'userid' => 'privacy:metadata:database:tiny_autosave:userid', 53 'drafttext' => 'privacy:metadata:database:tiny_autosave:drafttext', 54 'timemodified' => 'privacy:metadata:database:tiny_autosave:timemodified', 55 ], 'privacy:metadata:database:tiny_autosave'); 56 57 return $collection; 58 } 59 60 /** 61 * Get the list of contexts that contain user information for the specified user. 62 * 63 * @param int $userid The user to search. 64 * @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin. 65 */ 66 public static function get_contexts_for_userid(int $userid): \core_privacy\local\request\contextlist { 67 $contextlist = new \core_privacy\local\request\contextlist(); 68 69 // Data may be saved in the user context. 70 $sql = "SELECT 71 c.id 72 FROM {tiny_autosave} eas 73 JOIN {context} c ON c.id = eas.contextid 74 WHERE contextlevel = :contextuser AND c.instanceid = :userid"; 75 $contextlist->add_from_sql($sql, ['contextuser' => CONTEXT_USER, 'userid' => $userid]); 76 77 // Data may be saved against the userid. 78 $sql = "SELECT contextid FROM {tiny_autosave} WHERE userid = :userid"; 79 $contextlist->add_from_sql($sql, ['userid' => $userid]); 80 81 return $contextlist; 82 } 83 84 /** 85 * Get the list of users within a specific context. 86 * 87 * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination. 88 */ 89 public static function get_users_in_context(userlist $userlist) { 90 $context = $userlist->get_context(); 91 92 $params = [ 93 'contextid' => $context->id 94 ]; 95 96 $sql = "SELECT userid 97 FROM {tiny_autosave} 98 WHERE contextid = :contextid"; 99 100 $userlist->add_from_sql('userid', $sql, $params); 101 } 102 103 /** 104 * Export all user data for the specified user, in the specified contexts. 105 * 106 * @param approved_contextlist $contextlist The approved contexts to export information for. 107 */ 108 public static function export_user_data(approved_contextlist $contextlist) { 109 global $DB; 110 111 $user = $contextlist->get_user(); 112 113 // Firstly export all autosave records from all contexts in the list owned by the given user. 114 list($contextsql, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED); 115 $contextparams['userid'] = $user->id; 116 117 $sql = "SELECT * 118 FROM {tiny_autosave} 119 WHERE userid = :userid AND contextid {$contextsql}"; 120 121 $autosaves = $DB->get_recordset_sql($sql, $contextparams); 122 self::export_autosaves($user, $autosaves); 123 124 // Additionally export all eventual records in the given user's context regardless the actual owner. 125 // We still consider them to be the user's personal data even when edited by someone else. 126 [$contextsql, $contextparams] = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED); 127 $contextparams['userid'] = $user->id; 128 $contextparams['contextuser'] = CONTEXT_USER; 129 130 $sql = "SELECT eas.* 131 FROM {tiny_autosave} eas 132 JOIN {context} c ON c.id = eas.contextid 133 WHERE c.id {$contextsql} AND c.contextlevel = :contextuser AND c.instanceid = :userid"; 134 135 $autosaves = $DB->get_recordset_sql($sql, $contextparams); 136 self::export_autosaves($user, $autosaves); 137 } 138 139 /** 140 * Export all autosave records in the recordset, and close the recordset when finished. 141 * 142 * @param stdClass $user The user whose data is to be exported 143 * @param \moodle_recordset $autosaves The recordset containing the data to export 144 */ 145 protected static function export_autosaves(stdClass $user, \moodle_recordset $autosaves) { 146 foreach ($autosaves as $autosave) { 147 $context = \context::instance_by_id($autosave->contextid); 148 $subcontext = [ 149 get_string('pluginname', 'tiny_autosave'), 150 $autosave->id, 151 ]; 152 153 $html = writer::with_context($context) 154 ->rewrite_pluginfile_urls($subcontext, 'user', 'draft', $autosave->draftid, $autosave->drafttext); 155 156 $data = (object) [ 157 'drafttext' => format_text($html, FORMAT_HTML, static::get_filter_options()), 158 'timemodified' => \core_privacy\local\request\transform::datetime($autosave->timemodified), 159 ]; 160 161 if ($autosave->userid != $user->id) { 162 $data->author = \core_privacy\local\request\transform::user($autosave->userid); 163 } 164 165 writer::with_context($context) 166 ->export_data($subcontext, $data) 167 ->export_area_files($subcontext, 'user', 'draft', $autosave->draftid); 168 } 169 $autosaves->close(); 170 } 171 172 /** 173 * Delete all data for all users in the specified context. 174 * 175 * @param \context $context The specific context to delete data for. 176 */ 177 public static function delete_data_for_all_users_in_context(\context $context) { 178 global $DB; 179 180 $DB->delete_records('tiny_autosave', [ 181 'contextid' => $context->id, 182 ]); 183 } 184 185 /** 186 * Delete multiple users within a single context. 187 * 188 * @param approved_userlist $userlist The approved context and user information to delete information for. 189 */ 190 public static function delete_data_for_users(approved_userlist $userlist) { 191 global $DB; 192 193 $context = $userlist->get_context(); 194 $userids = $userlist->get_userids(); 195 196 [$useridsql, $useridsqlparams] = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED); 197 $params = ['contextid' => $context->id] + $useridsqlparams; 198 199 $DB->delete_records_select('tiny_autosave', "contextid = :contextid AND userid {$useridsql}", 200 $params); 201 } 202 203 /** 204 * Delete all user data for the specified user, in the specified contexts. 205 * 206 * @param approved_contextlist $contextlist The approved contexts and user information to delete information for. 207 */ 208 public static function delete_data_for_user(approved_contextlist $contextlist) { 209 global $DB; 210 211 $user = $contextlist->get_user(); 212 213 [$contextsql, $contextparams] = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED); 214 $contextparams['userid'] = $user->id; 215 216 $sql = "SELECT * FROM {tiny_autosave} WHERE contextid {$contextsql}"; 217 $autosaves = $DB->delete_records_select( 218 'tiny_autosave', 219 "userid = :userid AND contextid {$contextsql}", 220 $contextparams 221 ); 222 } 223 224 /** 225 * Get the filter options. 226 * 227 * This is shared to allow unit testing too. 228 * 229 * @return stdClass 230 */ 231 public static function get_filter_options() { 232 return (object) [ 233 'overflowdiv' => true, 234 'noclean' => true, 235 ]; 236 } 237 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body