mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 05:58:34 +01:00
MDL-63622 core_grading: Add support for removal of context users.
Core grading now implements the new core_userlist_provider interface to allow for deletion of specific users in a context.
This commit is contained in:
parent
448bd578d8
commit
980425022b
@ -41,6 +41,8 @@ use \core_privacy\manager;
|
||||
*/
|
||||
class provider implements
|
||||
\core_privacy\local\metadata\provider,
|
||||
\core_privacy\local\request\plugin\provider,
|
||||
\core_privacy\local\request\core_userlist_provider,
|
||||
\core_privacy\local\request\subsystem\provider {
|
||||
|
||||
/**
|
||||
@ -107,6 +109,34 @@ class provider implements
|
||||
return $contextlist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of contexts that contain user information for the specified user.
|
||||
*
|
||||
* @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(\core_privacy\local\request\userlist $userlist) {
|
||||
$context = $userlist->get_context();
|
||||
if ($context->contextlevel != CONTEXT_MODULE) {
|
||||
return;
|
||||
}
|
||||
|
||||
$params = ['contextid' => $context->id];
|
||||
|
||||
$sql = "SELECT d.usercreated, d.usermodified
|
||||
FROM {grading_definitions} d
|
||||
JOIN {grading_areas} a ON a.id = d.areaid
|
||||
WHERE a.contextid = :contextid";
|
||||
$userlist->add_from_sql('usercreated', $sql, $params);
|
||||
$userlist->add_from_sql('usermodified', $sql, $params);
|
||||
|
||||
$sql = "SELECT i.raterid
|
||||
FROM {grading_definitions} d
|
||||
JOIN {grading_areas} a ON a.id = d.areaid
|
||||
JOIN {grading_instances} i ON i.definitionid = d.id
|
||||
WHERE a.contextid = :contextid";
|
||||
$userlist->add_from_sql('raterid', $sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export all user data for the specified user, in the specified contexts.
|
||||
*
|
||||
@ -171,12 +201,27 @@ class provider implements
|
||||
* @param int|null $itemid An optional item ID to refine the deletion.
|
||||
*/
|
||||
public static function delete_instance_data(\context $context, int $itemid = null) {
|
||||
if (is_null($itemid)) {
|
||||
self::delete_data_for_instances($context);
|
||||
} else {
|
||||
self::delete_data_for_instances($context, [$itemid]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all user data related to a context and possibly itemids.
|
||||
*
|
||||
* @param \context $context The context to delete on.
|
||||
* @param array $itemids An optional list of item IDs to refine the deletion.
|
||||
*/
|
||||
public static function delete_data_for_instances(\context $context, array $itemids = []) {
|
||||
global $DB;
|
||||
$itemsql = '';
|
||||
$params = ['contextid' => $context->id];
|
||||
if (isset($itemid)) {
|
||||
$params['itemid'] = $itemid;
|
||||
$itemsql = 'AND gi.itemid = :itemid';
|
||||
if (!empty($itemids)) {
|
||||
list($itemsql, $itemparams) = $DB->get_in_or_equal($itemids, SQL_PARAMS_NAMED);
|
||||
$params = array_merge($params, $itemparams);
|
||||
$itemsql = "AND itemid $itemsql";
|
||||
}
|
||||
$sql = "SELECT gi.id AS instanceid, gd.id, gd.method
|
||||
FROM {grading_definitions} gd
|
||||
@ -359,4 +404,13 @@ class provider implements
|
||||
);
|
||||
// End of section to be removed for final deprecation.
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(\core_privacy\local\request\approved_userlist $userlist) {
|
||||
// The only information left to be deleted here is the grading definitions. Currently we are not deleting these.
|
||||
}
|
||||
}
|
||||
|
@ -106,28 +106,13 @@ class gradingform_guide_privacy_testcase extends provider_testcase {
|
||||
);
|
||||
$guide->create_guide();
|
||||
|
||||
$controller = $guide->manager->get_controller('guide');
|
||||
// In the situation of mod_assign this would be the id from assign_grades.
|
||||
$itemid = 1;
|
||||
$instance = $controller->create_instance($user->id, $itemid);
|
||||
// I need the ids for the criteria and there doesn't seem to be a nice method to get it.
|
||||
$criteria = $DB->get_records('gradingform_guide_criteria');
|
||||
$data = ['criteria' => []];
|
||||
foreach ($criteria as $key => $value) {
|
||||
if ($value->shortname == 'Spelling mistakes') {
|
||||
$data['criteria'][$key]['remark'] = 'This user made several mistakes.';
|
||||
$data['criteria'][$key]['remarkformat'] = 0;
|
||||
$data['criteria'][$key]['score'] = 5;
|
||||
} else {
|
||||
$data['criteria'][$key]['remark'] = 'This user has two pictures.';
|
||||
$data['criteria'][$key]['remarkformat'] = 0;
|
||||
$data['criteria'][$key]['score'] = 10;
|
||||
}
|
||||
}
|
||||
$data['itemid'] = $itemid;
|
||||
|
||||
// Update this instance with data.
|
||||
$instance->update($data);
|
||||
$gradedata = [
|
||||
['remark' => 'This user made several mistakes.', 'score' => 5],
|
||||
['remark' => 'This user has two pictures.', 'score' => 10]
|
||||
];
|
||||
$instance = $guide->grade_item($user->id, $itemid, $gradedata);
|
||||
$instanceid = $instance->get_data('id');
|
||||
|
||||
// Let's try the method we are testing.
|
||||
|
44
grade/grading/tests/fixtures/marking_guide.php
vendored
44
grade/grading/tests/fixtures/marking_guide.php
vendored
@ -45,6 +45,8 @@ class test_guide {
|
||||
protected $criterionid = 0;
|
||||
/** @var integer $sortorder The current id for the sort order. */
|
||||
protected $sortorder = 0;
|
||||
/** @var gradingform_controller The grading form controller. */
|
||||
protected $controller;
|
||||
|
||||
/** @var grading_manager $manager The grading manager to handle creating the real marking guide. */
|
||||
public $manager;
|
||||
@ -92,8 +94,8 @@ class test_guide {
|
||||
'status' => 20
|
||||
];
|
||||
|
||||
$controller = $this->manager->get_controller('guide');
|
||||
$controller->update_definition($data);
|
||||
$this->controller = $this->manager->get_controller('guide');
|
||||
$this->controller->update_definition($data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -115,4 +117,42 @@ class test_guide {
|
||||
'maxscore' => $maxscore
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the grade for the item provided.
|
||||
* Keep the gradeinfo array in the same order as the definition of the criteria.
|
||||
* The array should be [['remark' => remark, 'score' => intvalue],['remark' => remark, 'score' => intvalue]]
|
||||
* for a guide that has two criteria.
|
||||
*
|
||||
* @param int $userid The user we are updating.
|
||||
* @param int $itemid The itemid that the grade will be for
|
||||
* @param array $gradeinfo Comments and grades for the grade.
|
||||
* @return gradingform_guide_instance The created instance associated with the grade created.
|
||||
*/
|
||||
public function grade_item(int $userid, int $itemid, array $gradeinfo) : gradingform_guide_instance {
|
||||
global $DB;
|
||||
|
||||
if (!isset($this->controller)) {
|
||||
throw new Exception("Please call create_guide before calling this method", 1);
|
||||
}
|
||||
|
||||
$instance = $this->controller->create_instance($userid, $itemid);
|
||||
|
||||
// I need the ids for the criteria and there doesn't seem to be a nice method to get it.
|
||||
$criteria = $DB->get_records('gradingform_guide_criteria');
|
||||
$data = ['criteria' => []];
|
||||
$i = 0;
|
||||
// The sort order should keep everything here in order.
|
||||
foreach ($criteria as $key => $value) {
|
||||
$data['criteria'][$key]['remark'] = $gradeinfo[$i]['remark'];
|
||||
$data['criteria'][$key]['remarkformat'] = 0;
|
||||
$data['criteria'][$key]['score'] = $gradeinfo[$i]['score'];
|
||||
$i++;
|
||||
}
|
||||
$data['itemid'] = $itemid;
|
||||
|
||||
// Update this instance with data.
|
||||
$instance->update($data);
|
||||
return $instance;
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +87,19 @@ class core_grading_privacy_testcase extends provider_testcase {
|
||||
$this->assertCount(0, $contextlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test retrieval of user ids in a given context.
|
||||
*/
|
||||
public function test_get_users_in_context() {
|
||||
$this->resetAfterTest();
|
||||
$this->grading_setup_test_scenario_data();
|
||||
// Instance two has one user who created the definitions and another who modified it.
|
||||
$userlist = new \core_privacy\local\request\userlist($this->instancecontext2, 'core_grading');
|
||||
provider::get_users_in_context($userlist);
|
||||
// Check that we get both.
|
||||
$this->assertCount(2, $userlist->get_userids());
|
||||
}
|
||||
|
||||
/**
|
||||
* Export for a user with no grading definitions created or modified will not have any data exported.
|
||||
*/
|
||||
@ -274,32 +287,16 @@ class core_grading_privacy_testcase extends provider_testcase {
|
||||
);
|
||||
$guide->create_guide();
|
||||
|
||||
$controller = $guide->manager->get_controller('guide');
|
||||
// In the situation of mod_assign this would be the id from assign_grades.
|
||||
$itemid = 1;
|
||||
$instance = $controller->create_instance($user->id, $itemid);
|
||||
// I need the ids for the criteria and there doesn't seem to be a nice method to get it.
|
||||
$criteria = $DB->get_records('gradingform_guide_criteria');
|
||||
$data = ['criteria' => []];
|
||||
foreach ($criteria as $key => $value) {
|
||||
if ($value->shortname == 'Spelling mistakes') {
|
||||
$data['criteria'][$key]['remark'] = 'This user made several mistakes.';
|
||||
$data['criteria'][$key]['remarkformat'] = 0;
|
||||
$data['criteria'][$key]['score'] = 5;
|
||||
} else {
|
||||
$data['criteria'][$key]['remark'] = 'This user has two pictures.';
|
||||
$data['criteria'][$key]['remarkformat'] = 0;
|
||||
$data['criteria'][$key]['score'] = 10;
|
||||
}
|
||||
}
|
||||
$data['itemid'] = $itemid;
|
||||
|
||||
// Update this instance with data.
|
||||
$instance->update($data);
|
||||
$instanceid = $instance->get_data('id');
|
||||
$gradedata = [
|
||||
['remark' => 'This user made several mistakes.', 'score' => 5],
|
||||
['remark' => 'This user has two pictures.', 'score' => 10]
|
||||
];
|
||||
$instance = $guide->grade_item($user->id, $itemid, $gradedata);
|
||||
|
||||
provider::export_item_data($modulecontext, $itemid, ['Test']);
|
||||
$data = (array) writer::with_context($modulecontext)->get_data(['Test', 'Marking guide', $instanceid]);
|
||||
$data = (array) writer::with_context($modulecontext)->get_data(['Test', 'Marking guide', $instance->get_data('id')]);
|
||||
$this->assertCount(2, $data);
|
||||
$this->assertEquals('This user made several mistakes.', $data['Spelling mistakes']->remark);
|
||||
$this->assertEquals(5, $data['Spelling mistakes']->score);
|
||||
@ -335,49 +332,20 @@ class core_grading_privacy_testcase extends provider_testcase {
|
||||
);
|
||||
$guide->create_guide();
|
||||
|
||||
$controller = $guide->manager->get_controller('guide');
|
||||
// In the situation of mod_assign this would be the id from assign_grades.
|
||||
$itemid = 1;
|
||||
$instance = $controller->create_instance($user->id, $itemid);
|
||||
// I need the ids for the criteria and there doesn't seem to be a nice method to get it.
|
||||
$criteria = $DB->get_records('gradingform_guide_criteria');
|
||||
$data = ['criteria' => []];
|
||||
foreach ($criteria as $key => $value) {
|
||||
if ($value->shortname == 'Spelling mistakes') {
|
||||
$data['criteria'][$key]['remark'] = 'This user made several mistakes.';
|
||||
$data['criteria'][$key]['remarkformat'] = 0;
|
||||
$data['criteria'][$key]['score'] = 5;
|
||||
} else {
|
||||
$data['criteria'][$key]['remark'] = 'This user has two pictures.';
|
||||
$data['criteria'][$key]['remarkformat'] = 0;
|
||||
$data['criteria'][$key]['score'] = 10;
|
||||
}
|
||||
}
|
||||
$data['itemid'] = $itemid;
|
||||
|
||||
// Update this instance with data.
|
||||
$instance->update($data);
|
||||
$gradedata = [
|
||||
['remark' => 'This user made several mistakes.', 'score' => 5],
|
||||
['remark' => 'This user has two pictures.', 'score' => 10]
|
||||
];
|
||||
$instance = $guide->grade_item($user->id, $itemid, $gradedata);
|
||||
|
||||
$itemid = 2;
|
||||
$instance = $controller->create_instance($user->id, $itemid);
|
||||
// I need the ids for the criteria and there doesn't seem to be a nice method to get it.
|
||||
$criteria = $DB->get_records('gradingform_guide_criteria');
|
||||
$data = ['criteria' => []];
|
||||
foreach ($criteria as $key => $value) {
|
||||
if ($value->shortname == 'Spelling mistakes') {
|
||||
$data['criteria'][$key]['remark'] = 'This user made no mistakes.';
|
||||
$data['criteria'][$key]['remarkformat'] = 0;
|
||||
$data['criteria'][$key]['score'] = 25;
|
||||
} else {
|
||||
$data['criteria'][$key]['remark'] = 'This user has one pictures.';
|
||||
$data['criteria'][$key]['remarkformat'] = 0;
|
||||
$data['criteria'][$key]['score'] = 5;
|
||||
}
|
||||
}
|
||||
$data['itemid'] = $itemid;
|
||||
|
||||
// Update this instance with data.
|
||||
$instance->update($data);
|
||||
$gradedata = [
|
||||
['remark' => 'This user made no mistakes.', 'score' => 25],
|
||||
['remark' => 'This user has one picture.', 'score' => 5]
|
||||
];
|
||||
$instance = $guide->grade_item($user->id, $itemid, $gradedata);
|
||||
|
||||
// Check how many records we have in the fillings table.
|
||||
$records = $DB->get_records('gradingform_guide_fillings');
|
||||
@ -395,6 +363,72 @@ class core_grading_privacy_testcase extends provider_testcase {
|
||||
$this->assertEmpty($records);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the deletion of multiple instances at once.
|
||||
*/
|
||||
public function test_delete_data_for_instances() {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$module = $this->getDataGenerator()->create_module('assign', ['course' => $course]);
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
$user3 = $this->getDataGenerator()->create_user();
|
||||
|
||||
$this->setUser($user1);
|
||||
|
||||
$modulecontext = context_module::instance($module->cmid);
|
||||
$guide = new test_guide($modulecontext, 'testrubrib', 'Description text');
|
||||
$guide->add_criteria(
|
||||
'Spelling mistakes',
|
||||
'Full marks will be given for no spelling mistakes.',
|
||||
'Deduct 5 points per spelling mistake made.',
|
||||
25
|
||||
);
|
||||
$guide->add_criteria(
|
||||
'Pictures',
|
||||
'Full marks will be given for including 3 pictures.',
|
||||
'Give 5 points for each picture present',
|
||||
15
|
||||
);
|
||||
$guide->create_guide();
|
||||
|
||||
// In the situation of mod_assign this would be the id from assign_grades.
|
||||
$itemid1 = 1;
|
||||
$gradedata = [
|
||||
['remark' => 'This user made several mistakes.', 'score' => 5],
|
||||
['remark' => 'This user has two pictures.', 'score' => 10]
|
||||
];
|
||||
$instance1 = $guide->grade_item($user1->id, $itemid1, $gradedata);
|
||||
|
||||
$itemid2 = 2;
|
||||
$gradedata = [
|
||||
['remark' => 'This user made a couple of mistakes.', 'score' => 15],
|
||||
['remark' => 'This user has one picture.', 'score' => 10]
|
||||
];
|
||||
$instance2 = $guide->grade_item($user2->id, $itemid2, $gradedata);
|
||||
|
||||
$itemid3 = 3;
|
||||
$gradedata = [
|
||||
['remark' => 'This user made one mistakes.', 'score' => 20],
|
||||
['remark' => 'This user has one picture.', 'score' => 10]
|
||||
];
|
||||
$instance3 = $guide->grade_item($user3->id, $itemid3, $gradedata);
|
||||
|
||||
$records = $DB->get_records('gradingform_guide_fillings');
|
||||
$this->assertCount(6, $records);
|
||||
|
||||
// Delete all user data for items 1 and 3.
|
||||
provider::delete_data_for_instances($modulecontext, [$itemid1, $itemid3]);
|
||||
$records = $DB->get_records('gradingform_guide_fillings');
|
||||
$this->assertCount(2, $records);
|
||||
$instanceid = $instance2->get_data('id');
|
||||
// The instance id should match for all remaining records.
|
||||
foreach ($records as $record) {
|
||||
$this->assertEquals($instanceid, $record->instanceid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to setup the environment.
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user