mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 05:58:34 +01:00
MDL-63531 mod_assign: Update mod assign to use new interface.
This introduces a new interface for assign sub-plugins and updates the mod_assign provider to implement the new general interface for deleting data for users in a context.
This commit is contained in:
parent
980425022b
commit
b96e7fa6b2
@ -48,6 +48,15 @@ class assign_plugin_request_data {
|
|||||||
/** @var object If set then only export data related directly to this user. */
|
/** @var object If set then only export data related directly to this user. */
|
||||||
protected $user;
|
protected $user;
|
||||||
|
|
||||||
|
/** @var array The user IDs of the users that will be affected. */
|
||||||
|
protected $userids;
|
||||||
|
|
||||||
|
/** @var array The submissions related to the users added. */
|
||||||
|
protected $submissions = [];
|
||||||
|
|
||||||
|
/** @var array The grades related to the users added. */
|
||||||
|
protected $grades = [];
|
||||||
|
|
||||||
/** @var assign The assign object */
|
/** @var assign The assign object */
|
||||||
protected $assign;
|
protected $assign;
|
||||||
|
|
||||||
@ -69,6 +78,16 @@ class assign_plugin_request_data {
|
|||||||
$this->assign = $assign;
|
$this->assign = $assign;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method for adding an array of user IDs. This will do a query to populate the submissions and grades
|
||||||
|
* for these users.
|
||||||
|
*
|
||||||
|
* @param array $userids User IDs to do something with.
|
||||||
|
*/
|
||||||
|
public function set_userids(array $userids) {
|
||||||
|
$this->userids = $userids;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getter for this attribute.
|
* Getter for this attribute.
|
||||||
*
|
*
|
||||||
@ -113,4 +132,75 @@ class assign_plugin_request_data {
|
|||||||
public function get_assign() {
|
public function get_assign() {
|
||||||
return $this->assign;
|
return $this->assign;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A method to conveniently fetch the assign id.
|
||||||
|
*
|
||||||
|
* @return int The assign id.
|
||||||
|
*/
|
||||||
|
public function get_assignid() {
|
||||||
|
return $this->assign->get_instance()->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the user IDs
|
||||||
|
*
|
||||||
|
* @return array User IDs
|
||||||
|
*/
|
||||||
|
public function get_userids() {
|
||||||
|
return $this->userids;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all of the submission IDs
|
||||||
|
*
|
||||||
|
* @return array submission IDs
|
||||||
|
*/
|
||||||
|
public function get_submissionids() {
|
||||||
|
return array_keys($this->submissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the submissions related to the user IDs
|
||||||
|
*
|
||||||
|
* @return array User submissions.
|
||||||
|
*/
|
||||||
|
public function get_submissions() {
|
||||||
|
return $this->submissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the grade IDs related to the user IDs
|
||||||
|
*
|
||||||
|
* @return array User grade IDs.
|
||||||
|
*/
|
||||||
|
public function get_gradeids() {
|
||||||
|
return array_keys($this->grades);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the grades related to the user IDs
|
||||||
|
*
|
||||||
|
* @return array User grades.
|
||||||
|
*/
|
||||||
|
public function get_grades() {
|
||||||
|
return $this->grades;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all of the submissions and grades related to the User IDs provided. Use get_grades, get_submissions etc to
|
||||||
|
* retrieve this information.
|
||||||
|
*/
|
||||||
|
public function populate_submissions_and_grades() {
|
||||||
|
global $DB;
|
||||||
|
|
||||||
|
if (empty($this->get_userids())) {
|
||||||
|
throw new \coding_exception('Please use set_userids() before calling this method.');
|
||||||
|
}
|
||||||
|
|
||||||
|
list($sql, $params) = $DB->get_in_or_equal($this->get_userids(), SQL_PARAMS_NAMED);
|
||||||
|
$params['assign'] = $this->get_assign()->get_instance()->id;
|
||||||
|
$this->submissions = $DB->get_records_select('assign_submission', "assignment = :assign AND userid $sql", $params);
|
||||||
|
$this->grades = $DB->get_records_select('assign_grades', "assignment = :assign AND userid $sql", $params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,14 +29,13 @@ defined('MOODLE_INTERNAL') || die();
|
|||||||
require_once($CFG->dirroot . '/mod/assign/locallib.php');
|
require_once($CFG->dirroot . '/mod/assign/locallib.php');
|
||||||
|
|
||||||
use \core_privacy\local\metadata\collection;
|
use \core_privacy\local\metadata\collection;
|
||||||
use \core_privacy\local\metadata\provider as metadataprovider;
|
|
||||||
use \core_privacy\local\request\contextlist;
|
use \core_privacy\local\request\contextlist;
|
||||||
use \core_privacy\local\request\plugin\provider as pluginprovider;
|
|
||||||
use \core_privacy\local\request\user_preference_provider as preference_provider;
|
|
||||||
use \core_privacy\local\request\writer;
|
use \core_privacy\local\request\writer;
|
||||||
use \core_privacy\local\request\approved_contextlist;
|
use \core_privacy\local\request\approved_contextlist;
|
||||||
use \core_privacy\local\request\transform;
|
use \core_privacy\local\request\transform;
|
||||||
use \core_privacy\local\request\helper;
|
use \core_privacy\local\request\helper;
|
||||||
|
use \core_privacy\local\request\userlist;
|
||||||
|
use \core_privacy\local\request\approved_userlist;
|
||||||
use \core_privacy\manager;
|
use \core_privacy\manager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,11 +45,21 @@ use \core_privacy\manager;
|
|||||||
* @copyright 2018 Adrian Greeve <adrian@moodle.com>
|
* @copyright 2018 Adrian Greeve <adrian@moodle.com>
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
*/
|
*/
|
||||||
class provider implements metadataprovider, pluginprovider, preference_provider {
|
class provider implements
|
||||||
|
\core_privacy\local\metadata\provider,
|
||||||
|
\core_privacy\local\request\plugin\provider,
|
||||||
|
\core_privacy\local\request\user_preference_provider,
|
||||||
|
\core_privacy\local\request\core_userlist_provider {
|
||||||
|
|
||||||
/** Interface for all assign submission sub-plugins. */
|
/** Interface for all assign submission sub-plugins. */
|
||||||
const ASSIGNSUBMISSION_INTERFACE = 'mod_assign\privacy\assignsubmission_provider';
|
const ASSIGNSUBMISSION_INTERFACE = 'mod_assign\privacy\assignsubmission_provider';
|
||||||
|
|
||||||
|
/** Interface for all assign submission sub-plugins. This allows for deletion of users with a context. */
|
||||||
|
const ASSIGNSUBMISSION_USER_INTERFACE = 'mod_assign\privacy\assignsubmission_user_provider';
|
||||||
|
|
||||||
|
/** Interface for all assign feedback sub-plugins. This allows for deletion of users with a context. */
|
||||||
|
const ASSIGNFEEDBACK_USER_INTERFACE = 'mod_assign\privacy\assignfeedback_user_provider';
|
||||||
|
|
||||||
/** Interface for all assign feedback sub-plugins. */
|
/** Interface for all assign feedback sub-plugins. */
|
||||||
const ASSIGNFEEDBACK_INTERFACE = 'mod_assign\privacy\assignfeedback_provider';
|
const ASSIGNFEEDBACK_INTERFACE = 'mod_assign\privacy\assignfeedback_provider';
|
||||||
|
|
||||||
@ -192,6 +201,76 @@ class provider implements metadataprovider, pluginprovider, preference_provider
|
|||||||
return $contextlist;
|
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(userlist $userlist) {
|
||||||
|
|
||||||
|
$context = $userlist->get_context();
|
||||||
|
if ($context->contextlevel != CONTEXT_MODULE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$params = [
|
||||||
|
'modulename' => 'assign',
|
||||||
|
'contextid' => $context->id,
|
||||||
|
'contextlevel' => CONTEXT_MODULE
|
||||||
|
];
|
||||||
|
|
||||||
|
$sql = "SELECT g.userid, g.grader
|
||||||
|
FROM {context} ctx
|
||||||
|
JOIN {course_modules} cm ON cm.id = ctx.instanceid
|
||||||
|
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
|
||||||
|
JOIN {assign} a ON a.id = cm.instance
|
||||||
|
JOIN {assign_grades} g ON a.id = g.assignment
|
||||||
|
WHERE ctx.id = :contextid AND ctx.contextlevel = :contextlevel";
|
||||||
|
$userlist->add_from_sql('userid', $sql, $params);
|
||||||
|
$userlist->add_from_sql('grader', $sql, $params);
|
||||||
|
|
||||||
|
$sql = "SELECT o.userid
|
||||||
|
FROM {context} ctx
|
||||||
|
JOIN {course_modules} cm ON cm.id = ctx.instanceid
|
||||||
|
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
|
||||||
|
JOIN {assign} a ON a.id = cm.instance
|
||||||
|
JOIN {assign_overrides} o ON a.id = o.assignid
|
||||||
|
WHERE ctx.id = :contextid AND ctx.contextlevel = :contextlevel";
|
||||||
|
$userlist->add_from_sql('userid', $sql, $params);
|
||||||
|
|
||||||
|
$sql = "SELECT s.userid
|
||||||
|
FROM {context} ctx
|
||||||
|
JOIN {course_modules} cm ON cm.id = ctx.instanceid
|
||||||
|
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
|
||||||
|
JOIN {assign} a ON a.id = cm.instance
|
||||||
|
JOIN {assign_submission} s ON a.id = s.assignment
|
||||||
|
WHERE ctx.id = :contextid AND ctx.contextlevel = :contextlevel";
|
||||||
|
$userlist->add_from_sql('userid', $sql, $params);
|
||||||
|
|
||||||
|
$sql = "SELECT uf.userid
|
||||||
|
FROM {context} ctx
|
||||||
|
JOIN {course_modules} cm ON cm.id = ctx.instanceid
|
||||||
|
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
|
||||||
|
JOIN {assign} a ON a.id = cm.instance
|
||||||
|
JOIN {assign_user_flags} uf ON a.id = uf.assignment
|
||||||
|
WHERE ctx.id = :contextid AND ctx.contextlevel = :contextlevel";
|
||||||
|
$userlist->add_from_sql('userid', $sql, $params);
|
||||||
|
|
||||||
|
$sql = "SELECT um.userid
|
||||||
|
FROM {context} ctx
|
||||||
|
JOIN {course_modules} cm ON cm.id = ctx.instanceid
|
||||||
|
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
|
||||||
|
JOIN {assign} a ON a.id = cm.instance
|
||||||
|
JOIN {assign_user_mapping} um ON a.id = um.assignment
|
||||||
|
WHERE ctx.id = :contextid AND ctx.contextlevel = :contextlevel";
|
||||||
|
$userlist->add_from_sql('userid', $sql, $params);
|
||||||
|
|
||||||
|
manager::plugintype_class_callback('assignsubmission', self::ASSIGNSUBMISSION_USER_INTERFACE,
|
||||||
|
'get_userids_from_context', [$userlist]);
|
||||||
|
manager::plugintype_class_callback('assignfeedback', self::ASSIGNFEEDBACK_USER_INTERFACE,
|
||||||
|
'get_userids_from_context', [$userlist]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write out the user data filtered by contexts.
|
* Write out the user data filtered by contexts.
|
||||||
*
|
*
|
||||||
@ -265,7 +344,7 @@ class provider implements metadataprovider, pluginprovider, preference_provider
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Time to roll my own method for deleting overrides.
|
// Time to roll my own method for deleting overrides.
|
||||||
static::delete_user_overrides($assign);
|
static::delete_overrides_for_users($assign);
|
||||||
$DB->delete_records('assign_submission', ['assignment' => $assign->get_instance()->id]);
|
$DB->delete_records('assign_submission', ['assignment' => $assign->get_instance()->id]);
|
||||||
$DB->delete_records('assign_user_flags', ['assignment' => $assign->get_instance()->id]);
|
$DB->delete_records('assign_user_flags', ['assignment' => $assign->get_instance()->id]);
|
||||||
$DB->delete_records('assign_user_mapping', ['assignment' => $assign->get_instance()->id]);
|
$DB->delete_records('assign_user_mapping', ['assignment' => $assign->get_instance()->id]);
|
||||||
@ -311,7 +390,7 @@ class provider implements metadataprovider, pluginprovider, preference_provider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static::delete_user_overrides($assign, $user);
|
static::delete_overrides_for_users($assign, [$user->id]);
|
||||||
$DB->delete_records('assign_user_flags', ['assignment' => $assignid, 'userid' => $user->id]);
|
$DB->delete_records('assign_user_flags', ['assignment' => $assignid, 'userid' => $user->id]);
|
||||||
$DB->delete_records('assign_user_mapping', ['assignment' => $assignid, 'userid' => $user->id]);
|
$DB->delete_records('assign_user_mapping', ['assignment' => $assignid, 'userid' => $user->id]);
|
||||||
$DB->delete_records('assign_grades', ['assignment' => $assignid, 'userid' => $user->id]);
|
$DB->delete_records('assign_grades', ['assignment' => $assignid, 'userid' => $user->id]);
|
||||||
@ -320,32 +399,87 @@ class provider implements metadataprovider, pluginprovider, preference_provider
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes assignment overrides.
|
* Delete multiple users within a single context.
|
||||||
*
|
*
|
||||||
* @param \assign $assign The assignment object
|
* @param approved_userlist $userlist The approved context and user information to delete information for.
|
||||||
* @param \stdClass $user The user object if we are deleting only the overrides for one user.
|
|
||||||
*/
|
*/
|
||||||
protected static function delete_user_overrides(\assign $assign, \stdClass $user = null) {
|
public static function delete_data_for_users(approved_userlist $userlist) {
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
|
$context = $userlist->get_context();
|
||||||
|
if ($context->contextlevel != CONTEXT_MODULE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$userids = $userlist->get_userids();
|
||||||
|
|
||||||
|
$assign = new \assign($context, null, null);
|
||||||
$assignid = $assign->get_instance()->id;
|
$assignid = $assign->get_instance()->id;
|
||||||
$params = (isset($user)) ? ['assignid' => $assignid, 'userid' => $user->id] : ['assignid' => $assignid];
|
$requestdata = new assign_plugin_request_data($context, $assign);
|
||||||
|
$requestdata->set_userids($userids);
|
||||||
|
$requestdata->populate_submissions_and_grades();
|
||||||
|
manager::plugintype_class_callback('assignsubmission', self::ASSIGNSUBMISSION_USER_INTERFACE, 'delete_submissions',
|
||||||
|
[$requestdata]);
|
||||||
|
manager::plugintype_class_callback('assignfeedback', self::ASSIGNFEEDBACK_USER_INTERFACE, 'delete_feedback_for_grades',
|
||||||
|
[$requestdata]);
|
||||||
|
|
||||||
$overrides = $DB->get_records('assign_overrides', $params);
|
// Update this function to delete advanced grading information.
|
||||||
if (!empty($overrides)) {
|
$gradingmanager = get_grading_manager($context, 'mod_assign', 'submissions');
|
||||||
foreach ($overrides as $override) {
|
$controller = $gradingmanager->get_active_controller();
|
||||||
|
if (isset($controller)) {
|
||||||
// First delete calendar events associated with this override.
|
$gradeids = $requestdata->get_gradeids();
|
||||||
$conditions = ['modulename' => 'assign', 'instance' => $assignid];
|
// Careful here, if no gradeids are provided then all data is deleted for the context.
|
||||||
if (isset($user)) {
|
if (!empty($gradeids)) {
|
||||||
$conditions['userid'] = $user->id;
|
\core_grading\privacy\provider::delete_data_for_instances($context, $gradeids);
|
||||||
}
|
|
||||||
$DB->delete_records('event', $conditions);
|
|
||||||
|
|
||||||
// Next delete the overrides.
|
|
||||||
$DB->delete_records('assign_overrides', ['id' => $override->id]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static::delete_overrides_for_users($assign, $userids);
|
||||||
|
list($sql, $params) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
|
||||||
|
$params['assignment'] = $assignid;
|
||||||
|
$DB->delete_records_select('assign_user_flags', "assignment = :assignment AND userid $sql", $params);
|
||||||
|
$DB->delete_records_select('assign_user_mapping', "assignment = :assignment AND userid $sql", $params);
|
||||||
|
$DB->delete_records_select('assign_grades', "assignment = :assignment AND userid $sql", $params);
|
||||||
|
$DB->delete_records_select('assign_submission', "assignment = :assignment AND userid $sql", $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes assignment overrides in bulk
|
||||||
|
*
|
||||||
|
* @param \assign $assign The assignment object
|
||||||
|
* @param array $userids An array of user IDs
|
||||||
|
*/
|
||||||
|
protected static function delete_overrides_for_users(\assign $assign, array $userids = []) {
|
||||||
|
global $DB;
|
||||||
|
$assignid = $assign->get_instance()->id;
|
||||||
|
|
||||||
|
$usersql = '';
|
||||||
|
$params = ['assignid' => $assignid];
|
||||||
|
if (!empty($userids)) {
|
||||||
|
list($usersql, $userparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
|
||||||
|
$params = array_merge($params, $userparams);
|
||||||
|
$overrides = $DB->get_records_select('assign_overrides', "assignid = :assignid AND userid $usersql", $params);
|
||||||
|
} else {
|
||||||
|
$overrides = $DB->get_records('assign_overrides', $params);
|
||||||
|
}
|
||||||
|
if (!empty($overrides)) {
|
||||||
|
$params = ['modulename' => 'assign', 'instance' => $assignid];
|
||||||
|
if (!empty($userids)) {
|
||||||
|
$params = array_merge($params, $userparams);
|
||||||
|
$DB->delete_records_select('event', "modulename = :modulename AND instance = :instance AND userid $usersql",
|
||||||
|
$params);
|
||||||
|
// Setting up for the next query.
|
||||||
|
$params = $userparams;
|
||||||
|
$usersql = "AND userid $usersql";
|
||||||
|
} else {
|
||||||
|
$DB->delete_records('event', $params);
|
||||||
|
// Setting up for the next query.
|
||||||
|
$params = [];
|
||||||
|
}
|
||||||
|
list($overridesql, $overrideparams) = $DB->get_in_or_equal(array_keys($overrides), SQL_PARAMS_NAMED);
|
||||||
|
$params = array_merge($params, $overrideparams);
|
||||||
|
$DB->delete_records_select('assign_overrides', "id $overridesql $usersql", $params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -148,6 +148,95 @@ class mod_assign_privacy_testcase extends provider_testcase {
|
|||||||
$this->assertEmpty(array_diff($usercontextids, $contextlist->get_contextids()));
|
$this->assertEmpty(array_diff($usercontextids, $contextlist->get_contextids()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test returning a list of user IDs related to a context (assign).
|
||||||
|
*/
|
||||||
|
public function test_get_users_in_context() {
|
||||||
|
global $DB;
|
||||||
|
|
||||||
|
$this->resetAfterTest();
|
||||||
|
|
||||||
|
$course = $this->getDataGenerator()->create_course();
|
||||||
|
|
||||||
|
// Only made a comment on a submission.
|
||||||
|
$user1 = $this->getDataGenerator()->create_user();
|
||||||
|
// User 2 only has information about an activity override.
|
||||||
|
$user2 = $this->getDataGenerator()->create_user();
|
||||||
|
// User 3 made a submission.
|
||||||
|
$user3 = $this->getDataGenerator()->create_user();
|
||||||
|
// User 4 makes a submission and it is marked by the teacher.
|
||||||
|
$user4 = $this->getDataGenerator()->create_user();
|
||||||
|
// Grading and providing feedback as a teacher.
|
||||||
|
$user5 = $this->getDataGenerator()->create_user();
|
||||||
|
// This user has no entries and should not show up.
|
||||||
|
$user6 = $this->getDataGenerator()->create_user();
|
||||||
|
|
||||||
|
$this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
|
||||||
|
$this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
|
||||||
|
$this->getDataGenerator()->enrol_user($user3->id, $course->id, 'student');
|
||||||
|
$this->getDataGenerator()->enrol_user($user4->id, $course->id, 'student');
|
||||||
|
$this->getDataGenerator()->enrol_user($user5->id, $course->id, 'editingteacher');
|
||||||
|
$this->getDataGenerator()->enrol_user($user6->id, $course->id, 'student');
|
||||||
|
|
||||||
|
$assign1 = $this->create_instance(['course' => $course,
|
||||||
|
'assignsubmission_onlinetext_enabled' => true,
|
||||||
|
'assignfeedback_comments_enabled' => true]);
|
||||||
|
$assign2 = $this->create_instance(['course' => $course]);
|
||||||
|
|
||||||
|
$context = $assign1->get_context();
|
||||||
|
|
||||||
|
// Jam an entry in the comments table for user 1.
|
||||||
|
$comment = (object) [
|
||||||
|
'contextid' => $context->id,
|
||||||
|
'component' => 'assignsubmission_comments',
|
||||||
|
'commentarea' => 'submission_comments',
|
||||||
|
'itemid' => 5,
|
||||||
|
'content' => 'A comment by user 1',
|
||||||
|
'format' => 0,
|
||||||
|
'userid' => $user1->id,
|
||||||
|
'timecreated' => time()
|
||||||
|
];
|
||||||
|
$DB->insert_record('comments', $comment);
|
||||||
|
|
||||||
|
$this->setUser($user5); // Set the user to the teacher.
|
||||||
|
|
||||||
|
$overridedata = new \stdClass();
|
||||||
|
$overridedata->assignid = $assign1->get_instance()->id;
|
||||||
|
$overridedata->userid = $user2->id;
|
||||||
|
$overridedata->duedate = time();
|
||||||
|
$overridedata->allowsubmissionsfromdate = time();
|
||||||
|
$overridedata->cutoffdate = time();
|
||||||
|
$DB->insert_record('assign_overrides', $overridedata);
|
||||||
|
|
||||||
|
$submissiontext = 'My first submission';
|
||||||
|
$submission = $this->create_submission($assign1, $user3, $submissiontext);
|
||||||
|
|
||||||
|
$submissiontext = 'My first submission';
|
||||||
|
$submission = $this->create_submission($assign1, $user4, $submissiontext);
|
||||||
|
|
||||||
|
$this->setUser($user5);
|
||||||
|
|
||||||
|
$grade = '72.00';
|
||||||
|
$teachercommenttext = 'This is better. Thanks.';
|
||||||
|
$data = new \stdClass();
|
||||||
|
$data->attemptnumber = 1;
|
||||||
|
$data->grade = $grade;
|
||||||
|
$data->assignfeedbackcomments_editor = ['text' => $teachercommenttext, 'format' => FORMAT_MOODLE];
|
||||||
|
|
||||||
|
// Give the submission a grade.
|
||||||
|
$assign1->save_grade($user4->id, $data);
|
||||||
|
|
||||||
|
$userlist = new \core_privacy\local\request\userlist($context, 'assign');
|
||||||
|
provider::get_users_in_context($userlist);
|
||||||
|
$userids = $userlist->get_userids();
|
||||||
|
$this->assertTrue(in_array($user1->id, $userids));
|
||||||
|
$this->assertTrue(in_array($user2->id, $userids));
|
||||||
|
$this->assertTrue(in_array($user3->id, $userids));
|
||||||
|
$this->assertTrue(in_array($user4->id, $userids));
|
||||||
|
$this->assertTrue(in_array($user5->id, $userids));
|
||||||
|
$this->assertFalse(in_array($user6->id, $userids));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that a student with multiple submissions and grades is returned with the correct data.
|
* Test that a student with multiple submissions and grades is returned with the correct data.
|
||||||
*/
|
*/
|
||||||
@ -577,4 +666,150 @@ class mod_assign_privacy_testcase extends provider_testcase {
|
|||||||
// The remaining event should be for user 1.
|
// The remaining event should be for user 1.
|
||||||
$this->assertEquals($user1->id, $record->userid);
|
$this->assertEquals($user1->id, $record->userid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A test for deleting all user data for a bunch of users.
|
||||||
|
*/
|
||||||
|
public function test_delete_data_for_users() {
|
||||||
|
global $DB;
|
||||||
|
|
||||||
|
$this->resetAfterTest();
|
||||||
|
|
||||||
|
$course = $this->getDataGenerator()->create_course();
|
||||||
|
|
||||||
|
// Only made a comment on a submission.
|
||||||
|
$user1 = $this->getDataGenerator()->create_user();
|
||||||
|
// User 2 only has information about an activity override.
|
||||||
|
$user2 = $this->getDataGenerator()->create_user();
|
||||||
|
// User 3 made a submission.
|
||||||
|
$user3 = $this->getDataGenerator()->create_user();
|
||||||
|
// User 4 makes a submission and it is marked by the teacher.
|
||||||
|
$user4 = $this->getDataGenerator()->create_user();
|
||||||
|
// Grading and providing feedback as a teacher.
|
||||||
|
$user5 = $this->getDataGenerator()->create_user();
|
||||||
|
// This user has entries in assignment 2 and should not have their data deleted.
|
||||||
|
$user6 = $this->getDataGenerator()->create_user();
|
||||||
|
|
||||||
|
$this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
|
||||||
|
$this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
|
||||||
|
$this->getDataGenerator()->enrol_user($user3->id, $course->id, 'student');
|
||||||
|
$this->getDataGenerator()->enrol_user($user4->id, $course->id, 'student');
|
||||||
|
$this->getDataGenerator()->enrol_user($user5->id, $course->id, 'editingteacher');
|
||||||
|
$this->getDataGenerator()->enrol_user($user6->id, $course->id, 'student');
|
||||||
|
|
||||||
|
$assign1 = $this->create_instance(['course' => $course,
|
||||||
|
'assignsubmission_onlinetext_enabled' => true,
|
||||||
|
'assignfeedback_comments_enabled' => true]);
|
||||||
|
$assign2 = $this->create_instance(['course' => $course,
|
||||||
|
'assignsubmission_onlinetext_enabled' => true,
|
||||||
|
'assignfeedback_comments_enabled' => true]);
|
||||||
|
|
||||||
|
$context = $assign1->get_context();
|
||||||
|
|
||||||
|
// Jam an entry in the comments table for user 1.
|
||||||
|
$comment = (object) [
|
||||||
|
'contextid' => $context->id,
|
||||||
|
'component' => 'assignsubmission_comments',
|
||||||
|
'commentarea' => 'submission_comments',
|
||||||
|
'itemid' => 5,
|
||||||
|
'content' => 'A comment by user 1',
|
||||||
|
'format' => 0,
|
||||||
|
'userid' => $user1->id,
|
||||||
|
'timecreated' => time()
|
||||||
|
];
|
||||||
|
$DB->insert_record('comments', $comment);
|
||||||
|
|
||||||
|
$this->setUser($user5); // Set the user to the teacher.
|
||||||
|
|
||||||
|
$overridedata = new \stdClass();
|
||||||
|
$overridedata->assignid = $assign1->get_instance()->id;
|
||||||
|
$overridedata->userid = $user2->id;
|
||||||
|
$overridedata->duedate = time();
|
||||||
|
$overridedata->allowsubmissionsfromdate = time();
|
||||||
|
$overridedata->cutoffdate = time();
|
||||||
|
$DB->insert_record('assign_overrides', $overridedata);
|
||||||
|
|
||||||
|
$submissiontext = 'My first submission';
|
||||||
|
$submission = $this->create_submission($assign1, $user3, $submissiontext);
|
||||||
|
|
||||||
|
$submissiontext = 'My first submission';
|
||||||
|
$submission = $this->create_submission($assign1, $user4, $submissiontext);
|
||||||
|
|
||||||
|
$submissiontext = 'My first submission';
|
||||||
|
$submission = $this->create_submission($assign2, $user6, $submissiontext);
|
||||||
|
|
||||||
|
$this->setUser($user5);
|
||||||
|
|
||||||
|
$grade = '72.00';
|
||||||
|
$teachercommenttext = 'This is better. Thanks.';
|
||||||
|
$data = new \stdClass();
|
||||||
|
$data->attemptnumber = 1;
|
||||||
|
$data->grade = $grade;
|
||||||
|
$data->assignfeedbackcomments_editor = ['text' => $teachercommenttext, 'format' => FORMAT_MOODLE];
|
||||||
|
|
||||||
|
// Give the submission a grade.
|
||||||
|
$assign1->save_grade($user4->id, $data);
|
||||||
|
|
||||||
|
$this->setUser($user5);
|
||||||
|
|
||||||
|
$grade = '81.00';
|
||||||
|
$teachercommenttext = 'This is nice.';
|
||||||
|
$data = new \stdClass();
|
||||||
|
$data->attemptnumber = 1;
|
||||||
|
$data->grade = $grade;
|
||||||
|
$data->assignfeedbackcomments_editor = ['text' => $teachercommenttext, 'format' => FORMAT_MOODLE];
|
||||||
|
|
||||||
|
// Give the submission a grade.
|
||||||
|
$assign2->save_grade($user6->id, $data);
|
||||||
|
|
||||||
|
// Check data is in place.
|
||||||
|
$data = $DB->get_records('assign_submission');
|
||||||
|
// We should have one entry for user 3 and two entries each for user 4 and 6.
|
||||||
|
$this->assertCount(5, $data);
|
||||||
|
$usercounts = [
|
||||||
|
$user3->id => 0,
|
||||||
|
$user4->id => 0,
|
||||||
|
$user6->id => 0
|
||||||
|
];
|
||||||
|
foreach ($data as $datum) {
|
||||||
|
$usercounts[$datum->userid]++;
|
||||||
|
}
|
||||||
|
$this->assertEquals(1, $usercounts[$user3->id]);
|
||||||
|
$this->assertEquals(2, $usercounts[$user4->id]);
|
||||||
|
$this->assertEquals(2, $usercounts[$user6->id]);
|
||||||
|
|
||||||
|
$data = $DB->get_records('assign_grades');
|
||||||
|
// Two entries in assign_grades, one for each grade given.
|
||||||
|
$this->assertCount(2, $data);
|
||||||
|
|
||||||
|
$data = $DB->get_records('assign_overrides');
|
||||||
|
$this->assertCount(1, $data);
|
||||||
|
|
||||||
|
$data = $DB->get_records('comments');
|
||||||
|
$this->assertCount(1, $data);
|
||||||
|
|
||||||
|
$userlist = new \core_privacy\local\request\approved_userlist($context, 'assign', [$user1->id, $user2->id]);
|
||||||
|
provider::delete_data_for_users($userlist);
|
||||||
|
|
||||||
|
$data = $DB->get_records('assign_overrides');
|
||||||
|
$this->assertEmpty($data);
|
||||||
|
|
||||||
|
$data = $DB->get_records('comments');
|
||||||
|
$this->assertEmpty($data);
|
||||||
|
|
||||||
|
$data = $DB->get_records('assign_submission');
|
||||||
|
// No change here.
|
||||||
|
$this->assertCount(5, $data);
|
||||||
|
|
||||||
|
$userlist = new \core_privacy\local\request\approved_userlist($context, 'assign', [$user3->id, $user5->id]);
|
||||||
|
provider::delete_data_for_users($userlist);
|
||||||
|
|
||||||
|
$data = $DB->get_records('assign_submission');
|
||||||
|
// Only the record for user 3 has been deleted.
|
||||||
|
$this->assertCount(4, $data);
|
||||||
|
|
||||||
|
$data = $DB->get_records('assign_grades');
|
||||||
|
// Grades should be unchanged.
|
||||||
|
$this->assertCount(2, $data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user