MDL-63684 core_calendar: Add support for removal of context users

This issue is part of the MDL-62560 Epic.
This commit is contained in:
Mihail Geshoski 2018-10-31 14:10:08 +08:00
parent 448bd578d8
commit c844eafd6f
2 changed files with 504 additions and 30 deletions

View File

@ -20,7 +20,9 @@
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\privacy;
defined('MOODLE_INTERNAL') || die();
use \core_privacy\local\metadata\collection;
@ -29,6 +31,8 @@ use \core_privacy\local\request\context;
use \core_privacy\local\request\contextlist;
use \core_privacy\local\request\transform;
use \core_privacy\local\request\writer;
use \core_privacy\local\request\userlist;
use \core_privacy\local\request\approved_userlist;
/**
* Privacy Subsystem for core_calendar implementing metadata, plugin, and user_preference providers.
@ -38,9 +42,10 @@ use \core_privacy\local\request\writer;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements
\core_privacy\local\metadata\provider,
\core_privacy\local\request\plugin\provider,
\core_privacy\local\request\user_preference_provider
\core_privacy\local\metadata\provider,
\core_privacy\local\request\plugin\provider,
\core_privacy\local\request\core_userlist_provider,
\core_privacy\local\request\user_preference_provider
{
/**
@ -149,6 +154,101 @@ class provider implements
return $contextlist;
}
/**
* Get the list of users within a specific context.
*
* @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
*/
public static function get_users_in_context(userlist $userlist) {
$context = $userlist->get_context();
$allowedcontexts = [
CONTEXT_SYSTEM,
CONTEXT_COURSECAT,
CONTEXT_COURSE,
CONTEXT_MODULE,
CONTEXT_USER
];
if (!in_array($context->contextlevel, $allowedcontexts)) {
return;
}
$params = [
'modulecontext' => CONTEXT_MODULE,
'contextid' => $context->id,
];
$sql = "SELECT e.userid
FROM {course_modules} cm
JOIN {modules} m
ON m.id = cm.module
JOIN {event} e
ON e.modulename = m.name
AND e.courseid = cm.course
AND e.instance = cm.instance
JOIN {context} ctx
ON ctx.instanceid = cm.id
AND ctx.contextlevel = :modulecontext
WHERE ctx.id = :contextid";
$userlist->add_from_sql('userid', $sql, $params);
// Calendar Events can exist at Site, Course Category, Course, Course Group, User, or Course Modules contexts.
$params = [
'sitecontext' => CONTEXT_SYSTEM,
'categorycontext' => CONTEXT_COURSECAT,
'coursecontext' => CONTEXT_COURSE,
'groupcontext' => CONTEXT_COURSE,
'usercontext' => CONTEXT_USER,
'contextid' => $context->id
];
// Get contexts of Calendar Events for the owner.
$sql = "SELECT e.userid
FROM {event} e
JOIN {context} ctx
ON (ctx.contextlevel = :sitecontext
AND e.eventtype = 'site')
OR (ctx.contextlevel = :categorycontext
AND ctx.instanceid = e.categoryid
AND e.eventtype = 'category')
OR (ctx.contextlevel = :coursecontext
AND ctx.instanceid = e.courseid
AND e.eventtype = 'course')
OR (ctx.contextlevel = :groupcontext
AND ctx.instanceid = e.courseid
AND e.eventtype = 'group')
OR (ctx.contextlevel = :usercontext
AND ctx.instanceid = e.userid
AND e.eventtype = 'user')
WHERE ctx.id = :contextid";
$userlist->add_from_sql('userid', $sql, $params);
// Get contexts for Calendar Subscriptions for the owner.
$sql = "SELECT s.userid
FROM {event_subscriptions} s
JOIN {context} ctx
ON (ctx.contextlevel = :sitecontext
AND s.eventtype = 'site')
OR (ctx.instanceid = s.categoryid
AND ctx.contextlevel = :categorycontext
AND s.eventtype = 'category')
OR (ctx.instanceid = s.courseid
AND ctx.contextlevel = :coursecontext
AND s.eventtype = 'course')
OR (ctx.instanceid = s.courseid
AND ctx.contextlevel = :groupcontext
AND s.eventtype = 'group')
OR (ctx.instanceid = s.userid
AND ctx.contextlevel = :usercontext
AND s.eventtype = 'user')
WHERE ctx.id = :contextid";
$userlist->add_from_sql('userid', $sql, $params);
}
/**
* Export all user data for the specified user, in the specified contexts.
*
@ -198,6 +298,42 @@ class provider implements
}
}
/**
* Delete multiple users within a single context.
*
* @param approved_userlist $userlist The approved context and user information to delete information for.
*/
public static function delete_data_for_users(approved_userlist $userlist) {
$context = $userlist->get_context();
$userids = $userlist->get_userids();
$allowedcontexts = [
CONTEXT_SYSTEM,
CONTEXT_COURSECAT,
CONTEXT_COURSE,
CONTEXT_MODULE,
CONTEXT_USER
];
if (!in_array($context->contextlevel, $allowedcontexts)) {
return;
}
if (empty($userids)) {
return;
}
// Delete all Calendar Events in the specified context in batches.
if ($eventids = array_keys(self::get_calendar_event_ids_by_context($context, $userids))) {
self::delete_batch_records('event', 'id', $eventids);
}
// Delete all Calendar Subscriptions in the specified context in batches.
if ($subscriptionids = array_keys(self::get_calendar_subscription_ids_by_context($context, $userids))) {
self::delete_batch_records('event_subscriptions', 'id', $subscriptionids);
}
}
/**
* Delete all user data for the specified user, in the specified contexts.
*
@ -334,18 +470,25 @@ class provider implements
}
/**
* Helper function to return all Calendar Event id results for a specified context.
* Helper function to return all Calendar Event id results for a specified context and optionally
* included user list.
*
* @param \context $context
* @param array $userids
* @return array|null
* @throws \dml_exception
*/
protected static function get_calendar_event_ids_by_context(\context $context) {
protected static function get_calendar_event_ids_by_context(\context $context, $userids = array()) {
global $DB;
// Calendar Events can exist at Site, Course Category, Course, Course Group, User, or Course Modules contexts.
$events = null;
$whereusersql = '';
$userparams = array();
if (!empty($userids)) {
list($usersql, $userparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
$whereusersql = "AND e.userid {$usersql}";
}
// Calendar Events can exist at Site, Course Category, Course, Course Group, User, or Course Modules contexts.
if ($context->contextlevel == CONTEXT_MODULE) { // Course Module Contexts.
$params = [
'modulecontext' => $context->contextlevel,
@ -356,11 +499,17 @@ class provider implements
$sql = "SELECT DISTINCT
e.id AS eventid
FROM {context} ctx
INNER JOIN {course_modules} cm ON cm.id = ctx.instanceid AND ctx.contextlevel = :modulecontext
INNER JOIN {modules} m ON m.id = cm.module
INNER JOIN {event} e ON e.modulename = m.name AND e.courseid = cm.course AND e.instance = cm.instance
WHERE ctx.id = :contextid";
$events = $DB->get_records_sql($sql, $params);
INNER JOIN {course_modules} cm
ON cm.id = ctx.instanceid
AND ctx.contextlevel = :modulecontext
INNER JOIN {modules} m
ON m.id = cm.module
INNER JOIN {event} e
ON e.modulename = m.name
AND e.courseid = cm.course
AND e.instance = cm.instance
WHERE ctx.id = :contextid
{$whereusersql}";
} else { // Other Moodle Contexts.
$params = [
'sitecontext' => CONTEXT_SYSTEM,
@ -375,26 +524,38 @@ class provider implements
$sql = "SELECT DISTINCT
e.id AS eventid
FROM {context} ctx
INNER JOIN {event} e ON
(e.eventtype = 'site' AND ctx.contextlevel = :sitecontext) OR
(e.categoryid = ctx.instanceid AND e.eventtype = 'category' AND ctx.contextlevel = :categorycontext) OR
(e.courseid = ctx.instanceid AND (e.eventtype = 'course' OR e.eventtype = 'group' OR e.modulename != '0') AND ctx.contextlevel = :coursecontext) OR
(e.userid = ctx.instanceid AND e.eventtype = 'user' AND ctx.contextlevel = :usercontext)
WHERE ctx.id = :contextid";
$events = $DB->get_records_sql($sql, $params);
INNER JOIN {event} e
ON (e.eventtype = 'site'
AND ctx.contextlevel = :sitecontext)
OR (e.categoryid = ctx.instanceid
AND e.eventtype = 'category'
AND ctx.contextlevel = :categorycontext)
OR (e.courseid = ctx.instanceid
AND (e.eventtype = 'course'
OR e.eventtype = 'group'
OR e.modulename != '0')
AND ctx.contextlevel = :coursecontext)
OR (e.userid = ctx.instanceid
AND e.eventtype = 'user'
AND ctx.contextlevel = :usercontext)
WHERE ctx.id = :contextid
{$whereusersql}";
}
$params += $userparams;
return $events;
return $DB->get_records_sql($sql, $params);
}
/**
* Helper function to return all Calendar Subscription id results for a specified context.
* Helper function to return all Calendar Subscription id results for a specified context and optionally
* included user list.
*
* @param \context $context
* @param array $userids
* @return array
* @throws \dml_exception
*/
protected static function get_calendar_subscription_ids_by_context(\context $context) {
protected static function get_calendar_subscription_ids_by_context(\context $context, $userids = array()) {
global $DB;
// Calendar Subscriptions can exist at Site, Course Category, Course, Course Group, or User contexts.
@ -407,17 +568,36 @@ class provider implements
'contextid' => $context->id
];
$whereusersql = '';
$userparams = array();
if (!empty($userids)) {
list($usersql, $userparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
$whereusersql = "AND s.userid {$usersql}";
}
// Get Calendar Subscriptions for the specified context.
$sql = "SELECT DISTINCT
s.id AS subscriptionid
FROM {context} ctx
INNER JOIN {event_subscriptions} s ON
(s.eventtype = 'site' AND ctx.contextlevel = :sitecontext) OR
(s.categoryid = ctx.instanceid AND s.eventtype = 'category' AND ctx.contextlevel = :categorycontext) OR
(s.courseid = ctx.instanceid AND s.eventtype = 'course' AND ctx.contextlevel = :coursecontext) OR
(s.courseid = ctx.instanceid AND s.eventtype = 'group' AND ctx.contextlevel = :groupcontext) OR
(s.userid = ctx.instanceid AND s.eventtype = 'user' AND ctx.contextlevel = :usercontext)
WHERE ctx.id = :contextid";
INNER JOIN {event_subscriptions} s
ON (s.eventtype = 'site'
AND ctx.contextlevel = :sitecontext)
OR (s.categoryid = ctx.instanceid
AND s.eventtype = 'category'
AND ctx.contextlevel = :categorycontext)
OR (s.courseid = ctx.instanceid
AND s.eventtype = 'course'
AND ctx.contextlevel = :coursecontext)
OR (s.courseid = ctx.instanceid
AND s.eventtype = 'group'
AND ctx.contextlevel = :groupcontext)
OR (s.userid = ctx.instanceid
AND s.eventtype = 'user'
AND ctx.contextlevel = :usercontext)
WHERE ctx.id = :contextid
{$whereusersql}";
$params += $userparams;
return $DB->get_records_sql($sql, $params);
}
@ -552,5 +732,4 @@ class provider implements
$DB->delete_records_list($tablename, $field, $batchrecord);
}
}
}

View File

@ -34,6 +34,7 @@ use \core_privacy\local\metadata\collection;
use \core_privacy\local\request\approved_contextlist;
use \core_privacy\local\request\writer;
use \core_privacy\tests\provider_testcase;
use \core_privacy\local\request\approved_userlist;
/**
* Unit tests for calendar/classes/privacy/provider
@ -429,6 +430,300 @@ class core_calendar_privacy_testcase extends provider_testcase {
$this->assertCount(1, $eventsubscriptions);
}
/**
* Test that only users with a user context are fetched.
*/
public function test_get_users_in_context() {
$component = 'core_calendar';
// Create user1 to create Calendar Events and Subscriptions.
$user1 = $this->getDataGenerator()->create_user();
$usercontext1 = context_user::instance($user1->id);
// Create user2 to create Calendar Events and Subscriptions.
$user2 = $this->getDataGenerator()->create_user();
$usercontext2 = context_user::instance($user2->id);
// Create user3 to create Calendar Events and Subscriptions.
$user3 = $this->getDataGenerator()->create_user();
$usercontext3 = context_user::instance($user3->id);
// Create a Category and Courses to assign Calendar Events and Subscriptions.
$category = $this->getDataGenerator()->create_category();
$categorycontext = context_coursecat::instance($category->id);
$course1 = $this->getDataGenerator()->create_course();
$course1context = context_course::instance($course1->id);
$course2 = $this->getDataGenerator()->create_course();
$course2context = context_course::instance($course2->id);
$course3 = $this->getDataGenerator()->create_course();
$course3context = context_course::instance($course3->id);
$grouprecord = (object)[
'courseid' => $course3->id,
'name' => 'test_group'
];
$course3group = $this->getDataGenerator()->create_group($grouprecord);
// Add Category Calendar Events for Category.
$this->setUser($user1);
$this->create_test_standard_calendar_event('category', $user1->id, time(), '',
$category->id);
$this->setUser($user2);
$this->create_test_standard_calendar_event('category', $user2->id, time(), '',
$category->id);
// Add User Calendar Events for user1 and user2.
$this->setUser($user1);
$this->create_test_standard_calendar_event('user', $user1->id, time(), '');
$this->create_test_standard_calendar_event('user', $user1->id, time(), '',
0, $course1->id);
$this->create_test_standard_calendar_event('user', $user1->id, time(), '',
0, $course2->id);
$this->setUser($user2);
$this->create_test_standard_calendar_event('user', $user2->id, time(), '',
0, $course1->id);
// Add a Course Calendar Events for Course 1.
$this->setUser($user1);
$this->create_test_standard_calendar_event('course', $user1->id, time(), '',
0, $course1->id);
$this->setUser($user2);
$this->create_test_standard_calendar_event('course', $user2->id, time(), '',
0, $course1->id);
// Add a Course Assignment Action Calendar Event for Course 2.
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
$params['course'] = $course2->id;
$params['assignsubmission_onlinetext_enabled'] = 1;
$instance = $generator->create_instance($params);
$cm = get_coursemodule_from_instance('assign', $instance->id);
$modulecontext = context_module::instance($cm->id);
$assign = new assign($modulecontext, $cm, $course2);
$this->setUser($user2);
$this->create_test_action_calendar_event('duedate', $course2->id, $instance->id,
'assign', $user2->id, time());
$this->create_test_action_calendar_event('gradingduedate', $course2->id, $instance->id,
'assign', $user2->id, time());
// Add a Calendar Subscription and Group Calendar Event to Course 3.
$this->create_test_standard_calendar_event('group', $user2->id, time(), '', 0,
$course3->id, $course3group->id);
$this->setUser($user3);
$this->create_test_calendar_subscription('course', 'https://calendar.google.com/', $user3->id,
0, $course3->id);
// The user list for usercontext1 should return user1.
$userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component);
provider::get_users_in_context($userlist1);
$this->assertCount(1, $userlist1);
$this->assertTrue(in_array($user1->id, $userlist1->get_userids()));
// The user list for usercontext2 should return user2.
$userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component);
provider::get_users_in_context($userlist2);
$this->assertCount(1, $userlist2);
$this->assertTrue(in_array($user2->id, $userlist2->get_userids()));
// The user list for course1context should return user1 and user2.
$userlist3 = new \core_privacy\local\request\userlist($course1context, $component);
provider::get_users_in_context($userlist3);
$this->assertCount(2, $userlist3);
$this->assertTrue(in_array($user1->id, $userlist3->get_userids()));
$this->assertTrue(in_array($user2->id, $userlist3->get_userids()));
// The user list for course2context should not return any users.
$userlist4 = new \core_privacy\local\request\userlist($course2context, $component);
provider::get_users_in_context($userlist4);
$this->assertCount(0, $userlist4);
// The user list for course3context should return user2 and user3.
$userlist5 = new \core_privacy\local\request\userlist($course3context, $component);
provider::get_users_in_context($userlist5);
$this->assertCount(2, $userlist5);
$this->assertTrue(in_array($user2->id, $userlist5->get_userids()));
$this->assertTrue(in_array($user3->id, $userlist5->get_userids()));
// The user list for categorycontext should return user1 and user2.
$userlist6 = new \core_privacy\local\request\userlist($categorycontext, $component);
provider::get_users_in_context($userlist6);
$this->assertCount(2, $userlist6);
$this->assertTrue(in_array($user1->id, $userlist6->get_userids()));
$this->assertTrue(in_array($user2->id, $userlist6->get_userids()));
// The user list for modulecontext should return user2.
$userlist7 = new \core_privacy\local\request\userlist($modulecontext, $component);
provider::get_users_in_context($userlist7);
$this->assertCount(1, $userlist7);
$this->assertTrue(in_array($user2->id, $userlist7->get_userids()));
// The user list for usercontext3 should not return any users.
$userlist8 = new \core_privacy\local\request\userlist($usercontext3, $component);
provider::get_users_in_context($userlist8);
$this->assertCount(0, $userlist8);
}
/**
* Test that data for users in approved userlist is deleted.
*/
public function test_delete_data_for_users() {
$component = 'core_calendar';
// Create user1 to create Calendar Events and Subscriptions.
$user1 = $this->getDataGenerator()->create_user();
$usercontext1 = context_user::instance($user1->id);
// Create user2 to create Calendar Events and Subscriptions.
$user2 = $this->getDataGenerator()->create_user();
$usercontext2 = context_user::instance($user2->id);
// Create user3 to create Calendar Events and Subscriptions.
$user3 = $this->getDataGenerator()->create_user();
$usercontext3 = context_user::instance($user3->id);
// Create a Category and Courses to assign Calendar Events and Subscriptions.
$category = $this->getDataGenerator()->create_category();
$categorycontext = context_coursecat::instance($category->id);
$course1 = $this->getDataGenerator()->create_course();
$course1context = context_course::instance($course1->id);
$course2 = $this->getDataGenerator()->create_course();
$course2context = context_course::instance($course2->id);
$course3 = $this->getDataGenerator()->create_course();
$course3context = context_course::instance($course3->id);
$grouprecord = (object)[
'courseid' => $course3->id,
'name' => 'test_group'
];
$course3group = $this->getDataGenerator()->create_group($grouprecord);
// Add Category Calendar Events for Category.
$this->setUser($user1);
$this->create_test_standard_calendar_event('category', $user1->id, time(), '',
$category->id);
$this->setUser($user2);
$this->create_test_standard_calendar_event('category', $user2->id, time(), '',
$category->id);
// Add User Calendar Events for user1 and user2.
$this->setUser($user1);
$this->create_test_standard_calendar_event('user', $user1->id, time(), '');
$this->create_test_standard_calendar_event('user', $user1->id, time(), '',
0, $course1->id);
$this->create_test_standard_calendar_event('user', $user1->id, time(), '',
0, $course2->id);
$this->setUser($user2);
$this->create_test_standard_calendar_event('user', $user2->id, time(), '',
0, $course1->id);
// Add a Course Calendar Events for Course 1.
$this->setUser($user1);
$this->create_test_standard_calendar_event('course', $user1->id, time(), '',
0, $course1->id);
$this->setUser($user2);
$this->create_test_standard_calendar_event('course', $user2->id, time(), '',
0, $course1->id);
// Add a Course Assignment Action Calendar Event for Course 2.
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
$params['course'] = $course2->id;
$params['assignsubmission_onlinetext_enabled'] = 1;
$instance = $generator->create_instance($params);
$cm = get_coursemodule_from_instance('assign', $instance->id);
$modulecontext = context_module::instance($cm->id);
$assign = new assign($modulecontext, $cm, $course2);
$this->setUser($user2);
$this->create_test_action_calendar_event('duedate', $course2->id, $instance->id,
'assign', $user2->id, time());
$this->create_test_action_calendar_event('gradingduedate', $course2->id, $instance->id,
'assign', $user2->id, time());
// Add a Calendar Subscription and Group Calendar Event to Course 3.
$this->create_test_standard_calendar_event('group', $user2->id, time(), '', 0,
$course3->id, $course3group->id);
$this->setUser($user3);
$this->create_test_calendar_subscription('course', 'https://calendar.google.com/', $user3->id,
0, $course3->id);
// The user list for usercontext1 should return user1.
$userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component);
provider::get_users_in_context($userlist1);
$this->assertCount(1, $userlist1);
// The user list for usercontext2 should return user2.
$userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component);
provider::get_users_in_context($userlist2);
$this->assertCount(1, $userlist2);
// The user list for course1context should return user1 and user2.
$userlist3 = new \core_privacy\local\request\userlist($course1context, $component);
provider::get_users_in_context($userlist3);
$this->assertCount(2, $userlist3);
// The user list for course2context should not return any users.
$userlist4 = new \core_privacy\local\request\userlist($course2context, $component);
provider::get_users_in_context($userlist4);
$this->assertCount(0, $userlist4);
// The user list for course3context should return user2 and user3.
$userlist5 = new \core_privacy\local\request\userlist($course3context, $component);
provider::get_users_in_context($userlist5);
$this->assertCount(2, $userlist5);
// The user list for categorycontext should return user1 and user2.
$userlist6 = new \core_privacy\local\request\userlist($categorycontext, $component);
provider::get_users_in_context($userlist6);
$this->assertCount(2, $userlist6);
// The user list for modulecontext should return user2.
$userlist7 = new \core_privacy\local\request\userlist($modulecontext, $component);
provider::get_users_in_context($userlist7);
$this->assertCount(1, $userlist7);
// The user list for usercontext3 should not return any users.
$userlist8 = new \core_privacy\local\request\userlist($usercontext3, $component);
provider::get_users_in_context($userlist8);
$this->assertCount(0, $userlist8);
// Convert $userlist1 into an approved_contextlist.
$approvedlist1 = new approved_userlist($usercontext1, $component, $userlist1->get_userids());
// Delete using delete_data_for_user.
provider::delete_data_for_users($approvedlist1);
// The user list for usercontext1 should not return any users.
$userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component);
provider::get_users_in_context($userlist1);
$this->assertCount(0, $userlist1);
// The user list for usercontext2 should still return users2.
$userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component);
provider::get_users_in_context($userlist2);
$this->assertCount(1, $userlist2);
// Convert $userlist3 into an approved_contextlist.
// Pass an empty array as a value for the approved user list.
$approvedlist2 = new approved_userlist($course1context, $component, []);
// Delete using delete_data_for_user.
provider::delete_data_for_users($approvedlist2);
// The user list for course1context should return user1 and user2.
$userlist3 = new \core_privacy\local\request\userlist($course1context, $component);
provider::get_users_in_context($userlist3);
$this->assertCount(2, $userlist3);
$this->assertTrue(in_array($user1->id, $userlist3->get_userids()));
$this->assertTrue(in_array($user2->id, $userlist3->get_userids()));
// Convert $userlist3 into an approved_contextlist.
// Pass the ID of user1 as a value for the approved user list.
$approvedlist2 = new approved_userlist($course1context, $component, [$user1->id]);
// Delete using delete_data_for_user.
provider::delete_data_for_users($approvedlist2);
// The user list for course1context should return user2.
$userlist3 = new \core_privacy\local\request\userlist($course1context, $component);
provider::get_users_in_context($userlist3);
$this->assertCount(1, $userlist3);
$this->assertTrue(in_array($user2->id, $userlist3->get_userids()));
// The user list for course3context should still return user2 and user3.
$userlist5 = new \core_privacy\local\request\userlist($course3context, $component);
provider::get_users_in_context($userlist5);
$this->assertCount(2, $userlist5);
// Convert $userlist6 into an approved_contextlist.
$approvedlist3 = new approved_userlist($categorycontext, $component, $userlist6->get_userids());
// Delete using delete_data_for_user.
provider::delete_data_for_users($approvedlist3);
// The user list for categorycontext should not return any users.
$userlist6 = new \core_privacy\local\request\userlist($categorycontext, $component);
provider::get_users_in_context($userlist6);
$this->assertCount(0, $userlist6);
// Convert $userlist7 into an approved_contextlist.
$approvedlist4 = new approved_userlist($modulecontext, $component, $userlist7->get_userids());
// Delete using delete_data_for_user.
provider::delete_data_for_users($approvedlist4);
// The user list for modulecontext should not return any users.
$userlist7 = new \core_privacy\local\request\userlist($modulecontext, $component);
provider::get_users_in_context($userlist7);
$this->assertCount(0, $userlist7);
}
// Start of helper functions.
/**