MDL-63666 logging: Rename delete_data_for_all_users() function
[moodle.git] / admin / tool / log / store / database / tests / privacy_test.php
CommitLineData
0f3bcbb9
FM
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 tests.
19 *
20 * @package logstore_database
21 * @category test
22 * @copyright 2018 Frédéric Massart
23 * @author Frédéric Massart <fred@branchup.tech>
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
26
27defined('MOODLE_INTERNAL') || die();
28global $CFG;
29
30use core_privacy\tests\provider_testcase;
31use core_privacy\local\request\contextlist;
32use core_privacy\local\request\approved_contextlist;
33use core_privacy\local\request\transform;
34use core_privacy\local\request\writer;
35use logstore_database\privacy\provider;
36
37require_once(__DIR__ . '/fixtures/event.php');
38
39/**
40 * Data provider testcase class.
41 *
42 * This testcase is almost identical to the logstore_standard testcase, aside from the
43 * initialisation of the relevant logstore obviously.
44 *
45 * @package logstore_database
46 * @category test
47 * @copyright 2018 Frédéric Massart
48 * @author Frédéric Massart <fred@branchup.tech>
49 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
50 */
51class logstore_database_privacy_testcase extends provider_testcase {
52
53 public function setUp() {
54 global $CFG;
55 $this->resetAfterTest();
56 $this->preventResetByRollback(); // Logging waits till the transaction gets committed.
57
58 // Fake the settings, we will abuse the standard plugin table here...
59 set_config('dbdriver', $CFG->dblibrary . '/' . $CFG->dbtype, 'logstore_database');
60 set_config('dbhost', $CFG->dbhost, 'logstore_database');
61 set_config('dbuser', $CFG->dbuser, 'logstore_database');
62 set_config('dbpass', $CFG->dbpass, 'logstore_database');
63 set_config('dbname', $CFG->dbname, 'logstore_database');
64 set_config('dbtable', $CFG->prefix . 'logstore_standard_log', 'logstore_database');
65 if (!empty($CFG->dboptions['dbpersist'])) {
66 set_config('dbpersist', 1, 'logstore_database');
67 } else {
68 set_config('dbpersist', 0, 'logstore_database');
69 }
70 if (!empty($CFG->dboptions['dbsocket'])) {
71 set_config('dbsocket', $CFG->dboptions['dbsocket'], 'logstore_database');
72 } else {
73 set_config('dbsocket', '', 'logstore_database');
74 }
75 if (!empty($CFG->dboptions['dbport'])) {
76 set_config('dbport', $CFG->dboptions['dbport'], 'logstore_database');
77 } else {
78 set_config('dbport', '', 'logstore_database');
79 }
80 if (!empty($CFG->dboptions['dbschema'])) {
81 set_config('dbschema', $CFG->dboptions['dbschema'], 'logstore_database');
82 } else {
83 set_config('dbschema', '', 'logstore_database');
84 }
85 if (!empty($CFG->dboptions['dbcollation'])) {
86 set_config('dbcollation', $CFG->dboptions['dbcollation'], 'logstore_database');
87 } else {
88 set_config('dbcollation', '', 'logstore_database');
89 }
90 if (!empty($CFG->dboptions['dbhandlesoptions'])) {
91 set_config('dbhandlesoptions', $CFG->dboptions['dbhandlesoptions'], 'logstore_database');
92 } else {
93 set_config('dbhandlesoptions', false, 'logstore_database');
94 }
95 }
96
97 public function test_get_contexts_for_userid() {
98 $admin = \core_user::get_user(2);
99 $u1 = $this->getDataGenerator()->create_user();
100 $u2 = $this->getDataGenerator()->create_user();
101 $u3 = $this->getDataGenerator()->create_user();
102
103 $c1 = $this->getDataGenerator()->create_course();
104 $cm1 = $this->getDataGenerator()->create_module('url', ['course' => $c1]);
105 $c2 = $this->getDataGenerator()->create_course();
106 $cm2 = $this->getDataGenerator()->create_module('url', ['course' => $c2]);
107
108 $sysctx = context_system::instance();
109 $c1ctx = context_course::instance($c1->id);
110 $c2ctx = context_course::instance($c2->id);
111 $cm1ctx = context_module::instance($cm1->cmid);
112 $cm2ctx = context_module::instance($cm2->cmid);
113
114 $this->enable_logging();
115 $manager = get_log_manager(true);
116
117 // User 1 is the author.
118 $this->setUser($u1);
119 $this->assert_contextlist_equals($this->get_contextlist_for_user($u1), []);
120 $e = \logstore_database\event\unittest_executed::create(['context' => $cm1ctx]);
121 $e->trigger();
122 $this->assert_contextlist_equals($this->get_contextlist_for_user($u1), [$cm1ctx]);
123
124 // User 2 is the related user.
125 $this->setUser(0);
126 $this->assert_contextlist_equals($this->get_contextlist_for_user($u2), []);
127 $e = \logstore_database\event\unittest_executed::create(['context' => $cm2ctx, 'relateduserid' => $u2->id]);
128 $e->trigger();
129 $this->assert_contextlist_equals($this->get_contextlist_for_user($u2), [$cm2ctx]);
130
131 // Admin user is the real user.
132 $this->assert_contextlist_equals($this->get_contextlist_for_user($admin), []);
133 $this->assert_contextlist_equals($this->get_contextlist_for_user($u3), []);
134 $this->setAdminUser();
135 \core\session\manager::loginas($u3->id, $sysctx);
136 $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
137 $e->trigger();
138 $this->assert_contextlist_equals($this->get_contextlist_for_user($admin), [$sysctx, $c1ctx]);
139 $this->assert_contextlist_equals($this->get_contextlist_for_user($u3), [$sysctx, $c1ctx]);
140
141 // By admin user masquerading u1 related to u3.
142 $this->assert_contextlist_equals($this->get_contextlist_for_user($u1), [$cm1ctx]);
143 $this->assert_contextlist_equals($this->get_contextlist_for_user($u3), [$sysctx, $c1ctx]);
144 $this->assert_contextlist_equals($this->get_contextlist_for_user($admin), [$sysctx, $c1ctx]);
145 $this->setAdminUser();
146 \core\session\manager::loginas($u1->id, context_system::instance());
147 $e = \logstore_database\event\unittest_executed::create(['context' => $c2ctx, 'relateduserid' => $u3->id]);
148 $e->trigger();
149 $this->assert_contextlist_equals($this->get_contextlist_for_user($u1), [$sysctx, $cm1ctx, $c2ctx]);
150 $this->assert_contextlist_equals($this->get_contextlist_for_user($u3), [$sysctx, $c1ctx, $c2ctx]);
151 $this->assert_contextlist_equals($this->get_contextlist_for_user($admin), [$sysctx, $c1ctx, $c2ctx]);
152 }
153
ac7d086d
AG
154 /**
155 * Check that user IDs are returned for a given context.
156 */
157 public function test_add_userids_for_context() {
158 $admin = \core_user::get_user(2);
159 $u1 = $this->getDataGenerator()->create_user();
160 $u2 = $this->getDataGenerator()->create_user();
161 $u3 = $this->getDataGenerator()->create_user();
162 $u4 = $this->getDataGenerator()->create_user();
163
164 $c1 = $this->getDataGenerator()->create_course();
165
166 $sysctx = context_system::instance();
167 $c1ctx = context_course::instance($c1->id);
168
169 $this->enable_logging();
170 $manager = get_log_manager(true);
171
172 $userlist = new \core_privacy\local\request\userlist($sysctx, 'logstore_database');
173 $userids = $userlist->get_userids();
174 $this->assertEmpty($userids);
175 provider::add_userids_for_context($userlist);
176 $userids = $userlist->get_userids();
177 $this->assertEmpty($userids);
178 // User one should be added (userid).
179 $this->setUser($u1);
180 $e = \logstore_database\event\unittest_executed::create(['context' => $sysctx]);
181 $e->trigger();
182 // User two (userids) and three (relateduserid) should be added.
183 $this->setUser($u2);
184 $e = \logstore_database\event\unittest_executed::create(['context' => $sysctx, 'relateduserid' => $u3->id]);
185 $e->trigger();
186 // The admin user should be added (realuserid).
187 $this->setAdminUser();
188 \core\session\manager::loginas($u2->id, context_system::instance());
189 $e = \logstore_database\event\unittest_executed::create(['context' => $sysctx]);
190 $e->trigger();
191 // Set off an event in a different context. User 4 should not be returned below.
192 $this->setUser($u4);
193 $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
194 $e->trigger();
195
196 provider::add_userids_for_context($userlist);
197 $userids = $userlist->get_userids();
198 $this->assertCount(4, $userids);
199 $expectedresult = [$admin->id, $u1->id, $u2->id, $u3->id];
200 $this->assertEmpty(array_diff($expectedresult, $userids));
201 }
202
0f3bcbb9
FM
203 public function test_delete_data_for_user() {
204 global $DB;
205 $u1 = $this->getDataGenerator()->create_user();
206 $u2 = $this->getDataGenerator()->create_user();
207 $c1 = $this->getDataGenerator()->create_course();
208 $c2 = $this->getDataGenerator()->create_course();
209 $sysctx = context_system::instance();
210 $c1ctx = context_course::instance($c1->id);
211 $c2ctx = context_course::instance($c2->id);
212
213 $this->enable_logging();
214 $manager = get_log_manager(true);
215
216 // User 1 is the author.
217 $this->setUser($u1);
218 $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
219 $e->trigger();
220 $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
221 $e->trigger();
222 $e = \logstore_database\event\unittest_executed::create(['context' => $c2ctx]);
223 $e->trigger();
224
225 // User 2 is the author.
226 $this->setUser($u2);
227 $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
228 $e->trigger();
229 $e = \logstore_database\event\unittest_executed::create(['context' => $c2ctx]);
230 $e->trigger();
231
232 // Confirm data present.
233 $this->assertTrue($DB->record_exists('logstore_standard_log', ['userid' => $u1->id, 'contextid' => $c1ctx->id]));
234 $this->assertEquals(3, $DB->count_records('logstore_standard_log', ['userid' => $u1->id]));
235 $this->assertEquals(2, $DB->count_records('logstore_standard_log', ['userid' => $u2->id]));
236
237 // Delete all the things!
238 provider::delete_data_for_user(new approved_contextlist($u1, 'logstore_database', [$c1ctx->id]));
239 $this->assertFalse($DB->record_exists('logstore_standard_log', ['userid' => $u1->id, 'contextid' => $c1ctx->id]));
240 $this->assertEquals(1, $DB->count_records('logstore_standard_log', ['userid' => $u1->id]));
241 $this->assertEquals(2, $DB->count_records('logstore_standard_log', ['userid' => $u2->id]));
242 }
243
244 public function test_delete_data_for_all_users_in_context() {
245 global $DB;
246 $u1 = $this->getDataGenerator()->create_user();
247 $u2 = $this->getDataGenerator()->create_user();
248 $c1 = $this->getDataGenerator()->create_course();
249 $c2 = $this->getDataGenerator()->create_course();
250 $sysctx = context_system::instance();
251 $c1ctx = context_course::instance($c1->id);
252 $c2ctx = context_course::instance($c2->id);
253
254 $this->enable_logging();
255 $manager = get_log_manager(true);
256
257 // User 1 is the author.
258 $this->setUser($u1);
259 $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
260 $e->trigger();
261 $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
262 $e->trigger();
263 $e = \logstore_database\event\unittest_executed::create(['context' => $c2ctx]);
264 $e->trigger();
265
266 // User 2 is the author.
267 $this->setUser($u2);
268 $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
269 $e->trigger();
270 $e = \logstore_database\event\unittest_executed::create(['context' => $c2ctx]);
271 $e->trigger();
272
273 // Confirm data present.
274 $this->assertTrue($DB->record_exists('logstore_standard_log', ['contextid' => $c1ctx->id]));
275 $this->assertEquals(3, $DB->count_records('logstore_standard_log', ['userid' => $u1->id]));
276 $this->assertEquals(2, $DB->count_records('logstore_standard_log', ['userid' => $u2->id]));
277
278 // Delete all the things!
279 provider::delete_data_for_all_users_in_context($c1ctx);
280 $this->assertFalse($DB->record_exists('logstore_standard_log', ['contextid' => $c1ctx->id]));
281 $this->assertEquals(1, $DB->count_records('logstore_standard_log', ['userid' => $u1->id]));
282 $this->assertEquals(1, $DB->count_records('logstore_standard_log', ['userid' => $u2->id]));
283 }
284
ac7d086d
AG
285 /**
286 * Check that data is removed for the listed users in a given context.
287 */
d638ab7c 288 public function test_delete_data_for_userlist() {
ac7d086d
AG
289 global $DB;
290
291 $u1 = $this->getDataGenerator()->create_user();
292 $u2 = $this->getDataGenerator()->create_user();
293 $u3 = $this->getDataGenerator()->create_user();
294 $u4 = $this->getDataGenerator()->create_user();
295
296 $course = $this->getDataGenerator()->create_course();
297 $sysctx = context_system::instance();
298 $c1ctx = context_course::instance($course->id);
299
300 $this->enable_logging();
301 $manager = get_log_manager(true);
302
303 $this->setUser($u1);
304 $e = \logstore_database\event\unittest_executed::create(['context' => $sysctx]);
305 $e->trigger();
306 $this->setUser($u2);
307 $e = \logstore_database\event\unittest_executed::create(['context' => $sysctx]);
308 $e->trigger();
309 $this->setUser($u3);
310 $e = \logstore_database\event\unittest_executed::create(['context' => $sysctx]);
311 $e->trigger();
312 $this->setUser($u4);
313 $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
314 $e->trigger();
315
316 // Check that four records were created.
317 $this->assertEquals(4, $DB->count_records('logstore_standard_log'));
318
319 $userlist = new \core_privacy\local\request\approved_userlist($sysctx, 'logstore_database', [$u1->id, $u3->id]);
d638ab7c 320 provider::delete_data_for_userlist($userlist);
ac7d086d
AG
321 // We should have a record for u2 and u4.
322 $this->assertEquals(2, $DB->count_records('logstore_standard_log'));
323
324 $records = $DB->get_records('logstore_standard_log', ['contextid' => $sysctx->id]);
325 $this->assertCount(1, $records);
326 $currentrecord = array_shift($records);
327 $this->assertEquals($u2->id, $currentrecord->userid);
328 }
329
0f3bcbb9
FM
330 public function test_export_data_for_user() {
331 $admin = \core_user::get_user(2);
332 $u1 = $this->getDataGenerator()->create_user();
333 $u2 = $this->getDataGenerator()->create_user();
334 $u3 = $this->getDataGenerator()->create_user();
335 $u4 = $this->getDataGenerator()->create_user();
336 $c1 = $this->getDataGenerator()->create_course();
337 $cm1 = $this->getDataGenerator()->create_module('url', ['course' => $c1]);
338 $c2 = $this->getDataGenerator()->create_course();
339 $cm2 = $this->getDataGenerator()->create_module('url', ['course' => $c2]);
340 $sysctx = context_system::instance();
341 $c1ctx = context_course::instance($c1->id);
342 $c2ctx = context_course::instance($c2->id);
343 $cm1ctx = context_module::instance($cm1->cmid);
344 $cm2ctx = context_module::instance($cm2->cmid);
345
346 $path = [get_string('privacy:path:logs', 'tool_log'), get_string('pluginname', 'logstore_database')];
347 $this->enable_logging();
348 $manager = get_log_manager(true);
349
350 // User 1 is the author.
351 $this->setUser($u1);
352 $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx, 'other' => ['i' => 0]]);
353 $e->trigger();
354
355 // User 2 is related.
356 $this->setUser(0);
357 $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx, 'relateduserid' => $u2->id,
358 'other' => ['i' => 1]]);
359 $e->trigger();
360
361 // Admin user masquerades u3, which is related to u4.
362 $this->setAdminUser();
363 \core\session\manager::loginas($u3->id, $sysctx);
364 $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx, 'relateduserid' => $u4->id,
365 'other' => ['i' => 2]]);
366 $e->trigger();
367
368 // Confirm data present for u1.
369 provider::export_user_data(new approved_contextlist($u1, 'logstore_database', [$c2ctx->id, $c1ctx->id]));
370 $data = writer::with_context($c2ctx)->get_data($path);
371 $this->assertEmpty($data);
372 $data = writer::with_context($c1ctx)->get_data($path);
373 $this->assertCount(1, $data->logs);
374 $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_you']);
375 $this->assertSame(0, $data->logs[0]['other']['i']);
376
377 // Confirm data present for u2.
378 writer::reset();
379 provider::export_user_data(new approved_contextlist($u2, 'logstore_database', [$c2ctx->id, $c1ctx->id]));
380 $data = writer::with_context($c2ctx)->get_data($path);
381 $this->assertEmpty($data);
382 $data = writer::with_context($c1ctx)->get_data($path);
383 $this->assertCount(1, $data->logs);
384 $this->assertEquals(transform::yesno(false), $data->logs[0]['author_of_the_action_was_you']);
385 $this->assertEquals(transform::yesno(true), $data->logs[0]['related_user_was_you']);
386 $this->assertSame(1, $data->logs[0]['other']['i']);
387
388 // Confirm data present for u3.
389 writer::reset();
390 provider::export_user_data(new approved_contextlist($u3, 'logstore_database', [$c2ctx->id, $c1ctx->id]));
391 $data = writer::with_context($c2ctx)->get_data($path);
392 $this->assertEmpty($data);
393 $data = writer::with_context($c1ctx)->get_data($path);
394 $this->assertCount(1, $data->logs);
395 $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_you']);
396 $this->assertEquals(transform::yesno(false), $data->logs[0]['related_user_was_you']);
397 $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_masqueraded']);
398 $this->assertEquals(transform::yesno(false), $data->logs[0]['masquerading_user_was_you']);
399 $this->assertSame(2, $data->logs[0]['other']['i']);
400
401 // Confirm data present for u4.
402 writer::reset();
403 provider::export_user_data(new approved_contextlist($u4, 'logstore_database', [$c2ctx->id, $c1ctx->id]));
404 $data = writer::with_context($c2ctx)->get_data($path);
405 $this->assertEmpty($data);
406 $data = writer::with_context($c1ctx)->get_data($path);
407 $this->assertCount(1, $data->logs);
408 $this->assertEquals(transform::yesno(false), $data->logs[0]['author_of_the_action_was_you']);
409 $this->assertEquals(transform::yesno(true), $data->logs[0]['related_user_was_you']);
410 $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_masqueraded']);
411 $this->assertEquals(transform::yesno(false), $data->logs[0]['masquerading_user_was_you']);
412 $this->assertSame(2, $data->logs[0]['other']['i']);
413
414 // Add anonymous events.
415 $this->setUser($u1);
416 $e = \logstore_database\event\unittest_executed::create(['context' => $c2ctx, 'relateduserid' => $u2->id,
417 'anonymous' => true]);
418 $e->trigger();
419 $this->setAdminUser();
420 \core\session\manager::loginas($u3->id, $sysctx);
421 $e = \logstore_database\event\unittest_executed::create(['context' => $c2ctx, 'relateduserid' => $u4->id,
422 'anonymous' => true]);
423 $e->trigger();
424
425 // Confirm data present for u1.
426 provider::export_user_data(new approved_contextlist($u1, 'logstore_database', [$c2ctx->id]));
427 $data = writer::with_context($c2ctx)->get_data($path);
428 $this->assertCount(1, $data->logs);
429 $this->assertEquals(transform::yesno(true), $data->logs[0]['action_was_done_anonymously']);
430 $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_you']);
431
432 // Confirm data present for u2.
433 writer::reset();
434 provider::export_user_data(new approved_contextlist($u2, 'logstore_database', [$c2ctx->id]));
435 $data = writer::with_context($c2ctx)->get_data($path);
436 $this->assertCount(1, $data->logs);
437 $this->assertEquals(transform::yesno(true), $data->logs[0]['action_was_done_anonymously']);
438 $this->assertArrayNotHasKey('author_of_the_action_was_you', $data->logs[0]);
439 $this->assertArrayNotHasKey('authorid', $data->logs[0]);
440 $this->assertEquals(transform::yesno(true), $data->logs[0]['related_user_was_you']);
441
442 // Confirm data present for u3.
443 writer::reset();
444 provider::export_user_data(new approved_contextlist($u3, 'logstore_database', [$c2ctx->id]));
445 $data = writer::with_context($c2ctx)->get_data($path);
446 $this->assertCount(1, $data->logs);
447 $this->assertEquals(transform::yesno(true), $data->logs[0]['action_was_done_anonymously']);
448 $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_you']);
449 $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_masqueraded']);
450 $this->assertArrayNotHasKey('masquerading_user_was_you', $data->logs[0]);
451 $this->assertArrayNotHasKey('masqueradinguserid', $data->logs[0]);
452
453 // Confirm data present for u4.
454 writer::reset();
455 provider::export_user_data(new approved_contextlist($u4, 'logstore_database', [$c2ctx->id]));
456 $data = writer::with_context($c2ctx)->get_data($path);
457 $this->assertCount(1, $data->logs);
458 $this->assertEquals(transform::yesno(true), $data->logs[0]['action_was_done_anonymously']);
459 $this->assertArrayNotHasKey('author_of_the_action_was_you', $data->logs[0]);
460 $this->assertArrayNotHasKey('authorid', $data->logs[0]);
461 $this->assertEquals(transform::yesno(true), $data->logs[0]['related_user_was_you']);
462 $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_masqueraded']);
463 $this->assertArrayNotHasKey('masquerading_user_was_you', $data->logs[0]);
464 $this->assertArrayNotHasKey('masqueradinguserid', $data->logs[0]);
465 }
466
467 /**
468 * Assert the content of a context list.
469 *
470 * @param contextlist $contextlist The collection.
471 * @param array $expected List of expected contexts or IDs.
472 * @return void
473 */
474 protected function assert_contextlist_equals($contextlist, array $expected) {
475 $expectedids = array_map(function($context) {
476 if (is_object($context)) {
477 return $context->id;
478 }
479 return $context;
480 }, $expected);
481 $contextids = array_map('intval', $contextlist->get_contextids());
482 sort($contextids);
483 sort($expectedids);
484 $this->assertEquals($expectedids, $contextids);
485 }
486
487 /**
488 * Enable logging.
489 *
490 * @return void
491 */
492 protected function enable_logging() {
493 set_config('enabled_stores', 'logstore_database', 'tool_log');
494 set_config('buffersize', 0, 'logstore_database');
495 set_config('logguests', 1, 'logstore_database');
496 get_log_manager(true);
497 }
498
499 /**
500 * Get the contextlist for a user.
501 *
502 * @param object $user The user.
503 * @return contextlist
504 */
505 protected function get_contextlist_for_user($user) {
506 $contextlist = new contextlist();
507 provider::add_contexts_for_userid($contextlist, $user->id);
508 return $contextlist;
509 }
510}