MDL-63500 core_group: support removal of multiple users in a context

This issue is part of the MDL-62560 Epic.
This commit is contained in:
Shamim Rezaie 2018-10-04 21:33:30 +10:00 committed by David Monllao
parent bb65ee165c
commit e114ac6ec0
2 changed files with 214 additions and 1 deletions

View File

@ -29,8 +29,10 @@ defined('MOODLE_INTERNAL') || die();
use core_privacy\local\metadata\collection;
use core_privacy\local\request\approved_contextlist;
use core_privacy\local\request\approved_userlist;
use core_privacy\local\request\contextlist;
use core_privacy\local\request\transform;
use core_privacy\local\request\userlist;
/**
* Privacy Subsystem implementation for core_group.
@ -46,7 +48,10 @@ class provider implements
\core_privacy\local\request\subsystem\provider,
// The group subsystem can provide information to other plugins.
\core_privacy\local\request\subsystem\plugin_provider {
\core_privacy\local\request\subsystem\plugin_provider,
// This plugin is capable of determining which users have data within it.
\core_privacy\local\request\core_userlist_provider {
/**
* Returns meta data about this system.
@ -190,6 +195,73 @@ class provider implements
\cache_helper::invalidate_by_definition('core', 'user_group_groupings', array(), array($userid));
}
/**
* Add the list of users who are members of some groups in the specified constraints.
*
* @param userlist $userlist The userlist to add the users to.
* @param string $component The component to check.
* @param int $itemid Optional itemid associated with component.
*/
public static function get_group_members_in_context(userlist $userlist, string $component, int $itemid = 0) {
$context = $userlist->get_context();
if (!$context instanceof \context_course) {
return;
}
// Group members in the given context.
$sql = "SELECT gm.userid
FROM {groups_members} gm
JOIN {groups} g ON gm.groupid = g.id
WHERE g.courseid = :courseid AND gm.component = :component";
$params = [
'courseid' => $context->instanceid,
'component' => $component
];
if ($itemid) {
$sql .= ' AND gm.itemid = :itemid';
$params['itemid'] = $itemid;
}
$userlist->add_from_sql('userid', $sql, $params);
}
/**
* Deletes all records for multiple users within a single context.
*
* @param approved_userlist $userlist The approved context and user information to delete information for.
* @param string $component Component to delete from. Empty string means no component (manual memberships).
* @param int $itemid Optional itemid associated with component.
*/
public static function delete_groups_for_users(approved_userlist $userlist, string $component, int $itemid = 0) {
global $DB;
$context = $userlist->get_context();
$userids = $userlist->get_userids();
list($usersql, $userparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
$groupselect = "SELECT g.id
FROM {groups} g
JOIN {context} ctx ON g.courseid = ctx.instanceid AND ctx.contextlevel = :contextcourse
WHERE ctx.id = :contextid";
$groupparams = ['contextid' => $context->id, 'contextcourse' => CONTEXT_COURSE];
$select = "component = :component AND userid {$usersql} AND groupid IN ({$groupselect})";
$params = ['component' => $component] + $groupparams + $userparams;
if ($itemid) {
$select .= ' AND itemid = :itemid';
$params['itemid'] = $itemid;
}
$DB->delete_records_select('groups_members', $select, $params);
// Invalidate the group and grouping cache for the user.
\cache_helper::invalidate_by_definition('core', 'user_group_groupings', array(), $userids);
}
/**
* Get the list of contexts that contain user information for the specified user.
*
@ -215,6 +287,21 @@ class provider implements
return $contextlist;
}
/**
* Get the list of users who have data within a 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();
if (!$context instanceof \context_course) {
return;
}
static::get_group_members_in_context($userlist, '');
}
/**
* Export all user data for the specified user, in the specified contexts.
*
@ -245,4 +332,14 @@ class provider implements
public static function delete_data_for_user(approved_contextlist $contextlist) {
static::delete_groups_for_user($contextlist, '');
}
/**
* 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) {
static::delete_groups_for_users($userlist, '');
}
}

View File

@ -789,4 +789,120 @@ class core_group_privacy_provider_testcase extends provider_testcase {
WHERE gm.userid = ?", [$user1->id])
);
}
/**
* Test for provider::delete_data_for_users().
*/
public function test_delete_data_for_users() {
global $DB;
$this->resetAfterTest();
$course1 = $this->getDataGenerator()->create_course();
$course2 = $this->getDataGenerator()->create_course();
$group1a = $this->getDataGenerator()->create_group(array('courseid' => $course1->id));
$group1b = $this->getDataGenerator()->create_group(array('courseid' => $course1->id));
$group1c = $this->getDataGenerator()->create_group(array('courseid' => $course1->id));
$group2a = $this->getDataGenerator()->create_group(array('courseid' => $course2->id));
$group2b = $this->getDataGenerator()->create_group(array('courseid' => $course2->id));
$group2c = $this->getDataGenerator()->create_group(array('courseid' => $course2->id));
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
$user3 = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($user1->id, $course1->id);
$this->getDataGenerator()->enrol_user($user1->id, $course2->id);
$this->getDataGenerator()->enrol_user($user2->id, $course1->id);
$this->getDataGenerator()->enrol_user($user2->id, $course2->id);
$this->getDataGenerator()->enrol_user($user3->id, $course1->id);
$this->getDataGenerator()->enrol_user($user3->id, $course2->id);
$this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user1->id));
$this->getDataGenerator()->create_group_member(array('groupid' => $group1b->id, 'userid' => $user2->id));
$this->getDataGenerator()->create_group_member(array('groupid' => $group1c->id, 'userid' => $user3->id));
$this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user1->id));
$this->getDataGenerator()->create_group_member(array('groupid' => $group2b->id, 'userid' => $user2->id));
$this->getDataGenerator()->create_group_member(array('groupid' => $group2c->id, 'userid' => $user3->id));
$this->assertEquals(
3,
$DB->count_records_sql("SELECT COUNT(gm.id)
FROM {groups_members} gm
JOIN {groups} g ON gm.groupid = g.id
WHERE g.courseid = ?", [$course1->id])
);
$this->assertEquals(
3,
$DB->count_records_sql("SELECT COUNT(gm.id)
FROM {groups_members} gm
JOIN {groups} g ON gm.groupid = g.id
WHERE g.courseid = ?", [$course2->id])
);
$coursecontext1 = context_course::instance($course1->id);
$approveduserlist = new \core_privacy\local\request\approved_userlist($coursecontext1, 'core_group',
[$user1->id, $user2->id]);
provider::delete_data_for_users($approveduserlist);
$this->assertEquals(
[$user3->id],
$DB->get_fieldset_sql("SELECT gm.userid
FROM {groups_members} gm
JOIN {groups} g ON gm.groupid = g.id
WHERE g.courseid = ?", [$course1->id])
);
$this->assertEquals(
3,
$DB->count_records_sql("SELECT COUNT(gm.id)
FROM {groups_members} gm
JOIN {groups} g ON gm.groupid = g.id
WHERE g.courseid = ?", [$course2->id])
);
}
/**
* Test for provider::get_users_in_context().
*/
public function test_get_users_in_context() {
$this->resetAfterTest();
$course1 = $this->getDataGenerator()->create_course();
$course2 = $this->getDataGenerator()->create_course();
$group1a = $this->getDataGenerator()->create_group(array('courseid' => $course1->id));
$group1b = $this->getDataGenerator()->create_group(array('courseid' => $course1->id));
$group2a = $this->getDataGenerator()->create_group(array('courseid' => $course2->id));
$group2b = $this->getDataGenerator()->create_group(array('courseid' => $course2->id));
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
$user3 = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($user1->id, $course1->id);
$this->getDataGenerator()->enrol_user($user1->id, $course2->id);
$this->getDataGenerator()->enrol_user($user2->id, $course1->id);
$this->getDataGenerator()->enrol_user($user2->id, $course2->id);
$this->getDataGenerator()->enrol_user($user3->id, $course1->id);
$this->getDataGenerator()->enrol_user($user3->id, $course2->id);
$this->getDataGenerator()->create_group_member(array('userid' => $user1->id, 'groupid' => $group1a->id));
$this->getDataGenerator()->create_group_member(array('userid' => $user1->id, 'groupid' => $group2a->id));
$this->getDataGenerator()->create_group_member(array('userid' => $user2->id, 'groupid' => $group1b->id));
$this->getDataGenerator()->create_group_member(array('userid' => $user2->id, 'groupid' => $group2b->id));
$this->getDataGenerator()->create_group_member(array('userid' => $user3->id, 'groupid' => $group2a->id));
$coursecontext1 = context_course::instance($course1->id);
$userlist = new \core_privacy\local\request\userlist($coursecontext1, 'core_group');
\core_group\privacy\provider::get_users_in_context($userlist);
// Only user1 and user2. User3 is not member of any group in course1.
$this->assertCount(2, $userlist);
$this->assertEquals(
[$user1->id, $user2->id],
$userlist->get_userids(),
'', 0.0, 10, true);
}
}