mirror of
https://github.com/moodle/moodle.git
synced 2025-04-17 06:25:33 +02:00
MDL-62169 mod_assignment: Implemented privacy providers
This commit is contained in:
parent
446d8483a3
commit
0fed66ad0f
475
mod/assignment/classes/privacy/provider.php
Normal file
475
mod/assignment/classes/privacy/provider.php
Normal file
@ -0,0 +1,475 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Privacy Subsystem implementation for mod_assignment.
|
||||
*
|
||||
* @package mod_assignment
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace mod_assignment\privacy;
|
||||
|
||||
use core_privacy\local\metadata\collection;
|
||||
use core_privacy\local\request\approved_contextlist;
|
||||
use core_privacy\local\request\contextlist;
|
||||
use core_privacy\local\request\transform;
|
||||
use core_privacy\local\request\writer;
|
||||
use core_privacy\local\request\helper;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/mod/assignment/lib.php');
|
||||
|
||||
/**
|
||||
* Implementation of the privacy subsystem plugin provider for mod_assignment.
|
||||
*
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class provider implements
|
||||
\core_privacy\local\metadata\provider,
|
||||
\core_privacy\local\request\plugin\provider,
|
||||
\core_privacy\local\request\user_preference_provider {
|
||||
|
||||
/**
|
||||
* Return the fields which contain personal data.
|
||||
*
|
||||
* @param collection $collection a reference to the collection to use to store the metadata.
|
||||
* @return collection the updated collection of metadata items.
|
||||
*/
|
||||
public static function get_metadata(collection $collection) : collection {
|
||||
$collection->add_database_table(
|
||||
'assignment_submissions',
|
||||
[
|
||||
'userid' => 'privacy:metadata:assignment_submissions:userid',
|
||||
'timecreated' => 'privacy:metadata:assignment_submissions:timecreated',
|
||||
'timemodified' => 'privacy:metadata:assignment_submissions:timemodified',
|
||||
'numfiles' => 'privacy:metadata:assignment_submissions:numfiles',
|
||||
'data1' => 'privacy:metadata:assignment_submissions:data1',
|
||||
'data2' => 'privacy:metadata:assignment_submissions:data2',
|
||||
'grade' => 'privacy:metadata:assignment_submissions:grade',
|
||||
'submissioncomment' => 'privacy:metadata:assignment_submissions:submissioncomment',
|
||||
'teacher' => 'privacy:metadata:assignment_submissions:teacher',
|
||||
'timemarked' => 'privacy:metadata:assignment_submissions:timemarked',
|
||||
'mailed' => 'privacy:metadata:assignment_submissions:mailed'
|
||||
],
|
||||
'privacy:metadata:assignment_submissions'
|
||||
);
|
||||
|
||||
// Legacy mod_assignment preferences from Moodle 2.X.
|
||||
$collection->add_user_preference('assignment_filter', 'privacy:metadata:assignmentfilter');
|
||||
$collection->add_user_preference('assignment_mailinfo', 'privacy:metadata:assignmentmailinfo');
|
||||
$collection->add_user_preference('assignment_perpage', 'privacy:metadata:assignmentperpage');
|
||||
$collection->add_user_preference('assignment_quickgrade', 'privacy:metadata:assignmentquickgrade');
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of contexts that contain user information for the specified user.
|
||||
*
|
||||
* @param int $userid the userid.
|
||||
* @return contextlist the list of contexts containing user info for the user.
|
||||
*/
|
||||
public static function get_contexts_for_userid(int $userid) : contextlist {
|
||||
$contextlist = new contextlist();
|
||||
|
||||
$sql = "SELECT DISTINCT
|
||||
ctx.id
|
||||
FROM {context} ctx
|
||||
JOIN {course_modules} cm ON cm.id = ctx.instanceid AND ctx.contextlevel = :contextmodule
|
||||
JOIN {modules} m ON cm.module = m.id AND m.name = :modulename
|
||||
JOIN {assignment} a ON cm.instance = a.id
|
||||
JOIN {assignment_submissions} s ON s.assignment = a.id
|
||||
WHERE s.userid = :userid
|
||||
OR s.teacher = :teacher";
|
||||
|
||||
$params = [
|
||||
'contextmodule' => CONTEXT_MODULE,
|
||||
'modulename' => 'assignment',
|
||||
'userid' => $userid,
|
||||
'teacher' => $userid
|
||||
];
|
||||
|
||||
$contextlist->add_from_sql($sql, $params);
|
||||
|
||||
return $contextlist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export personal data for the given approved_contextlist.
|
||||
* User and context information is contained within the contextlist.
|
||||
*
|
||||
* @param approved_contextlist $contextlist a list of contexts approved for export.
|
||||
*/
|
||||
public static function export_user_data(approved_contextlist $contextlist) {
|
||||
if (empty($contextlist->count())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user = $contextlist->get_user();
|
||||
|
||||
foreach ($contextlist->get_contexts() as $context) {
|
||||
if ($context->contextlevel != CONTEXT_MODULE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Cannot make use of helper::export_context_files(), need to manually export assignment details.
|
||||
$assignmentdata = self::get_assignment_by_context($context);
|
||||
|
||||
// Get assignment details object for output.
|
||||
$assignment = self::get_assignment_output($assignmentdata);
|
||||
writer::with_context($context)->export_data([], $assignment);
|
||||
|
||||
// Check if the user has marked any assignment's submissions to determine assignment submissions to export.
|
||||
$teacher = (self::has_marked_assignment_submissions($assignmentdata->id, $user->id) == true) ? true : false;
|
||||
|
||||
// Get the assignment submissions submitted by & marked by the user for an assignment.
|
||||
$submissionsdata = self::get_assignment_submissions_by_assignment($assignmentdata->id, $user->id, $teacher);
|
||||
|
||||
foreach ($submissionsdata as $submissiondata) {
|
||||
// Default subcontext path to export assignment submissions submitted by the user.
|
||||
$subcontexts = [
|
||||
get_string('privacy:submissionpath', 'mod_assignment')
|
||||
];
|
||||
|
||||
if ($teacher == true) {
|
||||
if ($submissiondata->teacher == $user->id) {
|
||||
// Export assignment submissions that have been marked by the user.
|
||||
$subcontexts = [
|
||||
get_string('privacy:markedsubmissionspath', 'mod_assignment'),
|
||||
transform::user($submissiondata->userid)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Get assignment submission details object for output.
|
||||
$submission = self::get_assignment_submission_output($submissiondata);
|
||||
$itemid = $submissiondata->id;
|
||||
|
||||
writer::with_context($context)
|
||||
->export_data($subcontexts, $submission)
|
||||
->export_area_files($subcontexts, 'mod_assignment', 'submission', $itemid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the user preferences related to mod_assign.
|
||||
*
|
||||
* @param int $userid The user ID that we want the preferences for.
|
||||
*/
|
||||
public static function export_user_preferences(int $userid) {
|
||||
$context = \context_system::instance();
|
||||
$assignmentpreferences = [
|
||||
'assignment_filter' => [
|
||||
'string' => get_string('privacy:metadata:assignmentfilter', 'mod_assignment'),
|
||||
'bool' => false
|
||||
],
|
||||
'assignment_mailinfo' => [
|
||||
'string' => get_string('privacy:metadata:assignmentmailinfo', 'mod_assignment'),
|
||||
'bool' => false
|
||||
],
|
||||
'assignment_perpage' => [
|
||||
'string' => get_string('privacy:metadata:assignmentperpage', 'mod_assignment'),
|
||||
'bool' => false
|
||||
],
|
||||
'assignment_quickgrade' => [
|
||||
'string' => get_string('privacy:metadata:assignmentquickgrade', 'mod_assignment'),
|
||||
'bool' => false
|
||||
],
|
||||
];
|
||||
foreach ($assignmentpreferences as $key => $preference) {
|
||||
$value = get_user_preferences($key, null, $userid);
|
||||
if ($preference['bool']) {
|
||||
$value = transform::yesno($value);
|
||||
}
|
||||
if (isset($value)) {
|
||||
writer::with_context($context)
|
||||
->export_user_preference('mod_assignment', $key, $value, $preference['string']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all data for all users in the specified context.
|
||||
*
|
||||
* @param \context $context the context to delete in.
|
||||
*/
|
||||
public static function delete_data_for_all_users_in_context(\context $context) {
|
||||
global $DB;
|
||||
|
||||
if (empty($context)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($context->contextlevel == CONTEXT_MODULE) {
|
||||
// Delete all assignment submissions for the assignment associated with the context module.
|
||||
$assignment = self::get_assignment_by_context($context);
|
||||
if ($assignment != null) {
|
||||
$DB->delete_records('assignment_submissions', ['assignment' => $assignment->id]);
|
||||
|
||||
// Delete all file uploads associated with the assignment submission for the specified context.
|
||||
$fs = get_file_storage();
|
||||
$fs->delete_area_files($context->id, 'mod_assignment', 'submission');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all user data for the specified user, in the specified contexts.
|
||||
*
|
||||
* @param approved_contextlist $contextlist a list of contexts approved for deletion.
|
||||
*/
|
||||
public static function delete_data_for_user(approved_contextlist $contextlist) {
|
||||
global $DB;
|
||||
|
||||
if (empty($contextlist->count())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$userid = $contextlist->get_user()->id;
|
||||
|
||||
// Only retrieve assignment submissions submitted by the user for deletion.
|
||||
$assignmentsubmissionids = array_keys(self::get_assignment_submissions_by_contextlist($contextlist, $userid));
|
||||
$DB->delete_records_list('assignment_submissions', 'id', $assignmentsubmissionids);
|
||||
|
||||
// Delete all file uploads associated with the assignment submission for the user's specified list of contexts.
|
||||
$fs = get_file_storage();
|
||||
foreach ($contextlist->get_contextids() as $contextid) {
|
||||
foreach ($assignmentsubmissionids as $submissionid) {
|
||||
$fs->delete_area_files($contextid, 'mod_assignment', 'submission', $submissionid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start of helper functions.
|
||||
|
||||
/**
|
||||
* Helper function to check if a user has marked assignment submissions for a given assignment.
|
||||
*
|
||||
* @param int $assignmentid The assignment ID to check if user has marked associated submissions.
|
||||
* @param int $userid The user ID to check if user has marked associated submissions.
|
||||
* @return bool If user has marked associated submissions returns true, otherwise false.
|
||||
* @throws \dml_exception
|
||||
*/
|
||||
protected static function has_marked_assignment_submissions($assignmentid, $userid) {
|
||||
global $DB;
|
||||
|
||||
$params = [
|
||||
'assignment' => $assignmentid,
|
||||
'teacher' => $userid
|
||||
];
|
||||
|
||||
$sql = "SELECT count(s.id) as nomarked
|
||||
FROM {assignment_submissions} s
|
||||
WHERE s.assignment = :assignment
|
||||
AND s.teacher = :teacher";
|
||||
|
||||
$results = $DB->get_record_sql($sql, $params);
|
||||
|
||||
return ($results->nomarked > 0) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return assignment for a context module.
|
||||
*
|
||||
* @param object $context The context module object to return the assignment record by.
|
||||
* @return mixed The assignment details or null record associated with the context module.
|
||||
* @throws \dml_exception
|
||||
*/
|
||||
protected static function get_assignment_by_context($context) {
|
||||
global $DB;
|
||||
|
||||
$params = [
|
||||
'modulename' => 'assignment',
|
||||
'contextmodule' => CONTEXT_MODULE,
|
||||
'contextid' => $context->id
|
||||
];
|
||||
|
||||
$sql = "SELECT a.id,
|
||||
a.name,
|
||||
a.intro,
|
||||
a.assignmenttype,
|
||||
a.grade,
|
||||
a.timedue,
|
||||
a.timeavailable,
|
||||
a.timemodified
|
||||
FROM {assignment} a
|
||||
JOIN {course_modules} cm ON a.id = cm.instance
|
||||
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
|
||||
JOIN {context} ctx ON ctx.instanceid = cm.id AND ctx.contextlevel = :contextmodule
|
||||
WHERE ctx.id = :contextid";
|
||||
|
||||
return $DB->get_record_sql($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return assignment submissions submitted by / marked by a user and their contextlist.
|
||||
*
|
||||
* @param object $contextlist Object with the contexts related to a userid to retrieve assignment submissions by.
|
||||
* @param int $userid The user ID to find assignment submissions that were submitted by.
|
||||
* @param bool $teacher The teacher status to determine if marked assignment submissions should be returned.
|
||||
* @return array Array of assignment submission details.
|
||||
* @throws \coding_exception
|
||||
* @throws \dml_exception
|
||||
*/
|
||||
protected static function get_assignment_submissions_by_contextlist($contextlist, $userid, $teacher = false) {
|
||||
global $DB;
|
||||
|
||||
list($contextsql, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
|
||||
|
||||
$params = [
|
||||
'contextmodule' => CONTEXT_MODULE,
|
||||
'modulename' => 'assignment',
|
||||
'userid' => $userid
|
||||
];
|
||||
|
||||
$sql = "SELECT s.id as id,
|
||||
s.assignment as assignment,
|
||||
s.numfiles as numfiles,
|
||||
s.data1 as data1,
|
||||
s.data2 as data2,
|
||||
s.grade as grade,
|
||||
s.submissioncomment as submissioncomment,
|
||||
s.teacher as teacher,
|
||||
s.timemarked as timemarked,
|
||||
s.timecreated as timecreated,
|
||||
s.timemodified as timemodified
|
||||
FROM {context} ctx
|
||||
JOIN {course_modules} cm ON cm.id = ctx.instanceid AND ctx.contextlevel = :contextmodule
|
||||
JOIN {modules} m ON cm.module = m.id AND m.name = :modulename
|
||||
JOIN {assignment} a ON cm.instance = a.id
|
||||
JOIN {assignment_submissions} s ON s.assignment = a.id
|
||||
WHERE (s.userid = :userid";
|
||||
|
||||
if ($teacher == true) {
|
||||
$sql .= " OR s.teacher = :teacher";
|
||||
$params['teacher'] = $userid;
|
||||
}
|
||||
|
||||
$sql .= ")";
|
||||
|
||||
$sql .= " AND ctx.id {$contextsql}";
|
||||
$params += $contextparams;
|
||||
|
||||
return $DB->get_records_sql($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to retrieve assignment submissions submitted by / marked by a user for a specific assignment.
|
||||
*
|
||||
* @param int $assignmentid The assignment ID to retrieve assignment submissions by.
|
||||
* @param int $userid The user ID to retrieve assignment submissions submitted / marked by.
|
||||
* @param bool $teacher The teacher status to determine if marked assignment submissions should be returned.
|
||||
* @return array Array of assignment submissions details.
|
||||
* @throws \dml_exception
|
||||
*/
|
||||
protected static function get_assignment_submissions_by_assignment($assignmentid, $userid, $teacher = false) {
|
||||
global $DB;
|
||||
|
||||
$params = [
|
||||
'assignment' => $assignmentid,
|
||||
'userid' => $userid
|
||||
];
|
||||
|
||||
$sql = "SELECT s.id as id,
|
||||
s.assignment as assignment,
|
||||
s.numfiles as numfiles,
|
||||
s.data1 as data1,
|
||||
s.data2 as data2,
|
||||
s.grade as grade,
|
||||
s.submissioncomment as submissioncomment,
|
||||
s.teacher as teacher,
|
||||
s.timemarked as timemarked,
|
||||
s.timecreated as timecreated,
|
||||
s.timemodified as timemodified,
|
||||
s.userid as userid
|
||||
FROM {assignment_submissions} s
|
||||
WHERE s.assignment = :assignment
|
||||
AND (s.userid = :userid";
|
||||
|
||||
if ($teacher == true) {
|
||||
$sql .= " OR s.teacher = :teacher";
|
||||
$params['teacher'] = $userid;
|
||||
}
|
||||
|
||||
$sql .= ")";
|
||||
|
||||
return $DB->get_records_sql($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function generate assignment output object for exporting.
|
||||
*
|
||||
* @param object $assignmentdata Object containing assignment data.
|
||||
* @return object Formatted assignment output object for exporting.
|
||||
*/
|
||||
protected static function get_assignment_output($assignmentdata) {
|
||||
$assignment = (object) [
|
||||
'name' => $assignmentdata->name,
|
||||
'intro' => $assignmentdata->intro,
|
||||
'assignmenttype' => $assignmentdata->assignmenttype,
|
||||
'grade' => $assignmentdata->grade,
|
||||
'timemodified' => transform::datetime($assignmentdata->timemodified)
|
||||
];
|
||||
|
||||
if ($assignmentdata->timeavailable != 0) {
|
||||
$assignment->timeavailable = transform::datetime($assignmentdata->timeavailable);
|
||||
}
|
||||
|
||||
if ($assignmentdata->timedue != 0) {
|
||||
$assignment->timedue = transform::datetime($assignmentdata->timedue);
|
||||
}
|
||||
|
||||
return $assignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function generate assignment submission output object for exporting.
|
||||
*
|
||||
* @param object $submissiondata Object containing assignment submission data.
|
||||
* @return object Formatted assignment submission output for exporting.
|
||||
*/
|
||||
protected static function get_assignment_submission_output($submissiondata) {
|
||||
$submission = (object) [
|
||||
'assignment' => $submissiondata->assignment,
|
||||
'numfiles' => $submissiondata->numfiles,
|
||||
'data1' => $submissiondata->data1,
|
||||
'data2' => $submissiondata->data2,
|
||||
'grade' => $submissiondata->grade,
|
||||
'submissioncomment' => $submissiondata->submissioncomment,
|
||||
'teacher' => transform::user($submissiondata->teacher)
|
||||
];
|
||||
|
||||
if ($submissiondata->timecreated != 0) {
|
||||
$submission->timecreated = transform::datetime($submissiondata->timecreated);
|
||||
}
|
||||
|
||||
if ($submissiondata->timemarked != 0) {
|
||||
$submission->timemarked = transform::datetime($submissiondata->timemarked);
|
||||
}
|
||||
|
||||
if ($submissiondata->timemodified != 0) {
|
||||
$submission->timemodified = transform::datetime($submissiondata->timemodified);
|
||||
}
|
||||
|
||||
return $submission;
|
||||
}
|
||||
}
|
@ -42,3 +42,21 @@ $string['pluginname'] = 'Assignment 2.2 (Disabled)';
|
||||
$string['upgradenotification'] = 'This activity is based on an older assignment module.';
|
||||
$string['viewassignmentupgradetool'] = 'View the assignment upgrade tool';
|
||||
$string['pluginadministration'] = 'Assignment 2.2 (Disabled) administration';
|
||||
$string['privacy:markedsubmissionspath'] = 'markedsubmissions';
|
||||
$string['privacy:submissionpath'] = 'submission';
|
||||
$string['privacy:metadata:assignmentfilter'] = 'Filter preference of assignment submissions.';
|
||||
$string['privacy:metadata:assignmentperpage'] = 'Number of assignment submissions shown per page preference.';
|
||||
$string['privacy:metadata:assignmentmailinfo'] = 'Mail info preference for assignment submissions.';
|
||||
$string['privacy:metadata:assignmentquickgrade'] = 'Quick grading preference for assignment submissions.';
|
||||
$string['privacy:metadata:assignment_submissions'] = 'Assignment submissions associated with an assignment.';
|
||||
$string['privacy:metadata:assignment_submissions:userid'] = 'The user ID submitting the assignment submission.';
|
||||
$string['privacy:metadata:assignment_submissions:timecreated'] = 'The creation date/time of the assignment submission.';
|
||||
$string['privacy:metadata:assignment_submissions:timemodified'] = 'The modification date/time of the assignment submission.';
|
||||
$string['privacy:metadata:assignment_submissions:numfiles'] = 'The maximum number of files allowed for the assignment submission.';
|
||||
$string['privacy:metadata:assignment_submissions:data1'] = 'The onlinetext submitted for the assignment submission.';
|
||||
$string['privacy:metadata:assignment_submissions:data2'] = '';
|
||||
$string['privacy:metadata:assignment_submissions:grade'] = 'The grade value awarded for the assignment submission.';
|
||||
$string['privacy:metadata:assignment_submissions:submissioncomment'] = 'The submission comment accompanying the assignment submission.';
|
||||
$string['privacy:metadata:assignment_submissions:teacher'] = 'The teacher user ID grading the assignment submission.';
|
||||
$string['privacy:metadata:assignment_submissions:timemarked'] = 'The marking date/time of the assignment submission.';
|
||||
$string['privacy:metadata:assignment_submissions:mailed'] = 'The mailed notification status of the assignment submission.';
|
||||
|
606
mod/assignment/tests/privacy_test.php
Normal file
606
mod/assignment/tests/privacy_test.php
Normal file
@ -0,0 +1,606 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Privacy test for the event monitor
|
||||
*
|
||||
* @package mod_assignment
|
||||
* @category test
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once(__DIR__ . '/../lib.php');
|
||||
|
||||
use \mod_assignment\privacy\provider;
|
||||
use \core_privacy\local\metadata\collection;
|
||||
use \core_privacy\local\request\approved_contextlist;
|
||||
use \core_privacy\local\request\transform;
|
||||
use \core_privacy\local\request\writer;
|
||||
use \core_privacy\tests\provider_testcase;
|
||||
|
||||
/**
|
||||
* Privacy test for the event monitor
|
||||
*
|
||||
* @package mod_assignment
|
||||
* @category test
|
||||
* @copyright 2018 Zig Tan <zig@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class mod_assignment_privacy_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* @var int array Array of test student ids associated for Course 1.
|
||||
*/
|
||||
private $course1students = [];
|
||||
|
||||
/**
|
||||
* @var int array Array of test student ids associated for Course 2.
|
||||
*/
|
||||
private $course2students = [];
|
||||
|
||||
/**
|
||||
* Test for provider::get_contexts_for_userid().
|
||||
*
|
||||
* @throws coding_exception
|
||||
*/
|
||||
public function test_get_contexts_for_userid() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$this->create_courses_and_assignments();
|
||||
|
||||
// Get Teacher 1 to test get_contexts_for_userid().
|
||||
$teacher1 = $DB->get_record('user', ['username' => 'teacher1']);
|
||||
$contextids = provider::get_contexts_for_userid($teacher1->id);
|
||||
// Verify there should be 4 contexts, as Teacher 1 has submitted tests and marked Assignments in Course 1 and 2.
|
||||
$this->assertEquals(4, count($contextids->get_contextids()));
|
||||
|
||||
// Get Teacher 2 to test get_contexts_for_userid().
|
||||
$teacher2 = $DB->get_record('user', ['username' => 'teacher2']);
|
||||
$contextids = provider::get_contexts_for_userid($teacher2->id);
|
||||
// Verify there should be 0 contexts, as teacher 2 has not marked any Assignments.
|
||||
$this->assertEquals(0, count($contextids->get_contextids()));
|
||||
|
||||
// Get Student 1 to test get_contexts_for_userid().
|
||||
$student1 = $DB->get_record('user', ['username' => 'student1']);
|
||||
$contextids = provider::get_contexts_for_userid($student1->id);
|
||||
// Verify there should be 2 contexts, as student 1 added submissions for both Assignments in Course 1.
|
||||
$this->assertEquals(2, count($contextids->get_contextids()));
|
||||
|
||||
// Get Student 2 to test get_contexts_for_userid().
|
||||
$student2 = $DB->get_record('user', ['username' => 'student2']);
|
||||
$contextids = provider::get_contexts_for_userid($student2->id);
|
||||
// Verify there should be 2 context, as student 2 added submissions for both Assignments in Course 2.
|
||||
$this->assertEquals(2, count($contextids->get_contextids()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for provider::export_user_data().
|
||||
*
|
||||
* @throws coding_exception
|
||||
*/
|
||||
public function test_export_user_data_teacher() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$this->create_courses_and_assignments();
|
||||
|
||||
// Test Teacher 1 export_data_for_user() - marking assignment submissions for both Course 1 and 2.
|
||||
$teacher1 = $DB->get_record('user', ['username' => 'teacher1']);
|
||||
|
||||
$contextlist = provider::get_contexts_for_userid($teacher1->id);
|
||||
$approvedcontextlist = new approved_contextlist($teacher1, 'mod_assignment', $contextlist->get_contextids());
|
||||
|
||||
// Verify Teacher 1 has four contexts.
|
||||
$this->assertCount(4, $contextlist->get_contextids());
|
||||
|
||||
// Retrieve Assignment Submissions data for Teacher 1.
|
||||
provider::export_user_data($approvedcontextlist);
|
||||
|
||||
$contexts = $contextlist->get_contexts();
|
||||
|
||||
// Context 1 - Course 1's Assignment 1 -- (onlinetext).
|
||||
$writer = writer::with_context($contexts[0]);
|
||||
$subcontexts = [
|
||||
get_string('privacy:markedsubmissionspath', 'mod_assignment'),
|
||||
transform::user($teacher1->id)
|
||||
];
|
||||
// Verify the test assignment submission from Teacher 1 exists.
|
||||
$submission = $writer->get_data($subcontexts);
|
||||
$this->assertEquals('<p>Course 1 - Ass 1: Teacher Test Submission</p>', $submission->data1);
|
||||
|
||||
foreach ($this->course1students as $student) {
|
||||
$subcontexts = [
|
||||
get_string('privacy:markedsubmissionspath', 'mod_assignment'),
|
||||
transform::user($student->id)
|
||||
];
|
||||
// Verify the student assignment submissions exists.
|
||||
$submission = $writer->get_data($subcontexts);
|
||||
$this->assertEquals("<p>Course 1 - Ass 1: " . $student->id . "</p>", $submission->data1);
|
||||
}
|
||||
|
||||
// Context 2 - Course 1's Assignment 2 -- (single file upload).
|
||||
$writer = writer::with_context($contexts[1]);
|
||||
foreach ($this->course1students as $student) {
|
||||
$subcontexts = [
|
||||
get_string('privacy:markedsubmissionspath', 'mod_assignment'),
|
||||
transform::user($student->id)
|
||||
];
|
||||
// Verify the student assignment submissions exists.
|
||||
$submission = $writer->get_data($subcontexts);
|
||||
$this->assertEquals("<p>Course 1 - Ass 2: " . $student->id . "</p>", $submission->data1);
|
||||
|
||||
// Verify the student assignment submission file upload exists.
|
||||
$submissionfiles = $writer->get_files($subcontexts);
|
||||
$this->assertTrue(array_key_exists('Student' . $student->id . '-Course1-Ass2-(File 1 of 1)', $submissionfiles));
|
||||
}
|
||||
|
||||
// Context 3 - Course 2's Assignment 1 -- (offline).
|
||||
$writer = writer::with_context($contexts[2]);
|
||||
foreach ($this->course2students as $student) {
|
||||
$subcontexts = [
|
||||
get_string('privacy:markedsubmissionspath', 'mod_assignment'),
|
||||
transform::user($student->id)
|
||||
];
|
||||
// Verify the student assignment submissions exists.
|
||||
$submission = $writer->get_data($subcontexts);
|
||||
$this->assertEquals("<p>Course 2 - Ass 1: " . $student->id . "</p>", $submission->data1);
|
||||
}
|
||||
|
||||
// Context 4 - Course 2's Assignment 2 -- (multiple file upload).
|
||||
$writer = writer::with_context($contexts[3]);
|
||||
foreach ($this->course2students as $student) {
|
||||
$subcontexts = [
|
||||
get_string('privacy:markedsubmissionspath', 'mod_assignment'),
|
||||
transform::user($student->id)
|
||||
];
|
||||
// Verify the student assignment submissions exists.
|
||||
$submission = $writer->get_data($subcontexts);
|
||||
$this->assertEquals("<p>Course 2 - Ass 2: " . $student->id . "</p>", $submission->data1);
|
||||
|
||||
// Verify the student assignment submission file upload exists.
|
||||
$submissionfiles = $writer->get_files($subcontexts);
|
||||
$this->assertTrue(array_key_exists('Student' . $student->id . '-Course2-Ass2-(File 1 of 2)', $submissionfiles));
|
||||
$this->assertTrue(array_key_exists('Student' . $student->id . '-Course2-Ass2-(File 2 of 2)', $submissionfiles));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for provider::export_user_data().
|
||||
*
|
||||
* @throws dml_exception
|
||||
*/
|
||||
public function test_export_user_data_student() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$this->create_courses_and_assignments();
|
||||
|
||||
// Test Student 1 export_data_for_user() - added assignment submissions for both assignments in Course 1.
|
||||
$student1 = $DB->get_record('user', ['username' => 'student1']);
|
||||
|
||||
$contextlist = provider::get_contexts_for_userid($student1->id);
|
||||
$approvedcontextlist = new approved_contextlist($student1, 'mod_assignment', $contextlist->get_contextids());
|
||||
|
||||
// Retrieve Assignment Submissions data for Student 1.
|
||||
provider::export_user_data($approvedcontextlist);
|
||||
$contexts = $contextlist->get_contexts();
|
||||
|
||||
// Context 1 - Course 1's Assignment 1 -- (onlinetext).
|
||||
$writer = writer::with_context($contexts[0]);
|
||||
$subcontexts = [
|
||||
get_string('privacy:submissionpath', 'mod_assignment')
|
||||
];
|
||||
|
||||
// Verify the student assignment submissions exists.
|
||||
$submission = $writer->get_data($subcontexts);
|
||||
$this->assertEquals("<p>Course 1 - Ass 1: " . $student1->id . "</p>", $submission->data1);
|
||||
|
||||
// Context 2 - Course 1's Assignment 2 -- (single file upload).
|
||||
$writer = writer::with_context($contexts[1]);
|
||||
$subcontexts = [
|
||||
get_string('privacy:submissionpath', 'mod_assignment')
|
||||
];
|
||||
|
||||
// Verify the student assignment submission exists.
|
||||
$submission = $writer->get_data($subcontexts);
|
||||
$this->assertEquals("<p>Course 1 - Ass 2: " . $student1->id . "</p>", $submission->data1);
|
||||
|
||||
// Verify the student assignment submission file upload exists.
|
||||
$submissionfiles = $writer->get_files($subcontexts);
|
||||
$this->assertTrue(array_key_exists('Student' . $student1->id . '-Course1-Ass2-(File 1 of 1)', $submissionfiles));
|
||||
|
||||
// Test Student 2 export_data_for_user() - added assignment submissions for both assignments in Course 2.
|
||||
$student2 = $DB->get_record('user', ['username' => 'student2']);
|
||||
|
||||
$contextlist = provider::get_contexts_for_userid($student2->id);
|
||||
$approvedcontextlist = new approved_contextlist($student2, 'mod_assignment', $contextlist->get_contextids());
|
||||
|
||||
// Retrieve Assignment Submissions data for Student 2.
|
||||
provider::export_user_data($approvedcontextlist);
|
||||
$contexts = $contextlist->get_contexts();
|
||||
|
||||
// Context 1 - Course 2's Assignment 1 -- (offline).
|
||||
$writer = writer::with_context($contexts[0]);
|
||||
$subcontexts = [
|
||||
get_string('privacy:submissionpath', 'mod_assignment')
|
||||
];
|
||||
|
||||
// Verify the student assignment submissions exists.
|
||||
$submission = $writer->get_data($subcontexts);
|
||||
$this->assertEquals("<p>Course 2 - Ass 1: " . $student2->id . "</p>", $submission->data1);
|
||||
|
||||
// Context 2 - Course 2's Assignment 2 -- (multiple file upload).
|
||||
$writer = writer::with_context($contexts[1]);
|
||||
$subcontexts = [
|
||||
get_string('privacy:submissionpath', 'mod_assignment')
|
||||
];
|
||||
|
||||
// Verify the student assignment submission exists.
|
||||
$submission = $writer->get_data($subcontexts);
|
||||
$this->assertEquals("<p>Course 2 - Ass 2: " . $student2->id . "</p>", $submission->data1);
|
||||
|
||||
// Verify the student assignment submission file upload exists.
|
||||
$submissionfiles = $writer->get_files($subcontexts);
|
||||
$this->assertTrue(array_key_exists('Student' . $student2->id . '-Course2-Ass2-(File 1 of 2)', $submissionfiles));
|
||||
$this->assertTrue(array_key_exists('Student' . $student2->id . '-Course2-Ass2-(File 2 of 2)', $submissionfiles));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for provider::delete_data_for_all_users_in_context().
|
||||
*
|
||||
* @throws dml_exception
|
||||
*/
|
||||
public function test_delete_data_for_all_users_in_context() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$this->create_courses_and_assignments();
|
||||
|
||||
// Test teacher1 delete_data_for_all_users_in_context().
|
||||
$teacher1 = $DB->get_record('user', ['username' => 'teacher1']);
|
||||
$contextlist = provider::get_contexts_for_userid($teacher1->id);
|
||||
|
||||
foreach ($contextlist as $context) {
|
||||
provider::delete_data_for_all_users_in_context($context);
|
||||
|
||||
// Verify assignment submission(s) were deleted for the context.
|
||||
$deleted = $this->get_assignment_submissions($context->id);
|
||||
$this->assertCount(0, $deleted);
|
||||
|
||||
// Verify all the file submissions associated with the context for all users were deleted.
|
||||
$files = $DB->get_records('files', ['component' => 'mod_assignment', 'filearea' => 'submission', 'contextid' => $context->id]);
|
||||
$this->assertEquals(0, count($files));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for provider::delete_data_for_user().
|
||||
*
|
||||
* @throws dml_exception
|
||||
*/
|
||||
public function test_delete_data_for_user() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$this->create_courses_and_assignments();
|
||||
|
||||
// Test Teacher 1 delete_data_for_user(), should only remove the 1 test submission added by Teacher 1.
|
||||
// Should not remove any assignment submission records marked by the teacher.
|
||||
$teacher1 = $DB->get_record('user', ['username' => 'teacher1']);
|
||||
$contextlist = provider::get_contexts_for_userid($teacher1->id);
|
||||
$approvedcontextlist = new approved_contextlist($teacher1, 'mod_assignment', $contextlist->get_contextids());
|
||||
provider::delete_data_for_user($approvedcontextlist);
|
||||
|
||||
// Verify the submissions submitted by students still exists.
|
||||
$markedsubmissions = $DB->get_records('assignment_submissions', ['teacher' => $teacher1->id]);
|
||||
$this->assertCount(4, $markedsubmissions);
|
||||
|
||||
// Test student 1 delete_data_for_user().
|
||||
$student1 = $DB->get_record('user', ['username' => 'student1']);
|
||||
$contextlist = provider::get_contexts_for_userid($student1->id);
|
||||
$approvedcontextlist = new approved_contextlist($student1, 'mod_assignment', $contextlist->get_contextids());
|
||||
provider::delete_data_for_user($approvedcontextlist);
|
||||
|
||||
// Verify student 1's assignment submissions were deleted.
|
||||
$assignmentsubmissions = $DB->get_records('assignment_submissions', ['userid' => $student1->id]);
|
||||
$this->assertEquals(0, count($assignmentsubmissions));
|
||||
|
||||
// Verify student 1's file submissions were deleted.
|
||||
foreach ($contextlist->get_contextids() as $contextid) {
|
||||
$files = $DB->get_records('files', ['component' => 'mod_assignment', 'filearea' => 'submission', 'contextid' => $contextid]);
|
||||
$this->assertEquals(0, count($files));
|
||||
}
|
||||
}
|
||||
|
||||
// Start of helper functions.
|
||||
|
||||
/**
|
||||
* Helper function to setup Course, users, and assignments for testing.
|
||||
*/
|
||||
protected function create_courses_and_assignments() {
|
||||
// Create Courses, Users, and Assignments.
|
||||
$course1 = $this->getDataGenerator()->create_course(['shortname' => 'course1']);
|
||||
$course2 = $this->getDataGenerator()->create_course(['shortname' => 'course2']);
|
||||
|
||||
$teacher1 = $this->getDataGenerator()->create_user(['username' => 'teacher1']);
|
||||
$teacher2 = $this->getDataGenerator()->create_user(['username' => 'teacher2']);
|
||||
|
||||
$student1 = $this->getDataGenerator()->create_user(['username' => 'student1']);
|
||||
$student2 = $this->getDataGenerator()->create_user(['username' => 'student2']);
|
||||
|
||||
$this->course1students = [
|
||||
$student1
|
||||
];
|
||||
|
||||
$this->course2students = [
|
||||
$student2
|
||||
];
|
||||
|
||||
$course1assignment1 = $this->getDataGenerator()->create_module('assignment',
|
||||
[
|
||||
'course' => $course1->id,
|
||||
'name' => 'Course 1 - Assignment 1 (onlinetext)',
|
||||
'assignmenttype' => 'onlinetext',
|
||||
]
|
||||
);
|
||||
$course1assignment2 = $this->getDataGenerator()->create_module('assignment',
|
||||
[
|
||||
'course' => $course1->id,
|
||||
'name' => 'Course 1 - Assignment 2 (single file upload)',
|
||||
'assignmenttype' => 'uploadsingle',
|
||||
]
|
||||
);
|
||||
$course2assignment1 = $this->getDataGenerator()->create_module('assignment',
|
||||
[
|
||||
'course' => $course2->id,
|
||||
'name' => 'Course 2 - Assignment 1 (offline)',
|
||||
'assignmenttype' => 'offline',
|
||||
]
|
||||
);
|
||||
$course2assignment2 = $this->getDataGenerator()->create_module('assignment',
|
||||
[
|
||||
'course' => $course2->id,
|
||||
'name' => 'Course 2 - Assignment 2 (multiple file upload)',
|
||||
'assignmenttype' => 'upload',
|
||||
]
|
||||
);
|
||||
|
||||
// Teacher 1 add test assignment submission for Course 1 - Assignment 1.
|
||||
$this->add_assignment_submission(
|
||||
$course1assignment1,
|
||||
$teacher1,
|
||||
"Course 1 - Ass 1: Teacher Test Submission"
|
||||
);
|
||||
|
||||
// Student 1 add assignment submissions for Course 1 - Assignment 1 and 2.
|
||||
$this->add_assignment_submission(
|
||||
$course1assignment1,
|
||||
$student1,
|
||||
"Course 1 - Ass 1: " . $student1->id
|
||||
);
|
||||
$this->add_file_assignment_submission(
|
||||
$course1assignment2,
|
||||
$student1,
|
||||
"Course 1 - Ass 2: " . $student1->id,
|
||||
'Student' . $student1->id . '-Course1-Ass2'
|
||||
);
|
||||
|
||||
// Student 2 add assignment submissions for Course 2 - Assignment 1 and 2.
|
||||
$this->add_assignment_submission(
|
||||
$course2assignment1,
|
||||
$student2,
|
||||
"Course 2 - Ass 1: " . $student2->id
|
||||
);
|
||||
$this->add_file_assignment_submission(
|
||||
$course2assignment2,
|
||||
$student2,
|
||||
"Course 2 - Ass 2: " . $student2->id,
|
||||
'Student' . $student2->id . '-Course2-Ass2',
|
||||
2
|
||||
);
|
||||
|
||||
// Teacher 1 to mark assignment submissions for Course 1's Assignment 1 and 2.
|
||||
$course1submissions = $this->get_course_assignment_submissions($course1->id);
|
||||
foreach ($course1submissions as $submission) {
|
||||
$this->mark_assignment_submission($submission->assignment, $submission->id, $teacher1, 49);
|
||||
}
|
||||
|
||||
// Teacher 1 to mark assignment submissions for Course 2's Assignment 1 and 2.
|
||||
$course2submissions = $this->get_course_assignment_submissions($course2->id);
|
||||
foreach ($course2submissions as $submission) {
|
||||
$this->mark_assignment_submission($submission->assignment, $submission->id, $teacher1, 50);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to add an assignment submission for testing.
|
||||
*
|
||||
* @param object $assignment Object containing assignment submission details to create for testing.
|
||||
* @param object $user Object of the user making the assignment submission.
|
||||
* @param string $submissiondata The onlintext string value of the assignment submission.
|
||||
* @throws dml_exception
|
||||
*/
|
||||
protected function add_assignment_submission($assignment, $user, $submissiondata) {
|
||||
global $DB;
|
||||
|
||||
$submission = (object) [
|
||||
'assignment' => $assignment->id,
|
||||
'userid' => $user->id,
|
||||
'timecreated' => date('U'),
|
||||
'data1' => '<p>' . $submissiondata . '</p>',
|
||||
'submissioncomment' => 'My submission by ' . $user->username
|
||||
];
|
||||
|
||||
return $DB->insert_record('assignment_submissions', $submission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to add an assignment submission with file submissions for testing.
|
||||
*
|
||||
* @param object $assignment Object containing assignment submission details to create for testing.
|
||||
* @param object $user Object of the user making the assignment submission.
|
||||
* @param string $submissiondata The onlintext string value of the assignment submission.
|
||||
* @param string $filename The filename of the file submission included with the assignment submission.
|
||||
* @param int $numfiles The number of files included with the assignment submission.
|
||||
* @throws dml_exception
|
||||
* @throws file_exception
|
||||
* @throws stored_file_creation_exception
|
||||
*/
|
||||
protected function add_file_assignment_submission($assignment, $user, $submissiondata, $filename, $numfiles = 1) {
|
||||
global $CFG, $DB;
|
||||
|
||||
$submission = (object) [
|
||||
'assignment' => $assignment->id,
|
||||
'userid' => $user->id,
|
||||
'timecreated' => date('U'),
|
||||
'data1' => '<p>' . $submissiondata . '</p>',
|
||||
'numfiles' => $numfiles,
|
||||
'submissioncomment' => 'My submission by ' . $user->username
|
||||
];
|
||||
|
||||
$submissionid = $DB->insert_record('assignment_submissions', $submission);
|
||||
|
||||
// Create a file submission with the test pdf.
|
||||
$this->setUser($user->id);
|
||||
$context = context_module::instance($assignment->cmid);
|
||||
|
||||
$fs = get_file_storage();
|
||||
$sourcefile = $CFG->dirroot . '/mod/assign/feedback/editpdf/tests/fixtures/submission.pdf';
|
||||
|
||||
for ($f = 1; $f <= $numfiles; $f++) {
|
||||
$pdfsubmission = (object)array(
|
||||
'contextid' => $context->id,
|
||||
'component' => 'mod_assignment',
|
||||
'filearea' => 'submission',
|
||||
'itemid' => $submissionid,
|
||||
'filepath' => '/',
|
||||
'filename' => $filename . "-(File $f of $numfiles)"
|
||||
);
|
||||
$fs->create_file_from_pathname($pdfsubmission, $sourcefile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to retrieve the assignment submission records for a given course.
|
||||
*
|
||||
* @param int $courseid The course ID to get assignment submissions by.
|
||||
* @return array Array of assignment submission details.
|
||||
* @throws dml_exception
|
||||
*/
|
||||
protected function get_course_assignment_submissions($courseid) {
|
||||
global $DB;
|
||||
|
||||
$sql = "SELECT s.id,
|
||||
s.assignment,
|
||||
s.userid,
|
||||
s.timecreated,
|
||||
s.timemodified,
|
||||
s.numfiles,
|
||||
s.data1,
|
||||
s.data2,
|
||||
s.grade,
|
||||
s.submissioncomment,
|
||||
s.format,
|
||||
s.teacher,
|
||||
s.timemarked,
|
||||
s.mailed
|
||||
FROM {assignment} a
|
||||
JOIN {assignment_submissions} s ON s.assignment = a.id
|
||||
WHERE a.course = :courseid";
|
||||
$params = [
|
||||
'courseid' => $courseid
|
||||
];
|
||||
|
||||
return $DB->get_records_sql($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to update an assignment submission with grading details for a teacher.
|
||||
*
|
||||
* @param int $assignmentid The assignment ID to update assignment submissions with marking/graded details.
|
||||
* @param int $submissionid The assignment submission ID to update with marking/grading details.
|
||||
* @param int $teacher The teacher user ID to making the marking/grading details.
|
||||
* @param int $gradedata The grade value set for the marking/grading details.
|
||||
*/
|
||||
protected function mark_assignment_submission($assignmentid, $submissionid, $teacher, $gradedata) {
|
||||
global $DB;
|
||||
|
||||
$submission = (object) [
|
||||
'id' => $submissionid,
|
||||
'assignment' => $assignmentid,
|
||||
'grade' => $gradedata,
|
||||
'teacher' => $teacher->id,
|
||||
'timemarked' => date('U')
|
||||
];
|
||||
|
||||
return $DB->update_record('assignment_submissions', $submission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to retrieve the assignment records for a given context.
|
||||
*
|
||||
* @param int $contextid The context module ID value to retrieve assignment IDs by.
|
||||
* @return array Array of assignment IDs.
|
||||
* @throws dml_exception
|
||||
*/
|
||||
protected function get_assignments($contextid) {
|
||||
global $DB;
|
||||
|
||||
$sql = "SELECT a.id
|
||||
FROM {assignment} a
|
||||
JOIN {course_modules} cm ON a.id = cm.instance
|
||||
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
|
||||
JOIN {context} ctx ON ctx.instanceid = cm.id AND ctx.contextlevel = :contextmodule
|
||||
WHERE ctx.id = :contextid";
|
||||
$params = [
|
||||
'modulename' => 'assignment',
|
||||
'contextmodule' => CONTEXT_MODULE,
|
||||
'contextid' => $contextid
|
||||
];
|
||||
|
||||
return $DB->get_records_sql($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to retrieve the assignment submission records for a given context.
|
||||
*
|
||||
* @param int $contextid The context module ID value to retrieve assignment submission IDs by.
|
||||
* @return array Array of assignment submission IDs.
|
||||
* @throws dml_exception
|
||||
*/
|
||||
protected function get_assignment_submissions($contextid) {
|
||||
global $DB;
|
||||
|
||||
$sql = "SELECT s.id
|
||||
FROM {assignment_submissions} s
|
||||
JOIN {assignment} a ON a.id = s.assignment
|
||||
JOIN {course_modules} cm ON a.id = cm.instance
|
||||
JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
|
||||
JOIN {context} ctx ON ctx.instanceid = cm.id AND ctx.contextlevel = :contextmodule
|
||||
WHERE ctx.id = :contextid";
|
||||
$params = [
|
||||
'modulename' => 'assignment',
|
||||
'contextmodule' => CONTEXT_MODULE,
|
||||
'contextid' => $contextid
|
||||
];
|
||||
|
||||
return $DB->get_records_sql($sql, $params);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user