MDL-63513 mod_assignment: Add removal of context users.
[moodle.git] / mod / assignment / tests / privacy_test.php
blob18dbb41af2f4fd2483ec4aca89a511996d428c5e
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 /**
18 * Privacy test for the event monitor
20 * @package mod_assignment
21 * @category test
22 * @copyright 2018 Zig Tan <zig@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') || die();
28 require_once(__DIR__ . '/../lib.php');
30 use \mod_assignment\privacy\provider;
31 use \core_privacy\local\metadata\collection;
32 use \core_privacy\local\request\approved_contextlist;
33 use \core_privacy\local\request\transform;
34 use \core_privacy\local\request\writer;
35 use \core_privacy\tests\provider_testcase;
37 /**
38 * Privacy test for the event monitor
40 * @package mod_assignment
41 * @category test
42 * @copyright 2018 Zig Tan <zig@moodle.com>
43 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
45 class mod_assignment_privacy_testcase extends advanced_testcase {
47 /**
48 * @var int array Array of test student ids associated for Course 1.
50 private $course1students = [];
52 /**
53 * @var int array Array of test student ids associated for Course 2.
55 private $course2students = [];
57 /**
58 * @var int array Array of test assignments associated for Course 1.
60 private $course1assignments = [];
62 /**
63 * @var int array Array of test assignments associated for Course 2.
65 private $course2assignments = [];
67 /**
68 * Test for provider::get_contexts_for_userid().
70 * @throws coding_exception
72 public function test_get_contexts_for_userid() {
73 global $DB;
75 $this->resetAfterTest(true);
76 $this->create_courses_and_assignments();
78 // Get Teacher 1 to test get_contexts_for_userid().
79 $teacher1 = $DB->get_record('user', ['username' => 'teacher1']);
80 $contextids = provider::get_contexts_for_userid($teacher1->id);
81 // Verify there should be 4 contexts, as Teacher 1 has submitted tests and marked Assignments in Course 1 and 2.
82 $this->assertEquals(4, count($contextids->get_contextids()));
84 // Get Teacher 2 to test get_contexts_for_userid().
85 $teacher2 = $DB->get_record('user', ['username' => 'teacher2']);
86 $contextids = provider::get_contexts_for_userid($teacher2->id);
87 // Verify there should be 0 contexts, as teacher 2 has not marked any Assignments.
88 $this->assertEquals(0, count($contextids->get_contextids()));
90 // Get Student 1 to test get_contexts_for_userid().
91 $student1 = $DB->get_record('user', ['username' => 'student1']);
92 $contextids = provider::get_contexts_for_userid($student1->id);
93 // Verify there should be 2 contexts, as student 1 added submissions for both Assignments in Course 1.
94 $this->assertEquals(2, count($contextids->get_contextids()));
96 // Get Student 2 to test get_contexts_for_userid().
97 $student2 = $DB->get_record('user', ['username' => 'student2']);
98 $contextids = provider::get_contexts_for_userid($student2->id);
99 // Verify there should be 2 context, as student 2 added submissions for both Assignments in Course 2.
100 $this->assertEquals(2, count($contextids->get_contextids()));
104 * Test that the correct userids are returned for a specific context.
106 public function test_get_users_in_context() {
108 $this->resetAfterTest(true);
110 $student1 = $this->getDataGenerator()->create_user(['username' => 'student1']);
111 $student2 = $this->getDataGenerator()->create_user(['username' => 'student2']);
112 // Student 3 should not turn up in the results of this test.
113 $student3 = $this->getDataGenerator()->create_user(['username' => 'student3']);
114 $teacher1 = $this->getDataGenerator()->create_user(['username' => 'teacher1']);
116 $course = $this->getDataGenerator()->create_course();
117 $course1assignment1 = $this->getDataGenerator()->create_module('assignment',
119 'course' => $course->id,
120 'name' => 'Course 1 - Assignment 1 (onlinetext)',
121 'assignmenttype' => 'onlinetext',
124 // Create a second assignment in the same course.
125 $course1assignment2 = $this->getDataGenerator()->create_module('assignment',
127 'course' => $course->id,
128 'name' => 'Course 1 - Assignment 1 (onlinetext)',
129 'assignmenttype' => 'onlinetext',
133 $this->add_assignment_submission(
134 $course1assignment1,
135 $student1,
136 "Course 1 - Ass 1: Student1 Test Submission"
139 $this->add_assignment_submission(
140 $course1assignment1,
141 $student2,
142 "Course 1 - Ass 1: Student2 Test Submission"
144 // Add a submission for the second assignment.
145 $this->add_assignment_submission(
146 $course1assignment2,
147 $student3,
148 "Course 1 - Ass 2: Student3 Test Submission"
151 $submissions = $this->get_course_assignment_submissions($course->id);
152 foreach ($submissions as $submission) {
153 $this->mark_assignment_submission($submission->assignment, $submission->id, $teacher1, 50);
156 $c1ass1ctx = context_module::instance($course1assignment1->cmid);
157 $userlist = new \core_privacy\local\request\userlist($c1ass1ctx, 'mod_assignment');
159 provider::get_users_in_context($userlist);
160 $userids = $userlist->get_userids();
162 // This is both students and the teacher who marked both assignments.
163 $this->assertCount(3, $userids);
164 // Make sure that student 3 is not in the returned userids.
165 $this->assertFalse(in_array($student3->id, $userids));
166 // Try with the course context.
167 $coursecontext = context_course::instance($course->id);
168 $userlist = new \core_privacy\local\request\userlist($coursecontext, 'mod_assignment');
169 provider::get_users_in_context($userlist);
170 $this->assertEmpty($userlist->get_userids());
174 * Test for provider::export_user_data().
176 * @throws coding_exception
178 public function test_export_user_data_teacher() {
179 global $DB;
181 $this->resetAfterTest(true);
182 $this->create_courses_and_assignments();
184 // Test Teacher 1 export_data_for_user() - marking assignment submissions for both Course 1 and 2.
185 $teacher1 = $DB->get_record('user', ['username' => 'teacher1']);
187 $contextlist = provider::get_contexts_for_userid($teacher1->id);
188 $approvedcontextlist = new approved_contextlist($teacher1, 'mod_assignment', $contextlist->get_contextids());
190 // Verify Teacher 1 has four contexts.
191 $this->assertCount(4, $contextlist->get_contextids());
193 // Retrieve Assignment Submissions data for Teacher 1.
194 provider::export_user_data($approvedcontextlist);
196 $contexts = $contextlist->get_contexts();
198 // Context 1 - Course 1's Assignment 1 -- (onlinetext).
199 $context = context_module::instance($this->course1assignments['ass1']->cmid);
200 $this->assertContains($context, $contexts);
202 $writer = writer::with_context($context);
203 $subcontexts = [
204 get_string('privacy:markedsubmissionspath', 'mod_assignment'),
205 transform::user($teacher1->id)
207 // Verify the test assignment submission from Teacher 1 exists.
208 $submission = $writer->get_data($subcontexts);
209 $this->assertEquals('<p>Course 1 - Ass 1: Teacher Test Submission</p>', $submission->data1);
211 foreach ($this->course1students as $student) {
212 $subcontexts = [
213 get_string('privacy:markedsubmissionspath', 'mod_assignment'),
214 transform::user($student->id)
216 // Verify the student assignment submissions exists.
217 $submission = $writer->get_data($subcontexts);
218 $this->assertEquals("<p>Course 1 - Ass 1: " . $student->id . "</p>", $submission->data1);
221 // Context 2 - Course 1's Assignment 2 -- (single file upload).
222 $context = context_module::instance($this->course1assignments['ass2']->cmid);
223 $this->assertContains($context, $contexts);
225 $writer = writer::with_context($context);
226 foreach ($this->course1students as $student) {
227 $subcontexts = [
228 get_string('privacy:markedsubmissionspath', 'mod_assignment'),
229 transform::user($student->id)
231 // Verify the student assignment submissions exists.
232 $submission = $writer->get_data($subcontexts);
233 $this->assertEquals("<p>Course 1 - Ass 2: " . $student->id . "</p>", $submission->data1);
235 // Verify the student assignment submission file upload exists.
236 $submissionfiles = $writer->get_files($subcontexts);
237 $this->assertTrue(array_key_exists('Student' . $student->id . '-Course1-Ass2-(File 1 of 1)', $submissionfiles));
240 // Context 3 - Course 2's Assignment 1 -- (offline).
241 $context = context_module::instance($this->course2assignments['ass1']->cmid);
242 $this->assertContains($context, $contexts);
244 $writer = writer::with_context($context);
245 foreach ($this->course2students as $student) {
246 $subcontexts = [
247 get_string('privacy:markedsubmissionspath', 'mod_assignment'),
248 transform::user($student->id)
250 // Verify the student assignment submissions exists.
251 $submission = $writer->get_data($subcontexts);
252 $this->assertEquals("<p>Course 2 - Ass 1: " . $student->id . "</p>", $submission->data1);
255 // Context 4 - Course 2's Assignment 2 -- (multiple file upload).
256 $context = context_module::instance($this->course2assignments['ass2']->cmid);
257 $this->assertContains($context, $contexts);
259 $writer = writer::with_context($context);
260 foreach ($this->course2students as $student) {
261 $subcontexts = [
262 get_string('privacy:markedsubmissionspath', 'mod_assignment'),
263 transform::user($student->id)
265 // Verify the student assignment submissions exists.
266 $submission = $writer->get_data($subcontexts);
267 $this->assertEquals("<p>Course 2 - Ass 2: " . $student->id . "</p>", $submission->data1);
269 // Verify the student assignment submission file upload exists.
270 $submissionfiles = $writer->get_files($subcontexts);
271 $this->assertTrue(array_key_exists('Student' . $student->id . '-Course2-Ass2-(File 1 of 2)', $submissionfiles));
272 $this->assertTrue(array_key_exists('Student' . $student->id . '-Course2-Ass2-(File 2 of 2)', $submissionfiles));
277 * Test for provider::export_user_data().
279 * @throws dml_exception
281 public function test_export_user_data_student() {
282 global $DB;
284 $this->resetAfterTest(true);
285 $this->create_courses_and_assignments();
287 // Test Student 1 export_data_for_user() - added assignment submissions for both assignments in Course 1.
288 $student1 = $DB->get_record('user', ['username' => 'student1']);
290 $contextlist = provider::get_contexts_for_userid($student1->id);
291 $approvedcontextlist = new approved_contextlist($student1, 'mod_assignment', $contextlist->get_contextids());
293 // Retrieve Assignment Submissions data for Student 1.
294 provider::export_user_data($approvedcontextlist);
295 $contexts = $contextlist->get_contexts();
297 // Context 1 - Course 1's Assignment 1 -- (onlinetext).
298 $context = context_module::instance($this->course1assignments['ass1']->cmid);
299 $this->assertContains($context, $contexts);
301 $writer = writer::with_context($context);
302 $subcontexts = [
303 get_string('privacy:submissionpath', 'mod_assignment')
306 // Verify the student assignment submissions exists.
307 $submission = $writer->get_data($subcontexts);
308 $this->assertEquals("<p>Course 1 - Ass 1: " . $student1->id . "</p>", $submission->data1);
310 // Context 2 - Course 1's Assignment 2 -- (single file upload).
311 $context = context_module::instance($this->course1assignments['ass2']->cmid);
312 $this->assertContains($context, $contexts);
314 $writer = writer::with_context($context);
315 $subcontexts = [
316 get_string('privacy:submissionpath', 'mod_assignment')
319 // Verify the student assignment submission exists.
320 $submission = $writer->get_data($subcontexts);
321 $this->assertEquals("<p>Course 1 - Ass 2: " . $student1->id . "</p>", $submission->data1);
323 // Verify the student assignment submission file upload exists.
324 $submissionfiles = $writer->get_files($subcontexts);
325 $this->assertTrue(array_key_exists('Student' . $student1->id . '-Course1-Ass2-(File 1 of 1)', $submissionfiles));
327 // Test Student 2 export_data_for_user() - added assignment submissions for both assignments in Course 2.
328 $student2 = $DB->get_record('user', ['username' => 'student2']);
330 $contextlist = provider::get_contexts_for_userid($student2->id);
331 $approvedcontextlist = new approved_contextlist($student2, 'mod_assignment', $contextlist->get_contextids());
333 // Retrieve Assignment Submissions data for Student 2.
334 provider::export_user_data($approvedcontextlist);
335 $contexts = $contextlist->get_contexts();
337 // Context 1 - Course 2's Assignment 1 -- (offline).
338 $context = context_module::instance($this->course2assignments['ass1']->cmid);
339 $this->assertContains($context, $contexts);
341 $writer = writer::with_context($context);
342 $subcontexts = [
343 get_string('privacy:submissionpath', 'mod_assignment')
346 // Verify the student assignment submissions exists.
347 $submission = $writer->get_data($subcontexts);
348 $this->assertEquals("<p>Course 2 - Ass 1: " . $student2->id . "</p>", $submission->data1);
350 // Context 2 - Course 2's Assignment 2 -- (multiple file upload).
351 $context = context_module::instance($this->course2assignments['ass2']->cmid);
352 $this->assertContains($context, $contexts);
354 $writer = writer::with_context($context);
355 $subcontexts = [
356 get_string('privacy:submissionpath', 'mod_assignment')
359 // Verify the student assignment submission exists.
360 $submission = $writer->get_data($subcontexts);
361 $this->assertEquals("<p>Course 2 - Ass 2: " . $student2->id . "</p>", $submission->data1);
363 // Verify the student assignment submission file upload exists.
364 $submissionfiles = $writer->get_files($subcontexts);
365 $this->assertTrue(array_key_exists('Student' . $student2->id . '-Course2-Ass2-(File 1 of 2)', $submissionfiles));
366 $this->assertTrue(array_key_exists('Student' . $student2->id . '-Course2-Ass2-(File 2 of 2)', $submissionfiles));
370 * Test for provider::delete_data_for_all_users_in_context().
372 * @throws dml_exception
374 public function test_delete_data_for_all_users_in_context() {
375 global $DB;
377 $this->resetAfterTest(true);
378 $this->create_courses_and_assignments();
380 // Test teacher1 delete_data_for_all_users_in_context().
381 $teacher1 = $DB->get_record('user', ['username' => 'teacher1']);
382 $contextlist = provider::get_contexts_for_userid($teacher1->id);
384 foreach ($contextlist as $context) {
385 provider::delete_data_for_all_users_in_context($context);
387 // Verify assignment submission(s) were deleted for the context.
388 $deleted = $this->get_assignment_submissions($context->id);
389 $this->assertCount(0, $deleted);
391 // Verify all the file submissions associated with the context for all users were deleted.
392 $files = $DB->get_records('files', ['component' => 'mod_assignment', 'filearea' => 'submission', 'contextid' => $context->id]);
393 $this->assertEquals(0, count($files));
398 * Test for provider::delete_data_for_user().
400 * @throws dml_exception
402 public function test_delete_data_for_user() {
403 global $DB;
405 $this->resetAfterTest(true);
406 $this->create_courses_and_assignments();
408 // Test Teacher 1 delete_data_for_user(), should only remove the 1 test submission added by Teacher 1.
409 // Should not remove any assignment submission records marked by the teacher.
410 $teacher1 = $DB->get_record('user', ['username' => 'teacher1']);
411 $contextlist = provider::get_contexts_for_userid($teacher1->id);
412 $approvedcontextlist = new approved_contextlist($teacher1, 'mod_assignment', $contextlist->get_contextids());
413 provider::delete_data_for_user($approvedcontextlist);
415 // Verify the submissions submitted by students still exists.
416 $markedsubmissions = $DB->get_records('assignment_submissions', ['teacher' => $teacher1->id]);
417 $this->assertCount(4, $markedsubmissions);
419 // Test student 1 delete_data_for_user().
420 $student1 = $DB->get_record('user', ['username' => 'student1']);
421 $contextlist = provider::get_contexts_for_userid($student1->id);
422 $approvedcontextlist = new approved_contextlist($student1, 'mod_assignment', $contextlist->get_contextids());
423 provider::delete_data_for_user($approvedcontextlist);
425 // Verify student 1's assignment submissions were deleted.
426 $assignmentsubmissions = $DB->get_records('assignment_submissions', ['userid' => $student1->id]);
427 $this->assertEquals(0, count($assignmentsubmissions));
429 // Verify student 1's file submissions were deleted.
430 foreach ($contextlist->get_contextids() as $contextid) {
431 $files = $DB->get_records('files', ['component' => 'mod_assignment', 'filearea' => 'submission', 'contextid' => $contextid]);
432 $this->assertEquals(0, count($files));
437 * Test the deletion of a data for users.
439 public function test_delete_data_for_users() {
440 global $DB;
441 $this->resetAfterTest();
443 $student1 = $this->getDataGenerator()->create_user(['username' => 'student1']);
444 $student2 = $this->getDataGenerator()->create_user(['username' => 'student2']);
445 $student3 = $this->getDataGenerator()->create_user(['username' => 'student3']);
447 $course = $this->getDataGenerator()->create_course();
448 $course1assignment = $this->getDataGenerator()->create_module('assignment',
450 'course' => $course->id,
451 'name' => 'Course 1 - Assignment 1 (single file upload)',
452 'assignmenttype' => 'uploadsingle'
455 $context = context_module::instance($course1assignment->cmid);
457 // Student one submission.
458 $this->add_file_assignment_submission(
459 $course1assignment,
460 $student1,
461 "Course 1 - Ass 2: " . $student1->id,
462 'Student' . $student1->id . '-Course1-Ass2'
464 // Student two submission.
465 $this->add_file_assignment_submission(
466 $course1assignment,
467 $student2,
468 "Course 1 - Ass 2: " . $student2->id,
469 'Student' . $student2->id . '-Course1-Ass2'
471 // Student three submission to be retained.
472 $this->add_file_assignment_submission(
473 $course1assignment,
474 $student3,
475 "Course 1 - Ass 2: " . $student3->id,
476 'Student' . $student3->id . '-Course1-Ass2'
479 $files = $DB->get_records('files', [
480 'component' => 'mod_assignment',
481 'filearea' => 'submission',
482 'contextid' => $context->id
484 $this->assertCount(6, $files);
486 $submissions = $this->get_assignment_submissions($context->id);
487 $this->assertCount(3, $submissions);
489 $userlist = new \core_privacy\local\request\approved_userlist($context, 'mod_assignment', [$student1->id, $student2->id]);
490 provider::delete_data_for_users($userlist);
492 $files = $DB->get_records('files', [
493 'component' => 'mod_assignment',
494 'filearea' => 'submission',
495 'contextid' => $context->id
497 $this->assertCount(2, $files);
499 $submissions = $this->get_assignment_submissions($context->id);
500 $this->assertCount(1, $submissions);
503 // Start of helper functions.
506 * Helper function to setup Course, users, and assignments for testing.
508 protected function create_courses_and_assignments() {
509 // Create Courses, Users, and Assignments.
510 $course1 = $this->getDataGenerator()->create_course(['shortname' => 'course1']);
511 $course2 = $this->getDataGenerator()->create_course(['shortname' => 'course2']);
513 $teacher1 = $this->getDataGenerator()->create_user(['username' => 'teacher1']);
514 $teacher2 = $this->getDataGenerator()->create_user(['username' => 'teacher2']);
516 $student1 = $this->getDataGenerator()->create_user(['username' => 'student1']);
517 $student2 = $this->getDataGenerator()->create_user(['username' => 'student2']);
519 $this->course1students = [
520 $student1
523 $this->course2students = [
524 $student2
527 $course1assignment1 = $this->getDataGenerator()->create_module('assignment',
529 'course' => $course1->id,
530 'name' => 'Course 1 - Assignment 1 (onlinetext)',
531 'assignmenttype' => 'onlinetext',
534 $course1assignment2 = $this->getDataGenerator()->create_module('assignment',
536 'course' => $course1->id,
537 'name' => 'Course 1 - Assignment 2 (single file upload)',
538 'assignmenttype' => 'uploadsingle',
542 $this->course1assignments = [
543 'ass1' => $course1assignment1,
544 'ass2' => $course1assignment2
547 $course2assignment1 = $this->getDataGenerator()->create_module('assignment',
549 'course' => $course2->id,
550 'name' => 'Course 2 - Assignment 1 (offline)',
551 'assignmenttype' => 'offline',
554 $course2assignment2 = $this->getDataGenerator()->create_module('assignment',
556 'course' => $course2->id,
557 'name' => 'Course 2 - Assignment 2 (multiple file upload)',
558 'assignmenttype' => 'upload',
562 $this->course2assignments = [
563 'ass1' => $course2assignment1,
564 'ass2' => $course2assignment2
567 // Teacher 1 add test assignment submission for Course 1 - Assignment 1.
568 $this->add_assignment_submission(
569 $course1assignment1,
570 $teacher1,
571 "Course 1 - Ass 1: Teacher Test Submission"
574 // Student 1 add assignment submissions for Course 1 - Assignment 1 and 2.
575 $this->add_assignment_submission(
576 $course1assignment1,
577 $student1,
578 "Course 1 - Ass 1: " . $student1->id
580 $this->add_file_assignment_submission(
581 $course1assignment2,
582 $student1,
583 "Course 1 - Ass 2: " . $student1->id,
584 'Student' . $student1->id . '-Course1-Ass2'
587 // Student 2 add assignment submissions for Course 2 - Assignment 1 and 2.
588 $this->add_assignment_submission(
589 $course2assignment1,
590 $student2,
591 "Course 2 - Ass 1: " . $student2->id
593 $this->add_file_assignment_submission(
594 $course2assignment2,
595 $student2,
596 "Course 2 - Ass 2: " . $student2->id,
597 'Student' . $student2->id . '-Course2-Ass2',
601 // Teacher 1 to mark assignment submissions for Course 1's Assignment 1 and 2.
602 $course1submissions = $this->get_course_assignment_submissions($course1->id);
603 foreach ($course1submissions as $submission) {
604 $this->mark_assignment_submission($submission->assignment, $submission->id, $teacher1, 49);
607 // Teacher 1 to mark assignment submissions for Course 2's Assignment 1 and 2.
608 $course2submissions = $this->get_course_assignment_submissions($course2->id);
609 foreach ($course2submissions as $submission) {
610 $this->mark_assignment_submission($submission->assignment, $submission->id, $teacher1, 50);
615 * Helper function to add an assignment submission for testing.
617 * @param object $assignment Object containing assignment submission details to create for testing.
618 * @param object $user Object of the user making the assignment submission.
619 * @param string $submissiondata The onlintext string value of the assignment submission.
620 * @throws dml_exception
622 protected function add_assignment_submission($assignment, $user, $submissiondata) {
623 global $DB;
625 $submission = (object) [
626 'assignment' => $assignment->id,
627 'userid' => $user->id,
628 'timecreated' => date('U'),
629 'data1' => '<p>' . $submissiondata . '</p>',
630 'submissioncomment' => 'My submission by ' . $user->username
633 return $DB->insert_record('assignment_submissions', $submission);
637 * Helper function to add an assignment submission with file submissions for testing.
639 * @param object $assignment Object containing assignment submission details to create for testing.
640 * @param object $user Object of the user making the assignment submission.
641 * @param string $submissiondata The onlintext string value of the assignment submission.
642 * @param string $filename The filename of the file submission included with the assignment submission.
643 * @param int $numfiles The number of files included with the assignment submission.
644 * @throws dml_exception
645 * @throws file_exception
646 * @throws stored_file_creation_exception
648 protected function add_file_assignment_submission($assignment, $user, $submissiondata, $filename, $numfiles = 1) {
649 global $CFG, $DB;
651 $submission = (object) [
652 'assignment' => $assignment->id,
653 'userid' => $user->id,
654 'timecreated' => date('U'),
655 'data1' => '<p>' . $submissiondata . '</p>',
656 'numfiles' => $numfiles,
657 'submissioncomment' => 'My submission by ' . $user->username
660 $submissionid = $DB->insert_record('assignment_submissions', $submission);
662 // Create a file submission with the test pdf.
663 $this->setUser($user->id);
664 $context = context_module::instance($assignment->cmid);
666 $fs = get_file_storage();
667 $sourcefile = $CFG->dirroot . '/mod/assign/feedback/editpdf/tests/fixtures/submission.pdf';
669 for ($f = 1; $f <= $numfiles; $f++) {
670 $pdfsubmission = (object)array(
671 'contextid' => $context->id,
672 'component' => 'mod_assignment',
673 'filearea' => 'submission',
674 'itemid' => $submissionid,
675 'filepath' => '/',
676 'filename' => $filename . "-(File $f of $numfiles)"
678 $fs->create_file_from_pathname($pdfsubmission, $sourcefile);
683 * Helper function to retrieve the assignment submission records for a given course.
685 * @param int $courseid The course ID to get assignment submissions by.
686 * @return array Array of assignment submission details.
687 * @throws dml_exception
689 protected function get_course_assignment_submissions($courseid) {
690 global $DB;
692 $sql = "SELECT s.id,
693 s.assignment,
694 s.userid,
695 s.timecreated,
696 s.timemodified,
697 s.numfiles,
698 s.data1,
699 s.data2,
700 s.grade,
701 s.submissioncomment,
702 s.format,
703 s.teacher,
704 s.timemarked,
705 s.mailed
706 FROM {assignment} a
707 JOIN {assignment_submissions} s ON s.assignment = a.id
708 WHERE a.course = :courseid";
709 $params = [
710 'courseid' => $courseid
713 return $DB->get_records_sql($sql, $params);
717 * Helper function to update an assignment submission with grading details for a teacher.
719 * @param int $assignmentid The assignment ID to update assignment submissions with marking/graded details.
720 * @param int $submissionid The assignment submission ID to update with marking/grading details.
721 * @param int $teacher The teacher user ID to making the marking/grading details.
722 * @param int $gradedata The grade value set for the marking/grading details.
724 protected function mark_assignment_submission($assignmentid, $submissionid, $teacher, $gradedata) {
725 global $DB;
727 $submission = (object) [
728 'id' => $submissionid,
729 'assignment' => $assignmentid,
730 'grade' => $gradedata,
731 'teacher' => $teacher->id,
732 'timemarked' => date('U')
735 return $DB->update_record('assignment_submissions', $submission);
739 * Helper function to retrieve the assignment records for a given context.
741 * @param int $contextid The context module ID value to retrieve assignment IDs by.
742 * @return array Array of assignment IDs.
743 * @throws dml_exception
745 protected function get_assignments($contextid) {
746 global $DB;
748 $sql = "SELECT a.id
749 FROM {assignment} a
750 JOIN {course_modules} cm ON a.id = cm.instance
751 JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
752 JOIN {context} ctx ON ctx.instanceid = cm.id AND ctx.contextlevel = :contextmodule
753 WHERE ctx.id = :contextid";
754 $params = [
755 'modulename' => 'assignment',
756 'contextmodule' => CONTEXT_MODULE,
757 'contextid' => $contextid
760 return $DB->get_records_sql($sql, $params);
764 * Helper function to retrieve the assignment submission records for a given context.
766 * @param int $contextid The context module ID value to retrieve assignment submission IDs by.
767 * @return array Array of assignment submission IDs.
768 * @throws dml_exception
770 protected function get_assignment_submissions($contextid) {
771 global $DB;
773 $sql = "SELECT s.id
774 FROM {assignment_submissions} s
775 JOIN {assignment} a ON a.id = s.assignment
776 JOIN {course_modules} cm ON a.id = cm.instance
777 JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
778 JOIN {context} ctx ON ctx.instanceid = cm.id AND ctx.contextlevel = :contextmodule
779 WHERE ctx.id = :contextid";
780 $params = [
781 'modulename' => 'assignment',
782 'contextmodule' => CONTEXT_MODULE,
783 'contextid' => $contextid
786 return $DB->get_records_sql($sql, $params);