MDL-68796 core_contentbank: Store view preferences
[moodle.git] / contentbank / classes / privacy / provider.php
CommitLineData
33b8ca26
AA
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 provider implementation for core_contentbank.
19 *
20 * @package core_contentbank
21 * @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25namespace core_contentbank\privacy;
26
27use core_privacy\local\metadata\collection;
28use core_privacy\local\request\approved_contextlist;
33b8ca26 29use core_privacy\local\request\contextlist;
aeacd6c8 30use core_privacy\local\request\transform;
31use core_privacy\local\request\writer;
33b8ca26 32use core_privacy\local\request\userlist;
aeacd6c8 33use core_privacy\local\request\approved_userlist;
34use context_system;
35use context_coursecat;
36use context_course;
33b8ca26
AA
37
38/**
39 * Privacy provider implementation for core_contentbank.
40 *
41 * @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
42 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
43 */
44class provider implements
45 \core_privacy\local\metadata\provider,
46 \core_privacy\local\request\core_userlist_provider,
c393d818
BB
47 \core_privacy\local\request\plugin\provider,
48 \core_privacy\local\request\user_preference_provider {
33b8ca26
AA
49
50 /**
aeacd6c8 51 * Returns meta data about this system.
33b8ca26
AA
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 */
ce8cc797 56 public static function get_metadata(collection $collection): collection {
33b8ca26 57 $collection->add_database_table('contentbank_content', [
aeacd6c8 58 'name' => 'privacy:metadata:content:name',
59 'contenttype' => 'privacy:metadata:content:contenttype',
33b8ca26
AA
60 'usercreated' => 'privacy:metadata:content:usercreated',
61 'usermodified' => 'privacy:metadata:content:usermodified',
aeacd6c8 62 'timecreated' => 'privacy:metadata:content:timecreated',
63 'timemodified' => 'privacy:metadata:content:timemodified',
64 ], 'privacy:metadata:contentbankcontent');
33b8ca26
AA
65
66 return $collection;
67 }
68
c393d818
BB
69 /**
70 * Export all user preferences for the contentbank
71 *
72 * @param int $userid The userid of the user whose data is to be exported.
73 */
74 public static function export_user_preferences(int $userid) {
75 $preference = get_user_preferences('core_contentbank_view_list', null, $userid);
76 if (isset($preference)) {
77 writer::export_user_preference(
78 'core_contentbank',
79 'core_contentbank_view_list',
80 $preference,
81 get_string('privacy:request:preference:set', 'core_contentbank', (object) [
82 'name' => 'core_contentbank_view_list',
83 'value' => $preference,
84 ])
85 );
86 }
87 }
88
33b8ca26 89 /**
aeacd6c8 90 * Get the list of contexts that contain user information for the specified user.
33b8ca26 91 *
aeacd6c8 92 * @param int $userid The user to search.
93 * @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
33b8ca26 94 */
ce8cc797 95 public static function get_contexts_for_userid(int $userid): contextlist {
aeacd6c8 96 $sql = "SELECT DISTINCT ctx.id
97 FROM {context} ctx
98 JOIN {contentbank_content} cb
99 ON cb.contextid = ctx.id
100 WHERE cb.usercreated = :userid
101 AND (ctx.contextlevel = :contextlevel1
102 OR ctx.contextlevel = :contextlevel2
103 OR ctx.contextlevel = :contextlevel3)";
33b8ca26 104
aeacd6c8 105 $params = [
106 'userid' => $userid,
107 'contextlevel1' => CONTEXT_SYSTEM,
108 'contextlevel2' => CONTEXT_COURSECAT,
ce8cc797 109 'contextlevel3' => CONTEXT_COURSE,
aeacd6c8 110 ];
111
112 $contextlist = new contextlist();
113 $contextlist->add_from_sql($sql, $params);
114
115 return $contextlist;
33b8ca26
AA
116 }
117
118 /**
aeacd6c8 119 * Get the list of users within a specific context.
33b8ca26 120 *
aeacd6c8 121 * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
33b8ca26 122 */
aeacd6c8 123 public static function get_users_in_context(userlist $userlist) {
124 $context = $userlist->get_context();
125
126 $allowedcontextlevels = [
127 CONTEXT_SYSTEM,
128 CONTEXT_COURSECAT,
ce8cc797 129 CONTEXT_COURSE,
aeacd6c8 130 ];
131
132 if (!in_array($context->contextlevel, $allowedcontextlevels)) {
133 return;
134 }
33b8ca26 135
aeacd6c8 136 $sql = "SELECT cb.usercreated as userid
137 FROM {contentbank_content} cb
138 WHERE cb.contextid = :contextid";
139
140 $params = [
141 'contextid' => $context->id
142 ];
143
144 $userlist->add_from_sql('userid', $sql, $params);
33b8ca26
AA
145 }
146
147 /**
33b8ca26
AA
148 * Export all user data for the specified user, in the specified contexts.
149 *
aeacd6c8 150 * @param approved_contextlist $contextlist The approved contexts to export information for.
33b8ca26
AA
151 */
152 public static function export_user_data(approved_contextlist $contextlist) {
aeacd6c8 153 global $DB;
154
155 // Remove contexts different from SYSTEM, COURSECAT or COURSE.
156 $contextids = array_reduce($contextlist->get_contexts(), function($carry, $context) {
157 if ($context->contextlevel == CONTEXT_SYSTEM || $context->contextlevel == CONTEXT_COURSECAT
158 || $context->contextlevel == CONTEXT_COURSE) {
159 $carry[] = $context->id;
160 }
161 return $carry;
162 }, []);
163
164 if (empty($contextids)) {
165 return;
166 }
167
168 $userid = $contextlist->get_user()->id;
169
170 list($contextsql, $contextparams) = $DB->get_in_or_equal($contextids, SQL_PARAMS_NAMED);
171 // Retrieve the contentbank_content records created for the user.
172 $sql = "SELECT cb.id,
173 cb.name,
174 cb.contenttype,
175 cb.usercreated,
176 cb.usermodified,
177 cb.timecreated,
178 cb.timemodified,
179 cb.contextid
180 FROM {contentbank_content} cb
181 WHERE cb.usercreated = :userid
182 AND cb.contextid {$contextsql}
183 ORDER BY cb.contextid";
184
185 $params = ['userid' => $userid] + $contextparams;
186
187 $contents = $DB->get_recordset_sql($sql, $params);
188 $data = [];
189 $lastcontextid = null;
190 $subcontext = [
ce8cc797
AN
191 get_string('name', 'core_contentbank'),
192 ];
aeacd6c8 193 foreach ($contents as $content) {
194 // The core_contentbank data export is organised in:
195 // {Sytem|Course Category|Course Context Level}/Content/data.json.
196 if ($lastcontextid && $lastcontextid != $content->contextid) {
197 $context = \context::instance_by_id($lastcontextid);
198 writer::with_context($context)->export_data($subcontext, (object)$data);
199 $data = [];
200 }
201 $data[] = (object) [
202 'name' => $content->name,
203 'contenttype' => $content->contenttype,
204 'usercreated' => transform::user($content->usercreated),
205 'usermodified' => transform::user($content->usermodified),
206 'timecreated' => transform::datetime($content->timecreated),
207 'timemodified' => transform::datetime($content->timemodified)
208 ];
209 $lastcontextid = $content->contextid;
210
211 // The core_contentbank files export is organised in:
212 // {Sytem|Course Category|Course Context Level}/Content/_files/public/_itemid/filename.
213 $context = \context::instance_by_id($lastcontextid);
214 writer::with_context($context)->export_area_files($subcontext, 'contentbank', 'public', $content->id);
215 }
216 if (!empty($data)) {
217 $context = \context::instance_by_id($lastcontextid);
218 writer::with_context($context)->export_data($subcontext, (object)$data);
219 }
220 $contents->close();
33b8ca26
AA
221 }
222
223 /**
33b8ca26
AA
224 * Delete all data for all users in the specified context.
225 *
aeacd6c8 226 * @param context $context The specific context to delete data for.
33b8ca26
AA
227 */
228 public static function delete_data_for_all_users_in_context(\context $context) {
aeacd6c8 229 global $DB;
230
231 if (!$context instanceof context_system && !$context instanceof context_coursecat
ce8cc797 232 && !$context instanceof context_course) {
aeacd6c8 233 return;
234 }
235
236 static::delete_data($context, []);
237 }
238
239 /**
240 * Delete multiple users within a single context.
241 *
242 * @param approved_userlist $userlist The approved context and user information to delete information for.
243 */
244 public static function delete_data_for_users(approved_userlist $userlist) {
245 $context = $userlist->get_context();
246
247 if (!$context instanceof context_system && !$context instanceof context_coursecat
ce8cc797 248 && !$context instanceof context_course) {
aeacd6c8 249 return;
250 }
251
252 static::delete_data($context, $userlist->get_userids());
33b8ca26
AA
253 }
254
255 /**
33b8ca26
AA
256 * Delete all user data for the specified user, in the specified contexts.
257 *
aeacd6c8 258 * @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
33b8ca26
AA
259 */
260 public static function delete_data_for_user(approved_contextlist $contextlist) {
aeacd6c8 261 if (empty($contextlist->count())) {
262 return;
263 }
264
265 $userid = $contextlist->get_user()->id;
266 foreach ($contextlist->get_contexts() as $context) {
267 if (!$context instanceof context_system && !$context instanceof context_coursecat
268 && !$context instanceof context_course) {
269 continue;
270 }
271 static::delete_data($context, [$userid]);
272 }
273 }
274
275 /**
276 * Delete data related to a context and users (if defined).
277 *
278 * @param context $context A context.
279 * @param array $userids The user IDs.
280 */
281 protected static function delete_data(\context $context, array $userids) {
282 global $DB;
283
284 $params = ['contextid' => $context->id];
285 $select = 'contextid = :contextid';
286
287 // Delete the Content Bank files.
288 if (!empty($userids)) {
289 list($insql, $inparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
290 $params += $inparams;
291 $select .= ' AND usercreated '.$insql;
292 }
293 $fs = get_file_storage();
294 $contents = $DB->get_records_select('contentbank_content',
295 $select, $params);
296 foreach ($contents as $content) {
297 $fs->delete_area_files($content->contextid, 'contentbank', 'public', $content->id);
298 }
299
300 // Delete all the contents.
301 $DB->delete_records_select('contentbank_content', $select, $params);
33b8ca26
AA
302 }
303}