Differences Between: [Versions 39 and 310]
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. 13 // 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/>. 16 17 /** 18 * Privacy test for the event monitor 19 * 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 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 require_once (__DIR__ . '/../lib.php'); 29 30 use \mod_assignment\privacy\provider; 31 use \core_privacy\local\request\approved_contextlist; 32 use \core_privacy\local\request\transform; 33 use \core_privacy\local\request\writer; 34 use \core_privacy\tests\provider_testcase; 35 36 /** 37 * Privacy test for the event monitor 38 * 39 * @package mod_assignment 40 * @category test 41 * @copyright 2018 Zig Tan <zig@moodle.com> 42 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 43 */ 44 class mod_assignment_privacy_testcase extends provider_testcase { 45 46 /** 47 * @var int array Array of test student ids associated for Course 1. 48 */ 49 private $course1students = []; 50 51 /** 52 * @var int array Array of test student ids associated for Course 2. 53 */ 54 private $course2students = []; 55 56 /** 57 * @var int array Array of test assignments associated for Course 1. 58 */ 59 private $course1assignments = []; 60 61 /** 62 * @var int array Array of test assignments associated for Course 2. 63 */ 64 private $course2assignments = []; 65 66 /** 67 * Test for provider::get_contexts_for_userid(). 68 * 69 * @throws coding_exception 70 */ 71 public function test_get_contexts_for_userid() { 72 global $DB; 73 74 $this->resetAfterTest(true); 75 $this->create_courses_and_assignments(); 76 77 // Get Teacher 1 to test get_contexts_for_userid(). 78 $teacher1 = $DB->get_record('user', ['username' => 'teacher1']); 79 $contextids = provider::get_contexts_for_userid($teacher1->id); 80 // Verify there should be 4 contexts, as Teacher 1 has submitted tests and marked Assignments in Course 1 and 2. 81 $this->assertEquals(4, count($contextids->get_contextids())); 82 83 // Get Teacher 2 to test get_contexts_for_userid(). 84 $teacher2 = $DB->get_record('user', ['username' => 'teacher2']); 85 $contextids = provider::get_contexts_for_userid($teacher2->id); 86 // Verify there should be 0 contexts, as teacher 2 has not marked any Assignments. 87 $this->assertEquals(0, count($contextids->get_contextids())); 88 89 // Get Student 1 to test get_contexts_for_userid(). 90 $student1 = $DB->get_record('user', ['username' => 'student1']); 91 $contextids = provider::get_contexts_for_userid($student1->id); 92 // Verify there should be 2 contexts, as student 1 added submissions for both Assignments in Course 1. 93 $this->assertEquals(2, count($contextids->get_contextids())); 94 95 // Get Student 2 to test get_contexts_for_userid(). 96 $student2 = $DB->get_record('user', ['username' => 'student2']); 97 $contextids = provider::get_contexts_for_userid($student2->id); 98 // Verify there should be 2 context, as student 2 added submissions for both Assignments in Course 2. 99 $this->assertEquals(2, count($contextids->get_contextids())); 100 } 101 102 /** 103 * Test that the correct userids are returned for a specific context. 104 */ 105 public function test_get_users_in_context() { 106 107 $this->resetAfterTest(true); 108 109 $student1 = $this->getDataGenerator()->create_user(['username' => 'student1']); 110 $student2 = $this->getDataGenerator()->create_user(['username' => 'student2']); 111 // Student 3 should not turn up in the results of this test. 112 $student3 = $this->getDataGenerator()->create_user(['username' => 'student3']); 113 $teacher1 = $this->getDataGenerator()->create_user(['username' => 'teacher1']); 114 115 $course = $this->getDataGenerator()->create_course(); 116 $course1assignment1 = $this->getDataGenerator()->create_module('assignment', 117 [ 118 'course' => $course->id, 119 'name' => 'Course 1 - Assignment 1 (onlinetext)', 120 'assignmenttype' => 'onlinetext', 121 ] 122 ); 123 // Create a second assignment in the same course. 124 $course1assignment2 = $this->getDataGenerator()->create_module('assignment', 125 [ 126 'course' => $course->id, 127 'name' => 'Course 1 - Assignment 1 (onlinetext)', 128 'assignmenttype' => 'onlinetext', 129 ] 130 ); 131 132 $this->add_assignment_submission( 133 $course1assignment1, 134 $student1, 135 "Course 1 - Ass 1: Student1 Test Submission" 136 ); 137 138 $this->add_assignment_submission( 139 $course1assignment1, 140 $student2, 141 "Course 1 - Ass 1: Student2 Test Submission" 142 ); 143 // Add a submission for the second assignment. 144 $this->add_assignment_submission( 145 $course1assignment2, 146 $student3, 147 "Course 1 - Ass 2: Student3 Test Submission" 148 ); 149 150 $submissions = $this->get_course_assignment_submissions($course->id); 151 foreach ($submissions as $submission) { 152 $this->mark_assignment_submission($submission->assignment, $submission->id, $teacher1, 50); 153 } 154 155 $c1ass1ctx = context_module::instance($course1assignment1->cmid); 156 $userlist = new \core_privacy\local\request\userlist($c1ass1ctx, 'mod_assignment'); 157 158 provider::get_users_in_context($userlist); 159 $userids = $userlist->get_userids(); 160 161 // This is both students and the teacher who marked both assignments. 162 $this->assertCount(3, $userids); 163 // Make sure that student 3 is not in the returned userids. 164 $this->assertFalse(in_array($student3->id, $userids)); 165 // Try with the course context. 166 $coursecontext = context_course::instance($course->id); 167 $userlist = new \core_privacy\local\request\userlist($coursecontext, 'mod_assignment'); 168 provider::get_users_in_context($userlist); 169 $this->assertEmpty($userlist->get_userids()); 170 } 171 172 /** 173 * Test for provider::export_user_data(). 174 * 175 * @throws coding_exception 176 */ 177 public function test_export_user_data_teacher() { 178 global $DB; 179 180 $this->resetAfterTest(true); 181 $this->create_courses_and_assignments(); 182 183 // Test Teacher 1 export_data_for_user() - marking assignment submissions for both Course 1 and 2. 184 $teacher1 = $DB->get_record('user', ['username' => 'teacher1']); 185 186 $contextlist = provider::get_contexts_for_userid($teacher1->id); 187 $approvedcontextlist = new approved_contextlist($teacher1, 'mod_assignment', $contextlist->get_contextids()); 188 189 // Verify Teacher 1 has four contexts. 190 $this->assertCount(4, $contextlist->get_contextids()); 191 192 // Retrieve Assignment Submissions data for Teacher 1. 193 provider::export_user_data($approvedcontextlist); 194 195 $contexts = $contextlist->get_contexts(); 196 197 // Context 1 - Course 1's Assignment 1 -- (onlinetext). 198 $context = context_module::instance($this->course1assignments['ass1']->cmid); 199 $this->assertContains($context, $contexts); 200 201 $writer = writer::with_context($context); 202 $subcontexts = [ 203 get_string('privacy:markedsubmissionspath', 'mod_assignment'), 204 transform::user($teacher1->id) 205 ]; 206 // Verify the test assignment submission from Teacher 1 exists. 207 $submission = $writer->get_data($subcontexts); 208 $this->assertEquals('<p>Course 1 - Ass 1: Teacher Test Submission</p>', $submission->data1); 209 210 foreach ($this->course1students as $student) { 211 $subcontexts = [ 212 get_string('privacy:markedsubmissionspath', 'mod_assignment'), 213 transform::user($student->id) 214 ]; 215 // Verify the student assignment submissions exists. 216 $submission = $writer->get_data($subcontexts); 217 $this->assertEquals("<p>Course 1 - Ass 1: " . $student->id . "</p>", $submission->data1); 218 } 219 220 // Context 2 - Course 1's Assignment 2 -- (single file upload). 221 $context = context_module::instance($this->course1assignments['ass2']->cmid); 222 $this->assertContains($context, $contexts); 223 224 $writer = writer::with_context($context); 225 foreach ($this->course1students as $student) { 226 $subcontexts = [ 227 get_string('privacy:markedsubmissionspath', 'mod_assignment'), 228 transform::user($student->id) 229 ]; 230 // Verify the student assignment submissions exists. 231 $submission = $writer->get_data($subcontexts); 232 $this->assertEquals("<p>Course 1 - Ass 2: " . $student->id . "</p>", $submission->data1); 233 234 // Verify the student assignment submission file upload exists. 235 $submissionfiles = $writer->get_files($subcontexts); 236 $this->assertTrue(array_key_exists('Student' . $student->id . '-Course1-Ass2-(File 1 of 1)', $submissionfiles)); 237 } 238 239 // Context 3 - Course 2's Assignment 1 -- (offline). 240 $context = context_module::instance($this->course2assignments['ass1']->cmid); 241 $this->assertContains($context, $contexts); 242 243 $writer = writer::with_context($context); 244 foreach ($this->course2students as $student) { 245 $subcontexts = [ 246 get_string('privacy:markedsubmissionspath', 'mod_assignment'), 247 transform::user($student->id) 248 ]; 249 // Verify the student assignment submissions exists. 250 $submission = $writer->get_data($subcontexts); 251 $this->assertEquals("<p>Course 2 - Ass 1: " . $student->id . "</p>", $submission->data1); 252 } 253 254 // Context 4 - Course 2's Assignment 2 -- (multiple file upload). 255 $context = context_module::instance($this->course2assignments['ass2']->cmid); 256 $this->assertContains($context, $contexts); 257 258 $writer = writer::with_context($context); 259 foreach ($this->course2students as $student) { 260 $subcontexts = [ 261 get_string('privacy:markedsubmissionspath', 'mod_assignment'), 262 transform::user($student->id) 263 ]; 264 // Verify the student assignment submissions exists. 265 $submission = $writer->get_data($subcontexts); 266 $this->assertEquals("<p>Course 2 - Ass 2: " . $student->id . "</p>", $submission->data1); 267 268 // Verify the student assignment submission file upload exists. 269 $submissionfiles = $writer->get_files($subcontexts); 270 $this->assertTrue(array_key_exists('Student' . $student->id . '-Course2-Ass2-(File 1 of 2)', $submissionfiles)); 271 $this->assertTrue(array_key_exists('Student' . $student->id . '-Course2-Ass2-(File 2 of 2)', $submissionfiles)); 272 } 273 } 274 275 /** 276 * Test for provider::export_user_data(). 277 * 278 * @throws dml_exception 279 */ 280 public function test_export_user_data_student() { 281 global $DB; 282 283 $this->resetAfterTest(true); 284 $this->create_courses_and_assignments(); 285 286 // Test Student 1 export_data_for_user() - added assignment submissions for both assignments in Course 1. 287 $student1 = $DB->get_record('user', ['username' => 'student1']); 288 289 $contextlist = provider::get_contexts_for_userid($student1->id); 290 $approvedcontextlist = new approved_contextlist($student1, 'mod_assignment', $contextlist->get_contextids()); 291 292 // Retrieve Assignment Submissions data for Student 1. 293 provider::export_user_data($approvedcontextlist); 294 $contexts = $contextlist->get_contexts(); 295 296 // Context 1 - Course 1's Assignment 1 -- (onlinetext). 297 $context = context_module::instance($this->course1assignments['ass1']->cmid); 298 $this->assertContains($context, $contexts); 299 300 $writer = writer::with_context($context); 301 $subcontexts = [ 302 get_string('privacy:submissionpath', 'mod_assignment') 303 ]; 304 305 // Verify the student assignment submissions exists. 306 $submission = $writer->get_data($subcontexts); 307 $this->assertEquals("<p>Course 1 - Ass 1: " . $student1->id . "</p>", $submission->data1); 308 309 // Context 2 - Course 1's Assignment 2 -- (single file upload). 310 $context = context_module::instance($this->course1assignments['ass2']->cmid); 311 $this->assertContains($context, $contexts); 312 313 $writer = writer::with_context($context); 314 $subcontexts = [ 315 get_string('privacy:submissionpath', 'mod_assignment') 316 ]; 317 318 // Verify the student assignment submission exists. 319 $submission = $writer->get_data($subcontexts); 320 $this->assertEquals("<p>Course 1 - Ass 2: " . $student1->id . "</p>", $submission->data1); 321 322 // Verify the student assignment submission file upload exists. 323 $submissionfiles = $writer->get_files($subcontexts); 324 $this->assertTrue(array_key_exists('Student' . $student1->id . '-Course1-Ass2-(File 1 of 1)', $submissionfiles)); 325 326 // Test Student 2 export_data_for_user() - added assignment submissions for both assignments in Course 2. 327 $student2 = $DB->get_record('user', ['username' => 'student2']); 328 329 $contextlist = provider::get_contexts_for_userid($student2->id); 330 $approvedcontextlist = new approved_contextlist($student2, 'mod_assignment', $contextlist->get_contextids()); 331 332 // Retrieve Assignment Submissions data for Student 2. 333 provider::export_user_data($approvedcontextlist); 334 $contexts = $contextlist->get_contexts(); 335 336 // Context 1 - Course 2's Assignment 1 -- (offline). 337 $context = context_module::instance($this->course2assignments['ass1']->cmid); 338 $this->assertContains($context, $contexts); 339 340 $writer = writer::with_context($context); 341 $subcontexts = [ 342 get_string('privacy:submissionpath', 'mod_assignment') 343 ]; 344 345 // Verify the student assignment submissions exists. 346 $submission = $writer->get_data($subcontexts); 347 $this->assertEquals("<p>Course 2 - Ass 1: " . $student2->id . "</p>", $submission->data1); 348 349 // Context 2 - Course 2's Assignment 2 -- (multiple file upload). 350 $context = context_module::instance($this->course2assignments['ass2']->cmid); 351 $this->assertContains($context, $contexts); 352 353 $writer = writer::with_context($context); 354 $subcontexts = [ 355 get_string('privacy:submissionpath', 'mod_assignment') 356 ]; 357 358 // Verify the student assignment submission exists. 359 $submission = $writer->get_data($subcontexts); 360 $this->assertEquals("<p>Course 2 - Ass 2: " . $student2->id . "</p>", $submission->data1); 361 362 // Verify the student assignment submission file upload exists. 363 $submissionfiles = $writer->get_files($subcontexts); 364 $this->assertTrue(array_key_exists('Student' . $student2->id . '-Course2-Ass2-(File 1 of 2)', $submissionfiles)); 365 $this->assertTrue(array_key_exists('Student' . $student2->id . '-Course2-Ass2-(File 2 of 2)', $submissionfiles)); 366 } 367 368 /** 369 * Test for provider::delete_data_for_all_users_in_context(). 370 * 371 * @throws dml_exception 372 */ 373 public function test_delete_data_for_all_users_in_context() { 374 global $DB; 375 376 $this->resetAfterTest(true); 377 $this->create_courses_and_assignments(); 378 379 // Test teacher1 delete_data_for_all_users_in_context(). 380 $teacher1 = $DB->get_record('user', ['username' => 'teacher1']); 381 $contextlist = provider::get_contexts_for_userid($teacher1->id); 382 383 foreach ($contextlist as $context) { 384 provider::delete_data_for_all_users_in_context($context); 385 386 // Verify assignment submission(s) were deleted for the context. 387 $deleted = $this->get_assignment_submissions($context->id); 388 $this->assertCount(0, $deleted); 389 390 // Verify all the file submissions associated with the context for all users were deleted. 391 $files = $DB->get_records('files', ['component' => 'mod_assignment', 'filearea' => 'submission', 'contextid' => $context->id]); 392 $this->assertEquals(0, count($files)); 393 } 394 } 395 396 /** 397 * Test for provider::delete_data_for_user(). 398 * 399 * @throws dml_exception 400 */ 401 public function test_delete_data_for_user() { 402 global $DB; 403 404 $this->resetAfterTest(true); 405 $this->create_courses_and_assignments(); 406 407 // Test Teacher 1 delete_data_for_user(), should only remove the 1 test submission added by Teacher 1. 408 // Should not remove any assignment submission records marked by the teacher. 409 $teacher1 = $DB->get_record('user', ['username' => 'teacher1']); 410 $contextlist = provider::get_contexts_for_userid($teacher1->id); 411 $approvedcontextlist = new approved_contextlist($teacher1, 'mod_assignment', $contextlist->get_contextids()); 412 provider::delete_data_for_user($approvedcontextlist); 413 414 // Verify the submissions submitted by students still exists. 415 $markedsubmissions = $DB->get_records('assignment_submissions', ['teacher' => $teacher1->id]); 416 $this->assertCount(4, $markedsubmissions); 417 418 // Test student 1 delete_data_for_user(). 419 $student1 = $DB->get_record('user', ['username' => 'student1']); 420 $contextlist = provider::get_contexts_for_userid($student1->id); 421 $approvedcontextlist = new approved_contextlist($student1, 'mod_assignment', $contextlist->get_contextids()); 422 provider::delete_data_for_user($approvedcontextlist); 423 424 // Verify student 1's assignment submissions were deleted. 425 $assignmentsubmissions = $DB->get_records('assignment_submissions', ['userid' => $student1->id]); 426 $this->assertEquals(0, count($assignmentsubmissions)); 427 428 // Verify student 1's file submissions were deleted. 429 foreach ($contextlist->get_contextids() as $contextid) { 430 $files = $DB->get_records('files', ['component' => 'mod_assignment', 'filearea' => 'submission', 'contextid' => $contextid]); 431 $this->assertEquals(0, count($files)); 432 } 433 } 434 435 /** 436 * Test the deletion of a data for users. 437 */ 438 public function test_delete_data_for_users() { 439 global $DB; 440 $this->resetAfterTest(); 441 442 $student1 = $this->getDataGenerator()->create_user(['username' => 'student1']); 443 $student2 = $this->getDataGenerator()->create_user(['username' => 'student2']); 444 $student3 = $this->getDataGenerator()->create_user(['username' => 'student3']); 445 446 $course = $this->getDataGenerator()->create_course(); 447 $course1assignment = $this->getDataGenerator()->create_module('assignment', 448 [ 449 'course' => $course->id, 450 'name' => 'Course 1 - Assignment 1 (single file upload)', 451 'assignmenttype' => 'uploadsingle' 452 ] 453 ); 454 $context = context_module::instance($course1assignment->cmid); 455 456 // Student one submission. 457 $this->add_file_assignment_submission( 458 $course1assignment, 459 $student1, 460 "Course 1 - Ass 2: " . $student1->id, 461 'Student' . $student1->id . '-Course1-Ass2' 462 ); 463 // Student two submission. 464 $this->add_file_assignment_submission( 465 $course1assignment, 466 $student2, 467 "Course 1 - Ass 2: " . $student2->id, 468 'Student' . $student2->id . '-Course1-Ass2' 469 ); 470 // Student three submission to be retained. 471 $this->add_file_assignment_submission( 472 $course1assignment, 473 $student3, 474 "Course 1 - Ass 2: " . $student3->id, 475 'Student' . $student3->id . '-Course1-Ass2' 476 ); 477 478 $files = $DB->get_records('files', [ 479 'component' => 'mod_assignment', 480 'filearea' => 'submission', 481 'contextid' => $context->id 482 ]); 483 $this->assertCount(6, $files); 484 485 $submissions = $this->get_assignment_submissions($context->id); 486 $this->assertCount(3, $submissions); 487 488 $userlist = new \core_privacy\local\request\approved_userlist($context, 'mod_assignment', [$student1->id, $student2->id]); 489 provider::delete_data_for_users($userlist); 490 491 $files = $DB->get_records('files', [ 492 'component' => 'mod_assignment', 493 'filearea' => 'submission', 494 'contextid' => $context->id 495 ]); 496 $this->assertCount(2, $files); 497 498 $submissions = $this->get_assignment_submissions($context->id); 499 $this->assertCount(1, $submissions); 500 } 501 502 // Start of helper functions. 503 504 /** 505 * Helper function to setup Course, users, and assignments for testing. 506 */ 507 protected function create_courses_and_assignments() { 508 // Create Courses, Users, and Assignments. 509 $course1 = $this->getDataGenerator()->create_course(['shortname' => 'course1']); 510 $course2 = $this->getDataGenerator()->create_course(['shortname' => 'course2']); 511 512 $teacher1 = $this->getDataGenerator()->create_user(['username' => 'teacher1']); 513 $teacher2 = $this->getDataGenerator()->create_user(['username' => 'teacher2']); 514 515 $student1 = $this->getDataGenerator()->create_user(['username' => 'student1']); 516 $student2 = $this->getDataGenerator()->create_user(['username' => 'student2']); 517 518 $this->course1students = [ 519 $student1 520 ]; 521 522 $this->course2students = [ 523 $student2 524 ]; 525 526 $course1assignment1 = $this->getDataGenerator()->create_module('assignment', 527 [ 528 'course' => $course1->id, 529 'name' => 'Course 1 - Assignment 1 (onlinetext)', 530 'assignmenttype' => 'onlinetext', 531 ] 532 ); 533 $course1assignment2 = $this->getDataGenerator()->create_module('assignment', 534 [ 535 'course' => $course1->id, 536 'name' => 'Course 1 - Assignment 2 (single file upload)', 537 'assignmenttype' => 'uploadsingle', 538 ] 539 ); 540 541 $this->course1assignments = [ 542 'ass1' => $course1assignment1, 543 'ass2' => $course1assignment2 544 ]; 545 546 $course2assignment1 = $this->getDataGenerator()->create_module('assignment', 547 [ 548 'course' => $course2->id, 549 'name' => 'Course 2 - Assignment 1 (offline)', 550 'assignmenttype' => 'offline', 551 ] 552 ); 553 $course2assignment2 = $this->getDataGenerator()->create_module('assignment', 554 [ 555 'course' => $course2->id, 556 'name' => 'Course 2 - Assignment 2 (multiple file upload)', 557 'assignmenttype' => 'upload', 558 ] 559 ); 560 561 $this->course2assignments = [ 562 'ass1' => $course2assignment1, 563 'ass2' => $course2assignment2 564 ]; 565 566 // Teacher 1 add test assignment submission for Course 1 - Assignment 1. 567 $this->add_assignment_submission( 568 $course1assignment1, 569 $teacher1, 570 "Course 1 - Ass 1: Teacher Test Submission" 571 ); 572 573 // Student 1 add assignment submissions for Course 1 - Assignment 1 and 2. 574 $this->add_assignment_submission( 575 $course1assignment1, 576 $student1, 577 "Course 1 - Ass 1: " . $student1->id 578 ); 579 $this->add_file_assignment_submission( 580 $course1assignment2, 581 $student1, 582 "Course 1 - Ass 2: " . $student1->id, 583 'Student' . $student1->id . '-Course1-Ass2' 584 ); 585 586 // Student 2 add assignment submissions for Course 2 - Assignment 1 and 2. 587 $this->add_assignment_submission( 588 $course2assignment1, 589 $student2, 590 "Course 2 - Ass 1: " . $student2->id 591 ); 592 $this->add_file_assignment_submission( 593 $course2assignment2, 594 $student2, 595 "Course 2 - Ass 2: " . $student2->id, 596 'Student' . $student2->id . '-Course2-Ass2', 597 2 598 ); 599 600 // Teacher 1 to mark assignment submissions for Course 1's Assignment 1 and 2. 601 $course1submissions = $this->get_course_assignment_submissions($course1->id); 602 foreach ($course1submissions as $submission) { 603 $this->mark_assignment_submission($submission->assignment, $submission->id, $teacher1, 49); 604 } 605 606 // Teacher 1 to mark assignment submissions for Course 2's Assignment 1 and 2. 607 $course2submissions = $this->get_course_assignment_submissions($course2->id); 608 foreach ($course2submissions as $submission) { 609 $this->mark_assignment_submission($submission->assignment, $submission->id, $teacher1, 50); 610 } 611 } 612 613 /** 614 * Helper function to add an assignment submission for testing. 615 * 616 * @param object $assignment Object containing assignment submission details to create for testing. 617 * @param object $user Object of the user making the assignment submission. 618 * @param string $submissiondata The onlintext string value of the assignment submission. 619 * @throws dml_exception 620 */ 621 protected function add_assignment_submission($assignment, $user, $submissiondata) { 622 global $DB; 623 624 $submission = (object) [ 625 'assignment' => $assignment->id, 626 'userid' => $user->id, 627 'timecreated' => date('U'), 628 'data1' => '<p>' . $submissiondata . '</p>', 629 'submissioncomment' => 'My submission by ' . $user->username 630 ]; 631 632 return $DB->insert_record('assignment_submissions', $submission); 633 } 634 635 /** 636 * Helper function to add an assignment submission with file submissions for testing. 637 * 638 * @param object $assignment Object containing assignment submission details to create for testing. 639 * @param object $user Object of the user making the assignment submission. 640 * @param string $submissiondata The onlintext string value of the assignment submission. 641 * @param string $filename The filename of the file submission included with the assignment submission. 642 * @param int $numfiles The number of files included with the assignment submission. 643 * @throws dml_exception 644 * @throws file_exception 645 * @throws stored_file_creation_exception 646 */ 647 protected function add_file_assignment_submission($assignment, $user, $submissiondata, $filename, $numfiles = 1) { 648 global $CFG, $DB; 649 650 $submission = (object) [ 651 'assignment' => $assignment->id, 652 'userid' => $user->id, 653 'timecreated' => date('U'), 654 'data1' => '<p>' . $submissiondata . '</p>', 655 'numfiles' => $numfiles, 656 'submissioncomment' => 'My submission by ' . $user->username 657 ]; 658 659 $submissionid = $DB->insert_record('assignment_submissions', $submission); 660 661 // Create a file submission with the test pdf. 662 $this->setUser($user->id); 663 $context = context_module::instance($assignment->cmid); 664 665 $fs = get_file_storage(); 666 $sourcefile = $CFG->dirroot . '/mod/assign/feedback/editpdf/tests/fixtures/submission.pdf'; 667 668 for ($f = 1; $f <= $numfiles; $f++) { 669 $pdfsubmission = (object)array( 670 'contextid' => $context->id, 671 'component' => 'mod_assignment', 672 'filearea' => 'submission', 673 'itemid' => $submissionid, 674 'filepath' => '/', 675 'filename' => $filename . "-(File $f of $numfiles)" 676 ); 677 $fs->create_file_from_pathname($pdfsubmission, $sourcefile); 678 } 679 } 680 681 /** 682 * Helper function to retrieve the assignment submission records for a given course. 683 * 684 * @param int $courseid The course ID to get assignment submissions by. 685 * @return array Array of assignment submission details. 686 * @throws dml_exception 687 */ 688 protected function get_course_assignment_submissions($courseid) { 689 global $DB; 690 691 $sql = "SELECT s.id, 692 s.assignment, 693 s.userid, 694 s.timecreated, 695 s.timemodified, 696 s.numfiles, 697 s.data1, 698 s.data2, 699 s.grade, 700 s.submissioncomment, 701 s.format, 702 s.teacher, 703 s.timemarked, 704 s.mailed 705 FROM {assignment} a 706 JOIN {assignment_submissions} s ON s.assignment = a.id 707 WHERE a.course = :courseid"; 708 $params = [ 709 'courseid' => $courseid 710 ]; 711 712 return $DB->get_records_sql($sql, $params); 713 } 714 715 /** 716 * Helper function to update an assignment submission with grading details for a teacher. 717 * 718 * @param int $assignmentid The assignment ID to update assignment submissions with marking/graded details. 719 * @param int $submissionid The assignment submission ID to update with marking/grading details. 720 * @param int $teacher The teacher user ID to making the marking/grading details. 721 * @param int $gradedata The grade value set for the marking/grading details. 722 */ 723 protected function mark_assignment_submission($assignmentid, $submissionid, $teacher, $gradedata) { 724 global $DB; 725 726 $submission = (object) [ 727 'id' => $submissionid, 728 'assignment' => $assignmentid, 729 'grade' => $gradedata, 730 'teacher' => $teacher->id, 731 'timemarked' => date('U') 732 ]; 733 734 return $DB->update_record('assignment_submissions', $submission); 735 } 736 737 /** 738 * Helper function to retrieve the assignment records for a given context. 739 * 740 * @param int $contextid The context module ID value to retrieve assignment IDs by. 741 * @return array Array of assignment IDs. 742 * @throws dml_exception 743 */ 744 protected function get_assignments($contextid) { 745 global $DB; 746 747 $sql = "SELECT a.id 748 FROM {assignment} a 749 JOIN {course_modules} cm ON a.id = cm.instance 750 JOIN {modules} m ON m.id = cm.module AND m.name = :modulename 751 JOIN {context} ctx ON ctx.instanceid = cm.id AND ctx.contextlevel = :contextmodule 752 WHERE ctx.id = :contextid"; 753 $params = [ 754 'modulename' => 'assignment', 755 'contextmodule' => CONTEXT_MODULE, 756 'contextid' => $contextid 757 ]; 758 759 return $DB->get_records_sql($sql, $params); 760 } 761 762 /** 763 * Helper function to retrieve the assignment submission records for a given context. 764 * 765 * @param int $contextid The context module ID value to retrieve assignment submission IDs by. 766 * @return array Array of assignment submission IDs. 767 * @throws dml_exception 768 */ 769 protected function get_assignment_submissions($contextid) { 770 global $DB; 771 772 $sql = "SELECT s.id 773 FROM {assignment_submissions} s 774 JOIN {assignment} a ON a.id = s.assignment 775 JOIN {course_modules} cm ON a.id = cm.instance 776 JOIN {modules} m ON m.id = cm.module AND m.name = :modulename 777 JOIN {context} ctx ON ctx.instanceid = cm.id AND ctx.contextlevel = :contextmodule 778 WHERE ctx.id = :contextid"; 779 $params = [ 780 'modulename' => 'assignment', 781 'contextmodule' => CONTEXT_MODULE, 782 'contextid' => $contextid 783 ]; 784 785 return $DB->get_records_sql($sql, $params); 786 } 787 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body