2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
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
26 namespace core_block\privacy;
27 defined('MOODLE_INTERNAL') || die();
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;
37 * Data provider class.
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
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 {
52 * @param collection $collection The initialised collection to add items to.
53 * @return collection A listing of user data stored through this system.
55 public static function get_metadata(collection $collection) : collection {
56 $collection->add_user_preference('blockIDhidden', 'privacy:metadata:userpref:hiddenblock');
57 $collection->add_user_preference('docked_block_instance_ID', 'privacy:metadata:userpref:dockedinstance');
62 * Get the list of contexts that contain user information for the specified user.
64 * @param int $userid The user to search.
65 * @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
67 public static function get_contexts_for_userid(int $userid) : \core_privacy\local\request\contextlist {
69 $contextlist = new \core_privacy\local\request\contextlist();
71 // Fetch the block instance IDs.
72 $likehidden = $DB->sql_like('name', ':hidden', false, false);
73 $likedocked = $DB->sql_like('name', ':docked', false, false);
74 $sql = "userid = :userid AND ($likehidden OR $likedocked)";
77 'hidden' => 'block%hidden',
78 'docked' => 'docked_block_instance_%',
80 $prefs = $DB->get_fieldset_select('user_preferences', 'name', $sql, $params);
82 $instanceids = array_unique(array_map(function($prefname) {
83 if (preg_match('/^block(\d+)hidden$/', $prefname, $matches)) {
85 } else if (preg_match('/^docked_block_instance_(\d+)$/', $prefname, $matches)) {
91 // Find the context of the instances.
92 if (!empty($instanceids)) {
93 list($insql, $inparams) = $DB->get_in_or_equal($instanceids, SQL_PARAMS_NAMED);
97 WHERE ctx.instanceid $insql
98 AND ctx.contextlevel = :blocklevel";
99 $params = array_merge($inparams, ['blocklevel' => CONTEXT_BLOCK]);
100 $contextlist->add_from_sql($sql, $params);
107 * Export all user data for the specified user, in the specified contexts.
109 * @param approved_contextlist $contextlist The approved contexts to export information for.
111 public static function export_user_data(approved_contextlist $contextlist) {
113 $userid = $contextlist->get_user()->id;
115 // Extract the block instance IDs.
116 $instanceids = array_reduce($contextlist->get_contexts(), function($carry, $context) {
117 if ($context->contextlevel == CONTEXT_BLOCK) {
118 $carry[] = $context->instanceid;
122 if (empty($instanceids)) {
126 // Query the blocks and their preferences.
127 list($insql, $inparams) = $DB->get_in_or_equal($instanceids, SQL_PARAMS_NAMED);
128 $hiddenkey = $DB->sql_concat("'block'", 'bi.id', "'hidden'");
129 $dockedkey = $DB->sql_concat("'docked_block_instance_'", 'bi.id');
131 SELECT bi.id, h.value AS prefhidden, d.value AS prefdocked
132 FROM {block_instances} bi
133 LEFT JOIN {user_preferences} h
134 ON h.userid = :userid1
135 AND h.name = $hiddenkey
136 LEFT JOIN {user_preferences} d
137 ON d.userid = :userid2
138 AND d.name = $dockedkey
140 AND (h.id IS NOT NULL
141 OR d.id IS NOT NULL)";
142 $params = array_merge($inparams, [
143 'userid1' => $userid,
144 'userid2' => $userid,
147 // Export all the things.
148 $dockedstr = get_string('privacy:request:blockisdocked', 'core_block');
149 $hiddenstr = get_string('privacy:request:blockishidden', 'core_block');
150 $recordset = $DB->get_recordset_sql($sql, $params);
151 foreach ($recordset as $record) {
152 $context = context_block::instance($record->id);
153 if ($record->prefdocked !== null) {
154 writer::with_context($context)->export_user_preference(
157 transform::yesno($record->prefdocked),
161 if ($record->prefhidden !== null) {
162 writer::with_context($context)->export_user_preference(
165 transform::yesno($record->prefhidden),
174 * Export all user preferences for the plugin.
176 * @param int $userid The userid of the user whose data is to be exported.
178 public static function export_user_preferences(int $userid) {
179 // Our preferences aren't site-wide so they are exported in export_user_data.
183 * Delete all data for all users in the specified context.
185 * @param context $context The specific context to delete data for.
187 public static function delete_data_for_all_users_in_context(context $context) {
189 if ($context->contextlevel != CONTEXT_BLOCK) {
193 // Delete the user preferences.
194 $instanceid = $context->instanceid;
195 $DB->delete_records_list('user_preferences', 'name', [
196 "block{$instanceid}hidden",
197 "docked_block_instance_{$instanceid}"
202 * Delete all user data for the specified user, in the specified contexts.
204 * @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
206 public static function delete_data_for_user(approved_contextlist $contextlist) {
208 $userid = $contextlist->get_user()->id;
209 $prefnames = array_reduce($contextlist->get_contexts(), function($carry, $context) {
210 if ($context->contextlevel == CONTEXT_BLOCK) {
211 $carry[] = "block{$context->instanceid}hidden";
212 $carry[] = "docked_block_instance_{$context->instanceid}";
217 if (empty($prefnames)) {
221 list($insql, $inparams) = $DB->get_in_or_equal($prefnames, SQL_PARAMS_NAMED);
222 $sql = "userid = :userid AND name $insql";
223 $params = array_merge($inparams, ['userid' => $userid]);
224 $DB->delete_records_select('user_preferences', $sql, $params);