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