mirror of
https://github.com/moodle/moodle.git
synced 2025-01-29 19:50:14 +01:00
MDL-63501 mod_scorm: Add support for removal of context users
This issue is a part of the MDL-62560 Epic.
This commit is contained in:
parent
630a05c2aa
commit
6d6e4b7a51
@ -28,9 +28,11 @@ 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\helper;
|
||||
use core_privacy\local\request\transform;
|
||||
use core_privacy\local\request\userlist;
|
||||
use core_privacy\local\request\writer;
|
||||
|
||||
/**
|
||||
@ -41,6 +43,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 {
|
||||
|
||||
/**
|
||||
@ -103,6 +106,36 @@ 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;
|
||||
}
|
||||
|
||||
$sql = "SELECT ss.userid
|
||||
FROM {%s} ss
|
||||
JOIN {modules} m
|
||||
ON m.name = 'scorm'
|
||||
JOIN {course_modules} cm
|
||||
ON cm.instance = ss.scormid
|
||||
AND cm.module = m.id
|
||||
JOIN {context} ctx
|
||||
ON ctx.instanceid = cm.id
|
||||
AND ctx.contextlevel = :modlevel
|
||||
WHERE ctx.id = :contextid";
|
||||
|
||||
$params = ['modlevel' => CONTEXT_MODULE, 'contextid' => $context->id];
|
||||
|
||||
$userlist->add_from_sql('userid', sprintf($sql, 'scorm_scoes_track'), $params);
|
||||
$userlist->add_from_sql('userid', sprintf($sql, 'scorm_aicc_session'), $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export all user data for the specified user, in the specified contexts.
|
||||
*
|
||||
@ -290,6 +323,40 @@ class provider implements
|
||||
static::delete_data('scorm_aicc_session', $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();
|
||||
|
||||
if (!is_a($context, \context_module::class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare SQL to gather all completed IDs.
|
||||
$userids = $userlist->get_userids();
|
||||
list($insql, $inparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
|
||||
|
||||
$sql = "SELECT ss.id
|
||||
FROM {%s} ss
|
||||
JOIN {modules} m
|
||||
ON m.name = 'scorm'
|
||||
JOIN {course_modules} cm
|
||||
ON cm.instance = ss.scormid
|
||||
AND cm.module = m.id
|
||||
JOIN {context} ctx
|
||||
ON ctx.instanceid = cm.id
|
||||
WHERE ctx.id = :contextid
|
||||
AND ss.userid $insql";
|
||||
$params = array_merge($inparams, ['contextid' => $context->id]);
|
||||
|
||||
static::delete_data('scorm_scoes_track', $sql, $params);
|
||||
static::delete_data('scorm_aicc_session', $sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete data from $tablename with the IDs returned by $sql query.
|
||||
*
|
||||
|
@ -27,6 +27,7 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use mod_scorm\privacy\provider;
|
||||
use core_privacy\local\request\approved_contextlist;
|
||||
use core_privacy\local\request\approved_userlist;
|
||||
use core_privacy\local\request\writer;
|
||||
use core_privacy\tests\provider_testcase;
|
||||
|
||||
@ -68,6 +69,28 @@ class mod_scorm_testcase extends provider_testcase {
|
||||
$this->assertContains($this->context->id, $contextlist->get_contextids());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting the user IDs for the context related to this plugin.
|
||||
*/
|
||||
public function test_get_users_in_context() {
|
||||
$this->resetAfterTest(true);
|
||||
$this->setAdminUser();
|
||||
$this->scorm_setup_test_scenario_data();
|
||||
$component = 'mod_scorm';
|
||||
|
||||
$userlist = new \core_privacy\local\request\userlist($this->context, $component);
|
||||
provider::get_users_in_context($userlist);
|
||||
|
||||
// Students 1 and 2 have attempts in the SCORM context, student 0 does not.
|
||||
$this->assertCount(2, $userlist);
|
||||
|
||||
$expected = [$this->student1->id, $this->student2->id];
|
||||
$actual = $userlist->get_userids();
|
||||
sort($expected);
|
||||
sort($actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that data is exported correctly for this plugin.
|
||||
*/
|
||||
@ -196,9 +219,59 @@ class mod_scorm_testcase extends provider_testcase {
|
||||
$this->assertEquals(2, $count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for provider::delete_data_for_users().
|
||||
*/
|
||||
public function test_delete_data_for_users() {
|
||||
global $DB;
|
||||
$component = 'mod_scorm';
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$this->setAdminUser();
|
||||
$this->scorm_setup_test_scenario_data();
|
||||
|
||||
// Before deletion, we should have 8 entries in the scorm_scoes_track table.
|
||||
$count = $DB->count_records('scorm_scoes_track');
|
||||
$this->assertEquals(8, $count);
|
||||
// Before deletion, we should have 4 entries in the scorm_aicc_session table.
|
||||
$count = $DB->count_records('scorm_aicc_session');
|
||||
$this->assertEquals(4, $count);
|
||||
|
||||
// Delete only student 1's data, retain student 2's data.
|
||||
$approveduserids = [$this->student1->id];
|
||||
$approvedlist = new approved_userlist($this->context, $component, $approveduserids);
|
||||
provider::delete_data_for_users($approvedlist);
|
||||
|
||||
// After deletion, the scorm_scoes_track entries for the first student should have been deleted.
|
||||
$count = $DB->count_records('scorm_scoes_track', ['userid' => $this->student1->id]);
|
||||
$this->assertEquals(0, $count);
|
||||
$count = $DB->count_records('scorm_scoes_track');
|
||||
$this->assertEquals(4, $count);
|
||||
|
||||
// After deletion, the scorm_aicc_session entries for the first student should have been deleted.
|
||||
$count = $DB->count_records('scorm_aicc_session', ['userid' => $this->student1->id]);
|
||||
$this->assertEquals(0, $count);
|
||||
$count = $DB->count_records('scorm_aicc_session');
|
||||
$this->assertEquals(2, $count);
|
||||
|
||||
// Confirm that the SCORM hasn't been removed.
|
||||
$scormcount = $DB->get_records('scorm');
|
||||
$this->assertCount(1, (array) $scormcount);
|
||||
|
||||
// Delete scoes_track for student0 (nothing has to be removed).
|
||||
$approveduserids = [$this->student0->id];
|
||||
$approvedlist = new approved_userlist($this->context, $component, $approveduserids);
|
||||
provider::delete_data_for_users($approvedlist);
|
||||
|
||||
$count = $DB->count_records('scorm_scoes_track');
|
||||
$this->assertEquals(4, $count);
|
||||
$count = $DB->count_records('scorm_aicc_session');
|
||||
$this->assertEquals(2, $count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to setup 3 users and 2 SCORM attempts for student1 and student2.
|
||||
* $this->student0 is always created withot any attempt.
|
||||
* $this->student0 is always created without any attempt.
|
||||
*/
|
||||
protected function scorm_setup_test_scenario_data() {
|
||||
global $DB;
|
||||
|
Loading…
x
Reference in New Issue
Block a user