mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 05:58:34 +01:00
MDL-63497 mod_chat: Add support for removal of context users
This issue is part of the MDL-62560 Epic.
This commit is contained in:
parent
19fc6012cf
commit
464b17b79b
@ -33,9 +33,11 @@ use moodle_recordset;
|
||||
use stdClass;
|
||||
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\helper;
|
||||
use core_privacy\local\request\transform;
|
||||
use core_privacy\local\request\userlist;
|
||||
use core_privacy\local\request\writer;
|
||||
|
||||
/**
|
||||
@ -48,6 +50,7 @@ use core_privacy\local\request\writer;
|
||||
*/
|
||||
class provider implements
|
||||
\core_privacy\local\metadata\provider,
|
||||
\core_privacy\local\request\core_userlist_provider,
|
||||
\core_privacy\local\request\plugin\provider {
|
||||
|
||||
/**
|
||||
@ -123,6 +126,33 @@ 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 (!is_a($context, \context_module::class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$params = [
|
||||
'instanceid' => $context->instanceid,
|
||||
'modulename' => 'chat',
|
||||
];
|
||||
|
||||
$sql = "SELECT chm.userid
|
||||
FROM {course_modules} cm
|
||||
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
|
||||
JOIN {chat} c ON c.id = cm.instance
|
||||
JOIN {chat_messages} chm ON chm.chatid = c.id
|
||||
WHERE cm.id = :instanceid";
|
||||
|
||||
$userlist->add_from_sql('userid', $sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export all user data for the specified user, in the specified contexts.
|
||||
*
|
||||
@ -225,6 +255,28 @@ class provider implements
|
||||
$DB->delete_records_select('chat_users', $sql, $params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
global $DB;
|
||||
|
||||
$context = $userlist->get_context();
|
||||
$cm = $DB->get_record('course_modules', ['id' => $context->instanceid]);
|
||||
$chat = $DB->get_record('chat', ['id' => $cm->instance]);
|
||||
|
||||
list($userinsql, $userinparams) = $DB->get_in_or_equal($userlist->get_userids(), SQL_PARAMS_NAMED);
|
||||
$params = array_merge(['chatid' => $chat->id], $userinparams);
|
||||
$sql = "chatid = :chatid AND userid {$userinsql}";
|
||||
|
||||
$DB->delete_records_select('chat_messages', $sql, $params);
|
||||
$DB->delete_records_select('chat_messages_current', $sql, $params);
|
||||
$DB->delete_records_select('chat_users', $sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a dict of chat IDs mapped to their course module ID.
|
||||
*
|
||||
|
@ -29,6 +29,7 @@ global $CFG;
|
||||
|
||||
use core_privacy\tests\provider_testcase;
|
||||
use core_privacy\local\request\approved_contextlist;
|
||||
use core_privacy\local\request\approved_userlist;
|
||||
use core_privacy\local\request\transform;
|
||||
use core_privacy\local\request\writer;
|
||||
use mod_chat\privacy\provider;
|
||||
@ -96,6 +97,71 @@ class mod_chat_privacy_testcase extends provider_testcase {
|
||||
$this->assertTrue(in_array(context_module::instance($chat2a->cmid)->id, $contextids));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that only users with relevant contexts are fetched.
|
||||
*/
|
||||
public function test_get_users_in_context() {
|
||||
$component = 'mod_chat';
|
||||
$dg = $this->getDataGenerator();
|
||||
$c1 = $dg->create_course();
|
||||
$c2 = $dg->create_course();
|
||||
|
||||
$u1 = $dg->create_user();
|
||||
$u2 = $dg->create_user();
|
||||
|
||||
$chat1a = $dg->create_module('chat', ['course' => $c1]);
|
||||
$chat1b = $dg->create_module('chat', ['course' => $c1]);
|
||||
$chat2a = $dg->create_module('chat', ['course' => $c2]);
|
||||
|
||||
// Logins but no message.
|
||||
$chatuser = $this->login_user_in_course_chat($u1, $c1, $chat1a);
|
||||
|
||||
// Logins and messages.
|
||||
$chatuser = $this->login_user_in_course_chat($u1, $c1, $chat1b);
|
||||
chat_send_chatmessage($chatuser, 'Hello world!');
|
||||
|
||||
// Silent login (no system message).
|
||||
$chatuser = $this->login_user_in_course_chat($u1, $c2, $chat2a, 0, true);
|
||||
|
||||
// Silent login and messages.
|
||||
$chatuser = $this->login_user_in_course_chat($u2, $c1, $chat1b, 0, true);
|
||||
chat_send_chatmessage($chatuser, 'Ça va ?');
|
||||
chat_send_chatmessage($chatuser, 'Moi, ça va.');
|
||||
|
||||
// Silent login and messages.
|
||||
$chatuser = $this->login_user_in_course_chat($u2, $c2, $chat2a);
|
||||
chat_send_chatmessage($chatuser, 'What\'s happening here?');
|
||||
|
||||
$context1a = context_module::instance($chat1a->cmid);
|
||||
$context1b = context_module::instance($chat1b->cmid);
|
||||
$context2a = context_module::instance($chat2a->cmid);
|
||||
|
||||
$userlist1a = new \core_privacy\local\request\userlist($context1a, $component);
|
||||
$userlist1b = new \core_privacy\local\request\userlist($context1b, $component);
|
||||
$userlist2a = new \core_privacy\local\request\userlist($context2a, $component);
|
||||
\mod_chat\privacy\provider::get_users_in_context($userlist1a);
|
||||
\mod_chat\privacy\provider::get_users_in_context($userlist1b);
|
||||
\mod_chat\privacy\provider::get_users_in_context($userlist2a);
|
||||
|
||||
// Ensure correct users are found in relevant contexts.
|
||||
$this->assertCount(1, $userlist1a);
|
||||
$expected = [$u1->id];
|
||||
$actual = $userlist1a->get_userids();
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
$this->assertCount(2, $userlist1b);
|
||||
$expected = [$u1->id, $u2->id];
|
||||
$actual = $userlist1b->get_userids();
|
||||
sort($expected);
|
||||
sort($actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
$this->assertCount(1, $userlist2a);
|
||||
$expected = [$u1->id];
|
||||
$actual = $userlist1a->get_userids();
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
public function test_delete_data_for_all_users_in_context() {
|
||||
global $DB;
|
||||
$dg = $this->getDataGenerator();
|
||||
@ -190,6 +256,62 @@ class mod_chat_privacy_testcase extends provider_testcase {
|
||||
$this->assert_has_no_data_in_chat($u2, $chat1b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that data for users in approved userlist is deleted.
|
||||
*/
|
||||
public function test_delete_data_for_users() {
|
||||
global $DB;
|
||||
$component = 'mod_chat';
|
||||
$dg = $this->getDataGenerator();
|
||||
$c1 = $dg->create_course();
|
||||
|
||||
$u1 = $dg->create_user();
|
||||
$u2 = $dg->create_user();
|
||||
$u3 = $dg->create_user();
|
||||
|
||||
$chat1 = $dg->create_module('chat', ['course' => $c1]);
|
||||
$chat1context = context_module::instance($chat1->cmid);
|
||||
|
||||
$u1chat1 = $this->login_user_in_course_chat($u1, $c1, $chat1);
|
||||
$u2chat1 = $this->login_user_in_course_chat($u2, $c1, $chat1);
|
||||
$u3chat1 = $this->login_user_in_course_chat($u3, $c1, $chat1);
|
||||
chat_send_chatmessage($u1chat1, 'Ça va ?');
|
||||
chat_send_chatmessage($u2chat1, 'Oui, et toi ?');
|
||||
chat_send_chatmessage($u1chat1, 'Bien merci.');
|
||||
chat_send_chatmessage($u2chat1, 'Pourquoi ils disent omelette "du" fromage ?!');
|
||||
chat_send_chatmessage($u1chat1, 'Aucune idée');
|
||||
chat_send_chatmessage($u3chat1, 'Je ne comprends pas');
|
||||
$this->assert_has_data_in_chat($u1, $chat1);
|
||||
$this->assert_has_data_in_chat($u2, $chat1);
|
||||
$this->assert_has_data_in_chat($u3, $chat1);
|
||||
|
||||
$chat2 = $dg->create_module('chat', ['course' => $c1]);
|
||||
|
||||
$u1chat2 = $this->login_user_in_course_chat($u1, $c1, $chat2);
|
||||
$u2chat2 = $this->login_user_in_course_chat($u2, $c1, $chat2);
|
||||
$u3chat2 = $this->login_user_in_course_chat($u3, $c1, $chat2);
|
||||
chat_send_chatmessage($u1chat2, 'Why do we have a separate chat?');
|
||||
chat_send_chatmessage($u2chat2, 'I have no idea!');
|
||||
chat_send_chatmessage($u3chat2, 'Me either.');
|
||||
$this->assert_has_data_in_chat($u1, $chat2);
|
||||
$this->assert_has_data_in_chat($u2, $chat2);
|
||||
$this->assert_has_data_in_chat($u3, $chat2);
|
||||
|
||||
// Delete user 1 and 2 data from chat 1 context only.
|
||||
$approveduserids = [$u1->id, $u2->id];
|
||||
$approvedlist = new approved_userlist($chat1context, $component, $approveduserids);
|
||||
provider::delete_data_for_users($approvedlist);
|
||||
|
||||
// Ensure correct chat data is deleted.
|
||||
$this->assert_has_no_data_in_chat($u1, $chat1);
|
||||
$this->assert_has_no_data_in_chat($u2, $chat1);
|
||||
$this->assert_has_data_in_chat($u3, $chat1);
|
||||
|
||||
$this->assert_has_data_in_chat($u1, $chat2);
|
||||
$this->assert_has_data_in_chat($u2, $chat2);
|
||||
$this->assert_has_data_in_chat($u3, $chat2);
|
||||
}
|
||||
|
||||
public function test_export_data_for_user() {
|
||||
global $DB;
|
||||
$dg = $this->getDataGenerator();
|
||||
|
Loading…
x
Reference in New Issue
Block a user