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 * Data provider. 19 * 20 * @package core_block 21 * @copyright 2018 Frédéric Massart 22 * @author Frédéric Massart <fred@branchup.tech> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 namespace core_block\privacy; 27 defined('MOODLE_INTERNAL') || die(); 28 29 use context; 30 use context_block; 31 use core_privacy\local\metadata\collection; 32 use core_privacy\local\request\approved_contextlist; 33 use core_privacy\local\request\transform; 34 use core_privacy\local\request\writer; 35 36 /** 37 * Data provider class. 38 * 39 * @package core_block 40 * @copyright 2018 Frédéric Massart 41 * @author Frédéric Massart <fred@branchup.tech> 42 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 43 */ 44 class provider implements 45 \core_privacy\local\metadata\provider, 46 \core_privacy\local\request\subsystem\provider, 47 \core_privacy\local\request\user_preference_provider, 48 \core_privacy\local\request\core_userlist_provider { 49 50 /** 51 * Returns metadata. 52 * 53 * @param collection $collection The initialised collection to add items to. 54 * @return collection A listing of user data stored through this system. 55 */ 56 public static function get_metadata(collection $collection) : collection { 57 $collection->add_user_preference('blockIDhidden', 'privacy:metadata:userpref:hiddenblock'); 58 $collection->add_user_preference('docked_block_instance_ID', 'privacy:metadata:userpref:dockedinstance'); 59 return $collection; 60 } 61 62 /** 63 * Get the list of contexts that contain user information for the specified user. 64 * 65 * @param int $userid The user to search. 66 * @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin. 67 */ 68 public static function get_contexts_for_userid(int $userid) : \core_privacy\local\request\contextlist { 69 global $DB; 70 $contextlist = new \core_privacy\local\request\contextlist(); 71 72 // Fetch the block instance IDs. 73 $likehidden = $DB->sql_like('name', ':hidden', false, false); 74 $likedocked = $DB->sql_like('name', ':docked', false, false); 75 $sql = "userid = :userid AND ($likehidden OR $likedocked)"; 76 $params = [ 77 'userid' => $userid, 78 'hidden' => 'block%hidden', 79 'docked' => 'docked_block_instance_%', 80 ]; 81 $prefs = $DB->get_fieldset_select('user_preferences', 'name', $sql, $params); 82 83 $instanceids = array_unique(array_map(function($prefname) { 84 if (preg_match('/^block(\d+)hidden$/', $prefname, $matches)) { 85 return $matches[1]; 86 } else if (preg_match('/^docked_block_instance_(\d+)$/', $prefname, $matches)) { 87 return $matches[1]; 88 } 89 return 0; 90 }, $prefs)); 91 92 // Find the context of the instances. 93 if (!empty($instanceids)) { 94 list($insql, $inparams) = $DB->get_in_or_equal($instanceids, SQL_PARAMS_NAMED); 95 $sql = " 96 SELECT ctx.id 97 FROM {context} ctx 98 WHERE ctx.instanceid $insql 99 AND ctx.contextlevel = :blocklevel"; 100 $params = array_merge($inparams, ['blocklevel' => CONTEXT_BLOCK]); 101 $contextlist->add_from_sql($sql, $params); 102 } 103 104 return $contextlist; 105 } 106 107 /** 108 * Get the list of users who have data within a context. 109 * 110 * @param \core_privacy\local\request\userlist $userlist The userlist containing the list of users who have data in this context/plugin combination. 111 */ 112 public static function get_users_in_context(\core_privacy\local\request\userlist $userlist) { 113 global $DB; 114 115 $context = $userlist->get_context(); 116 if ($context->contextlevel != CONTEXT_BLOCK) { 117 return; 118 } 119 120 $params = ['docked' => 'docked_block_instance_' . $context->instanceid, 121 'hidden' => 'block' . $context->instanceid . 'hidden']; 122 123 $sql = "SELECT userid 124 FROM {user_preferences} 125 WHERE name = :hidden OR name = :docked"; 126 $userlist->add_from_sql('userid', $sql, $params); 127 } 128 129 /** 130 * Export all user data for the specified user, in the specified contexts. 131 * 132 * @param approved_contextlist $contextlist The approved contexts to export information for. 133 */ 134 public static function export_user_data(approved_contextlist $contextlist) { 135 global $DB; 136 $userid = $contextlist->get_user()->id; 137 138 // Extract the block instance IDs. 139 $instanceids = array_reduce($contextlist->get_contexts(), function($carry, $context) { 140 if ($context->contextlevel == CONTEXT_BLOCK) { 141 $carry[] = $context->instanceid; 142 } 143 return $carry; 144 }, []); 145 if (empty($instanceids)) { 146 return; 147 } 148 149 // Query the blocks and their preferences. 150 list($insql, $inparams) = $DB->get_in_or_equal($instanceids, SQL_PARAMS_NAMED); 151 $hiddenkey = $DB->sql_concat("'block'", 'bi.id', "'hidden'"); 152 $dockedkey = $DB->sql_concat("'docked_block_instance_'", 'bi.id'); 153 $sql = " 154 SELECT bi.id, h.value AS prefhidden, d.value AS prefdocked 155 FROM {block_instances} bi 156 LEFT JOIN {user_preferences} h 157 ON h.userid = :userid1 158 AND h.name = $hiddenkey 159 LEFT JOIN {user_preferences} d 160 ON d.userid = :userid2 161 AND d.name = $dockedkey 162 WHERE bi.id $insql 163 AND (h.id IS NOT NULL 164 OR d.id IS NOT NULL)"; 165 $params = array_merge($inparams, [ 166 'userid1' => $userid, 167 'userid2' => $userid, 168 ]); 169 170 // Export all the things. 171 $dockedstr = get_string('privacy:request:blockisdocked', 'core_block'); 172 $hiddenstr = get_string('privacy:request:blockishidden', 'core_block'); 173 $recordset = $DB->get_recordset_sql($sql, $params); 174 foreach ($recordset as $record) { 175 $context = context_block::instance($record->id); 176 if ($record->prefdocked !== null) { 177 writer::with_context($context)->export_user_preference( 178 'core_block', 179 'block_is_docked', 180 transform::yesno($record->prefdocked), 181 $dockedstr 182 ); 183 } 184 if ($record->prefhidden !== null) { 185 writer::with_context($context)->export_user_preference( 186 'core_block', 187 'block_is_hidden', 188 transform::yesno($record->prefhidden), 189 $hiddenstr 190 ); 191 } 192 } 193 $recordset->close(); 194 } 195 196 /** 197 * Export all user preferences for the plugin. 198 * 199 * @param int $userid The userid of the user whose data is to be exported. 200 */ 201 public static function export_user_preferences(int $userid) { 202 // Our preferences aren't site-wide so they are exported in export_user_data. 203 } 204 205 /** 206 * Delete all data for all users in the specified context. 207 * 208 * @param context $context The specific context to delete data for. 209 */ 210 public static function delete_data_for_all_users_in_context(context $context) { 211 global $DB; 212 if ($context->contextlevel != CONTEXT_BLOCK) { 213 return; 214 } 215 216 // Delete the user preferences. 217 $instanceid = $context->instanceid; 218 $DB->delete_records_list('user_preferences', 'name', [ 219 "block{$instanceid}hidden", 220 "docked_block_instance_{$instanceid}" 221 ]); 222 } 223 224 /** 225 * Delete all user data for the specified user, in the specified contexts. 226 * 227 * @param approved_contextlist $contextlist The approved contexts and user information to delete information for. 228 */ 229 public static function delete_data_for_user(approved_contextlist $contextlist) { 230 global $DB; 231 $userid = $contextlist->get_user()->id; 232 $prefnames = array_reduce($contextlist->get_contexts(), function($carry, $context) { 233 if ($context->contextlevel == CONTEXT_BLOCK) { 234 $carry[] = "block{$context->instanceid}hidden"; 235 $carry[] = "docked_block_instance_{$context->instanceid}"; 236 } 237 return $carry; 238 }, []); 239 240 if (empty($prefnames)) { 241 return; 242 } 243 244 list($insql, $inparams) = $DB->get_in_or_equal($prefnames, SQL_PARAMS_NAMED); 245 $sql = "userid = :userid AND name $insql"; 246 $params = array_merge($inparams, ['userid' => $userid]); 247 $DB->delete_records_select('user_preferences', $sql, $params); 248 } 249 250 251 /** 252 * Delete multiple users within a single context. 253 * 254 * @param \core_privacy\local\request\approved_userlist $userlist The approved context and user information to delete 255 * information for. 256 */ 257 public static function delete_data_for_users(\core_privacy\local\request\approved_userlist $userlist) { 258 global $DB; 259 $context = $userlist->get_context(); 260 if ($context->contextlevel != CONTEXT_BLOCK) { 261 return; 262 } 263 264 list($insql, $params) = $DB->get_in_or_equal($userlist->get_userids(), SQL_PARAMS_NAMED); 265 $params['hidden'] = 'block' . $context->instanceid . 'hidden'; 266 $params['docked'] = 'docked_block_instance_' . $context->instanceid; 267 268 $DB->delete_records_select('user_preferences', "(name = :hidden OR name = :docked) AND userid $insql", $params); 269 } 270 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body