mirror of
https://github.com/moodle/moodle.git
synced 2025-03-14 12:40:01 +01:00
MDL-63510 mod_survey: Add support for removal of context users
This issue is a part of the MDL-62560 Epic.
This commit is contained in:
parent
6d6e4b7a51
commit
bd0b6d8693
@ -31,8 +31,10 @@ use context_helper;
|
||||
use context_module;
|
||||
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\helper;
|
||||
use core_privacy\local\request\transform;
|
||||
use core_privacy\local\request\userlist;
|
||||
use core_privacy\local\request\writer;
|
||||
|
||||
require_once($CFG->dirroot . '/mod/survey/lib.php');
|
||||
@ -47,6 +49,7 @@ require_once($CFG->dirroot . '/mod/survey/lib.php');
|
||||
*/
|
||||
class provider implements
|
||||
\core_privacy\local\metadata\provider,
|
||||
\core_privacy\local\request\core_userlist_provider,
|
||||
\core_privacy\local\request\plugin\provider {
|
||||
|
||||
/**
|
||||
@ -113,6 +116,61 @@ 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 = [
|
||||
'survey' => 'survey',
|
||||
'modulelevel' => CONTEXT_MODULE,
|
||||
'contextid' => $context->id,
|
||||
];
|
||||
|
||||
$sql = "
|
||||
SELECT sa.userid
|
||||
FROM {survey} s
|
||||
JOIN {modules} m
|
||||
ON m.name = :survey
|
||||
JOIN {course_modules} cm
|
||||
ON cm.instance = s.id
|
||||
AND cm.module = m.id
|
||||
JOIN {context} ctx
|
||||
ON ctx.instanceid = cm.id
|
||||
AND ctx.contextlevel = :modulelevel
|
||||
JOIN {survey_answers} sa
|
||||
ON sa.survey = s.id
|
||||
WHERE ctx.id = :contextid
|
||||
AND s.template <> 0";
|
||||
|
||||
$userlist->add_from_sql('userid', $sql, $params);
|
||||
|
||||
$sql = "
|
||||
SELECT sy.userid
|
||||
FROM {survey} s
|
||||
JOIN {modules} m
|
||||
ON m.name = :survey
|
||||
JOIN {course_modules} cm
|
||||
ON cm.instance = s.id
|
||||
AND cm.module = m.id
|
||||
JOIN {context} ctx
|
||||
ON ctx.instanceid = cm.id
|
||||
AND ctx.contextlevel = :modulelevel
|
||||
JOIN {survey_analysis} sy
|
||||
ON sy.survey = s.id
|
||||
WHERE ctx.id = :contextid
|
||||
AND s.template <> 0";
|
||||
|
||||
$userlist->add_from_sql('userid', $sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export all user data for the specified user, in the specified contexts.
|
||||
*
|
||||
@ -275,6 +333,44 @@ class provider implements
|
||||
$DB->delete_records_select('survey_analysis', "survey $insql AND userid = :userid", $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();
|
||||
|
||||
if ($context->contextlevel != CONTEXT_MODULE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch the survey ID.
|
||||
$sql = "
|
||||
SELECT s.id
|
||||
FROM {survey} s
|
||||
JOIN {modules} m
|
||||
ON m.name = :survey
|
||||
JOIN {course_modules} cm
|
||||
ON cm.instance = s.id
|
||||
AND cm.module = m.id
|
||||
WHERE cm.id = :cmid";
|
||||
$params = [
|
||||
'survey' => 'survey',
|
||||
'cmid' => $context->instanceid,
|
||||
];
|
||||
$surveyid = $DB->get_field_sql($sql, $params);
|
||||
$userids = $userlist->get_userids();
|
||||
|
||||
// Delete all the things.
|
||||
list($insql, $params) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
|
||||
$params['surveyid'] = $surveyid;
|
||||
|
||||
$DB->delete_records_select('survey_answers', "survey = :surveyid AND userid {$insql}", $params);
|
||||
$DB->delete_records_select('survey_analysis', "survey = :surveyid AND userid {$insql}", $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a survey ID from its context.
|
||||
*
|
||||
|
@ -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_survey\privacy\provider;
|
||||
@ -85,6 +86,59 @@ class mod_survey_privacy_testcase extends provider_testcase {
|
||||
$this->assertTrue(in_array(context_module::instance($cm1c->cmid)->id, $contextids));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for provider::test_get_users_in_context().
|
||||
*/
|
||||
public function test_get_users_in_context() {
|
||||
$dg = $this->getDataGenerator();
|
||||
$component = 'mod_survey';
|
||||
|
||||
$c1 = $dg->create_course();
|
||||
$c2 = $dg->create_course();
|
||||
$cm1a = $dg->create_module('survey', ['template' => 1, 'course' => $c1]);
|
||||
$cm1b = $dg->create_module('survey', ['template' => 2, 'course' => $c1]);
|
||||
$cm2 = $dg->create_module('survey', ['template' => 1, 'course' => $c2]);
|
||||
$cm1acontext = context_module::instance($cm1a->cmid);
|
||||
$cm1bcontext = context_module::instance($cm1b->cmid);
|
||||
$cm2context = context_module::instance($cm2->cmid);
|
||||
|
||||
$u1 = $dg->create_user();
|
||||
$u2 = $dg->create_user();
|
||||
$bothusers = [$u1->id, $u2->id];
|
||||
sort($bothusers);
|
||||
|
||||
$this->create_answer($cm1a->id, 1, $u1->id);
|
||||
$this->create_answer($cm1b->id, 1, $u1->id);
|
||||
$this->create_answer($cm1b->id, 1, $u2->id);
|
||||
$this->create_answer($cm2->id, 1, $u2->id);
|
||||
$this->create_analysis($cm2->id, $u1->id);
|
||||
|
||||
// Cm1a should only contain u1.
|
||||
$userlist = new \core_privacy\local\request\userlist($cm1acontext, $component);
|
||||
provider::get_users_in_context($userlist);
|
||||
|
||||
$this->assertCount(1, $userlist);
|
||||
$this->assertEquals([$u1->id], $userlist->get_userids());
|
||||
|
||||
// Cm1b should contain u1 and u2 (both have answers).
|
||||
$userlist = new \core_privacy\local\request\userlist($cm1bcontext, $component);
|
||||
provider::get_users_in_context($userlist);
|
||||
|
||||
$this->assertCount(2, $userlist);
|
||||
$actual = $userlist->get_userids();
|
||||
sort($actual);
|
||||
$this->assertEquals($bothusers, $actual);
|
||||
|
||||
// Cm2 should contain u1 (analysis) and u2 (answer).
|
||||
$userlist = new \core_privacy\local\request\userlist($cm2context, $component);
|
||||
provider::get_users_in_context($userlist);
|
||||
|
||||
$this->assertCount(2, $userlist);
|
||||
$actual = $userlist->get_userids();
|
||||
sort($actual);
|
||||
$this->assertEquals($bothusers, $actual);
|
||||
}
|
||||
|
||||
public function test_delete_data_for_all_users_in_context() {
|
||||
global $DB;
|
||||
$dg = $this->getDataGenerator();
|
||||
@ -190,6 +244,64 @@ class mod_survey_privacy_testcase extends provider_testcase {
|
||||
$this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1c->id]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for provider::delete_data_for_users().
|
||||
*/
|
||||
public function test_delete_data_for_users() {
|
||||
global $DB;
|
||||
$dg = $this->getDataGenerator();
|
||||
$component = 'mod_survey';
|
||||
|
||||
$c1 = $dg->create_course();
|
||||
$cm1a = $dg->create_module('survey', ['template' => 1, 'course' => $c1]);
|
||||
$cm1b = $dg->create_module('survey', ['template' => 2, 'course' => $c1]);
|
||||
$cm1c = $dg->create_module('survey', ['template' => 2, 'course' => $c1]);
|
||||
$cm1acontext = context_module::instance($cm1a->cmid);
|
||||
$cm1bcontext = context_module::instance($cm1b->cmid);
|
||||
|
||||
$u1 = $dg->create_user();
|
||||
$u2 = $dg->create_user();
|
||||
|
||||
$this->create_answer($cm1a->id, 1, $u1->id);
|
||||
$this->create_answer($cm1a->id, 1, $u2->id);
|
||||
$this->create_analysis($cm1a->id, $u1->id);
|
||||
$this->create_analysis($cm1a->id, $u2->id);
|
||||
$this->create_answer($cm1b->id, 1, $u2->id);
|
||||
$this->create_analysis($cm1b->id, $u1->id);
|
||||
$this->create_answer($cm1c->id, 1, $u1->id);
|
||||
$this->create_analysis($cm1c->id, $u2->id);
|
||||
|
||||
// Confirm data exists before deletion.
|
||||
$this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1a->id]));
|
||||
$this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1c->id]));
|
||||
$this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1a->id]));
|
||||
$this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1b->id]));
|
||||
$this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1a->id]));
|
||||
$this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1b->id]));
|
||||
$this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1a->id]));
|
||||
$this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1c->id]));
|
||||
|
||||
// Ensure only approved user data is deleted.
|
||||
$approveduserids = [$u1->id];
|
||||
$approvedlist = new approved_userlist($cm1acontext, $component, $approveduserids);
|
||||
provider::delete_data_for_users($approvedlist);
|
||||
|
||||
$this->assertFalse($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1a->id]));
|
||||
$this->assertFalse($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1a->id]));
|
||||
$this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1a->id]));
|
||||
$this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1a->id]));
|
||||
|
||||
$approveduserids = [$u1->id, $u2->id];
|
||||
$approvedlist = new approved_userlist($cm1bcontext, $component, $approveduserids);
|
||||
provider::delete_data_for_users($approvedlist);
|
||||
|
||||
$this->assertFalse($DB->record_exists('survey_answers', ['survey' => $cm1b->id]));
|
||||
$this->assertFalse($DB->record_exists('survey_analysis', ['survey' => $cm1b->id]));
|
||||
|
||||
$this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1c->id]));
|
||||
$this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1c->id]));
|
||||
}
|
||||
|
||||
public function test_export_data_for_user() {
|
||||
global $DB;
|
||||
$dg = $this->getDataGenerator();
|
||||
|
Loading…
x
Reference in New Issue
Block a user