/** * This function copies annotations and comments from the source user * to the current group member being processed when using applytoall. * @param int|\assign $assignment * @param stdClass $grade * @param int $sourceuserid * @return bool */ public static function copy_drafts_from_to($assignment, $grade, $sourceuserid) { global $DB; // Delete any existing annotations and comments from current user. $DB->delete_records('assignfeedback_editpdf_annot', array('gradeid' => $grade->id)); $DB->delete_records('assignfeedback_editpdf_cmnt', array('gradeid' => $grade->id)); // Get gradeid, annotations and comments from sourceuserid. $sourceusergrade = $assignment->get_user_grade($sourceuserid, true, $grade->attemptnumber); $annotations = $DB->get_records('assignfeedback_editpdf_annot', array('gradeid' => $sourceusergrade->id, 'draft' => 1)); $comments = $DB->get_records('assignfeedback_editpdf_cmnt', array('gradeid' => $sourceusergrade->id, 'draft' => 1)); // Add annotations and comments to current user to generate feedback file. foreach ($annotations as $annotation) { $annotation->gradeid = $grade->id; $DB->insert_record('assignfeedback_editpdf_annot', $annotation); } foreach ($comments as $comment) { $comment->gradeid = $grade->id; $DB->insert_record('assignfeedback_editpdf_cmnt', $comment); } return true; }
/** * Test upgrade minmaxgrade step. */ public function test_upgrade_minmaxgrade() { global $CFG, $DB; require_once $CFG->libdir . '/gradelib.php'; $initialminmax = $CFG->grade_minmaxtouse; $this->resetAfterTest(); $c1 = $this->getDataGenerator()->create_course(); $c2 = $this->getDataGenerator()->create_course(); $c3 = $this->getDataGenerator()->create_course(); $u1 = $this->getDataGenerator()->create_user(); $a1 = $this->getDataGenerator()->create_module('assign', array('course' => $c1, 'grade' => 100)); $a2 = $this->getDataGenerator()->create_module('assign', array('course' => $c2, 'grade' => 100)); $a3 = $this->getDataGenerator()->create_module('assign', array('course' => $c3, 'grade' => 100)); $cm1 = get_coursemodule_from_instance('assign', $a1->id); $ctx1 = context_module::instance($cm1->id); $assign1 = new assign($ctx1, $cm1, $c1); $cm2 = get_coursemodule_from_instance('assign', $a2->id); $ctx2 = context_module::instance($cm2->id); $assign2 = new assign($ctx2, $cm2, $c2); $cm3 = get_coursemodule_from_instance('assign', $a3->id); $ctx3 = context_module::instance($cm3->id); $assign3 = new assign($ctx3, $cm3, $c3); // Give a grade to the student. $ug = $assign1->get_user_grade($u1->id, true); $ug->grade = 10; $assign1->update_grade($ug); $ug = $assign2->get_user_grade($u1->id, true); $ug->grade = 20; $assign2->update_grade($ug); $ug = $assign3->get_user_grade($u1->id, true); $ug->grade = 30; $assign3->update_grade($ug); // Run the upgrade. upgrade_minmaxgrade(); // Nothing has happened. $this->assertFalse($DB->record_exists('config', array('name' => 'show_min_max_grades_changed_' . $c1->id))); $this->assertSame(false, grade_get_setting($c1->id, 'minmaxtouse', false, true)); $this->assertFalse($DB->record_exists('grade_items', array('needsupdate' => 1, 'courseid' => $c1->id))); $this->assertFalse($DB->record_exists('config', array('name' => 'show_min_max_grades_changed_' . $c2->id))); $this->assertSame(false, grade_get_setting($c2->id, 'minmaxtouse', false, true)); $this->assertFalse($DB->record_exists('grade_items', array('needsupdate' => 1, 'courseid' => $c2->id))); $this->assertFalse($DB->record_exists('config', array('name' => 'show_min_max_grades_changed_' . $c3->id))); $this->assertSame(false, grade_get_setting($c3->id, 'minmaxtouse', false, true)); $this->assertFalse($DB->record_exists('grade_items', array('needsupdate' => 1, 'courseid' => $c3->id))); // Create inconsistency in c1 and c2. $giparams = array('itemtype' => 'mod', 'itemmodule' => 'assign', 'iteminstance' => $a1->id, 'courseid' => $c1->id, 'itemnumber' => 0); $gi = grade_item::fetch($giparams); $gi->grademin = 5; $gi->update(); $giparams = array('itemtype' => 'mod', 'itemmodule' => 'assign', 'iteminstance' => $a2->id, 'courseid' => $c2->id, 'itemnumber' => 0); $gi = grade_item::fetch($giparams); $gi->grademax = 50; $gi->update(); // C1 and C2 should be updated, but the course setting should not be set. $CFG->grade_minmaxtouse = GRADE_MIN_MAX_FROM_GRADE_GRADE; // Run the upgrade. upgrade_minmaxgrade(); // C1 and C2 were partially updated. $this->assertTrue($DB->record_exists('config', array('name' => 'show_min_max_grades_changed_' . $c1->id))); $this->assertSame(false, grade_get_setting($c1->id, 'minmaxtouse', false, true)); $this->assertTrue($DB->record_exists('grade_items', array('needsupdate' => 1, 'courseid' => $c1->id))); $this->assertTrue($DB->record_exists('config', array('name' => 'show_min_max_grades_changed_' . $c2->id))); $this->assertSame(false, grade_get_setting($c2->id, 'minmaxtouse', false, true)); $this->assertTrue($DB->record_exists('grade_items', array('needsupdate' => 1, 'courseid' => $c2->id))); // Nothing has happened for C3. $this->assertFalse($DB->record_exists('config', array('name' => 'show_min_max_grades_changed_' . $c3->id))); $this->assertSame(false, grade_get_setting($c3->id, 'minmaxtouse', false, true)); $this->assertFalse($DB->record_exists('grade_items', array('needsupdate' => 1, 'courseid' => $c3->id))); // Course setting should not be set on a course that has the setting already. $CFG->grade_minmaxtouse = GRADE_MIN_MAX_FROM_GRADE_ITEM; grade_set_setting($c1->id, 'minmaxtouse', -1); // Sets different value than constant to check that it remained the same. // Run the upgrade. upgrade_minmaxgrade(); // C2 was updated. $this->assertSame((string) GRADE_MIN_MAX_FROM_GRADE_GRADE, grade_get_setting($c2->id, 'minmaxtouse', false, true)); // Nothing has happened for C1. $this->assertSame('-1', grade_get_setting($c1->id, 'minmaxtouse', false, true)); // Nothing has happened for C3. $this->assertFalse($DB->record_exists('config', array('name' => 'show_min_max_grades_changed_' . $c3->id))); $this->assertSame(false, grade_get_setting($c3->id, 'minmaxtouse', false, true)); $this->assertFalse($DB->record_exists('grade_items', array('needsupdate' => 1, 'courseid' => $c3->id))); // Final check, this time we'll unset the default config. unset($CFG->grade_minmaxtouse); grade_set_setting($c1->id, 'minmaxtouse', null); // Run the upgrade. upgrade_minmaxgrade(); // C1 was updated. $this->assertSame((string) GRADE_MIN_MAX_FROM_GRADE_GRADE, grade_get_setting($c1->id, 'minmaxtouse', false, true)); // Nothing has happened for C3. $this->assertFalse($DB->record_exists('config', array('name' => 'show_min_max_grades_changed_' . $c3->id))); $this->assertSame(false, grade_get_setting($c3->id, 'minmaxtouse', false, true)); $this->assertFalse($DB->record_exists('grade_items', array('needsupdate' => 1, 'courseid' => $c3->id))); // Restore value. $CFG->grade_minmaxtouse = $initialminmax; }
define('AJAX_SCRIPT', true); // To be able to process concurrent ajax request with the generate pdf ajax request we can not use cookie. define('NO_MOODLE_COOKIES', true); use assignfeedback_editpdf\document_services; require_once '../../../../config.php'; try { $assignmentid = required_param('assignmentid', PARAM_INT); $userid = required_param('userid', PARAM_INT); $attemptnumber = required_param('attemptnumber', PARAM_INT); // Retrieve the assignments. require_once $CFG->dirroot . '/mod/assign/locallib.php'; $cm = get_coursemodule_from_instance('assign', $assignmentid, 0, false, MUST_EXIST); $context = context_module::instance($cm->id); $assignment = new assign($context, null, null); // Get the generated images from file API call. $grade = $assignment->get_user_grade($userid, false, $attemptnumber); // Check we found a grade. if (empty($grade)) { throw new coding_exception('grade not found'); } // No need to handle the readonly files here, the should be already generated. $component = 'assignfeedback_editpdf'; $filearea = document_services::PAGE_IMAGE_FILEAREA; $filepath = '/'; $fs = get_file_storage(); $files = $fs->get_directory_files($context->id, $component, $filearea, $grade->id, $filepath); // The important security part: we ONLY RETURN the total NUMBER of generated images. echo $OUTPUT->header(); echo json_encode(count($files)); echo $OUTPUT->footer(); } catch (Exception $e) {
public function test_grade_grade_min_max() { global $CFG; $initialminmaxtouse = $CFG->grade_minmaxtouse; $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); $user = $this->getDataGenerator()->create_user(); $assignrecord = $this->getDataGenerator()->create_module('assign', array('course' => $course, 'grade' => 100)); $cm = get_coursemodule_from_instance('assign', $assignrecord->id); $assigncontext = context_module::instance($cm->id); $assign = new assign($assigncontext, $cm, $course); // Fetch the assignment item. $giparams = array('itemtype' => 'mod', 'itemmodule' => 'assign', 'iteminstance' => $assignrecord->id, 'courseid' => $course->id, 'itemnumber' => 0); $gi = grade_item::fetch($giparams); $this->assertEquals(0, $gi->grademin); $this->assertEquals(100, $gi->grademax); // Give a grade to the student. $usergrade = $assign->get_user_grade($user->id, true); $usergrade->grade = 10; $assign->update_grade($usergrade); // Check the grade stored in gradebook. $gg = grade_grade::fetch(array('userid' => $user->id, 'itemid' => $gi->id)); $this->assertEquals(10, $gg->rawgrade); $this->assertEquals(0, $gg->get_grade_min()); $this->assertEquals(100, $gg->get_grade_max()); // Change the min/max grade of the item. $gi->grademax = 50; $gi->grademin = 2; $gi->update(); // Fetch the updated item. $gi = grade_item::fetch($giparams); // Now check the grade grade min/max with system setting. $CFG->grade_minmaxtouse = GRADE_MIN_MAX_FROM_GRADE_ITEM; grade_set_setting($course->id, 'minmaxtouse', null); // Ensure no course setting. $gg = grade_grade::fetch(array('userid' => $user->id, 'itemid' => $gi->id)); $this->assertEquals(2, $gg->get_grade_min()); $this->assertEquals(50, $gg->get_grade_max()); // Now with other system setting. $CFG->grade_minmaxtouse = GRADE_MIN_MAX_FROM_GRADE_GRADE; grade_set_setting($course->id, 'minmaxtouse', null); // Ensure no course setting, and reset static cache. $gg = grade_grade::fetch(array('userid' => $user->id, 'itemid' => $gi->id)); $this->assertEquals(0, $gg->get_grade_min()); $this->assertEquals(100, $gg->get_grade_max()); // Now with overriden setting in course. $CFG->grade_minmaxtouse = GRADE_MIN_MAX_FROM_GRADE_ITEM; grade_set_setting($course->id, 'minmaxtouse', GRADE_MIN_MAX_FROM_GRADE_GRADE); $gg = grade_grade::fetch(array('userid' => $user->id, 'itemid' => $gi->id)); $this->assertEquals(0, $gg->get_grade_min()); $this->assertEquals(100, $gg->get_grade_max()); $CFG->grade_minmaxtouse = GRADE_MIN_MAX_FROM_GRADE_GRADE; grade_set_setting($course->id, 'minmaxtouse', GRADE_MIN_MAX_FROM_GRADE_ITEM); $gg = grade_grade::fetch(array('userid' => $user->id, 'itemid' => $gi->id)); $this->assertEquals(2, $gg->get_grade_min()); $this->assertEquals(50, $gg->get_grade_max()); $CFG->grade_minmaxtouse = $initialminmaxtouse; }
/** * Does this file exist in any of the current files supported by this plugin for this user? * * @param assign $assignment - The assignment instance * @param stdClass $user The user matching this uploaded file * @param assign_plugin $plugin The matching plugin from the filename * @param string $filename The parsed filename from the zip * @param stored_file $fileinfo The info about the extracted file from the zip * @return bool - True if the file has been modified or is new */ public function is_file_modified($assignment, $user, $plugin, $filename, $fileinfo) { $sg = null; if ($plugin->get_subtype() == 'assignsubmission') { $sg = $assignment->get_user_submission($user->id, false); } else if ($plugin->get_subtype() == 'assignfeedback') { $sg = $assignment->get_user_grade($user->id, false); } else { return false; } if (!$sg) { return true; } foreach ($plugin->get_files($sg, $user) as $pluginfilename => $file) { if ($pluginfilename == $filename) { // Extract the file and compare hashes. $contenthash = ''; if (is_array($file)) { $content = reset($file); $contenthash = sha1($content); } else { $contenthash = $file->get_contenthash(); } if ($contenthash != $fileinfo->get_contenthash()) { return true; } else { return false; } } } return true; }
/** * Copy annotations, comments, pages, and other required content from the source user to the current group member * being procssed when using applytoall. * * @param int|\assign $assignment * @param stdClass $grade * @param int $sourceuserid * @return bool */ public static function copy_drafts_from_to($assignment, $grade, $sourceuserid) { global $DB; // Delete any existing annotations and comments from current user. $DB->delete_records('assignfeedback_editpdf_annot', array('gradeid' => $grade->id)); $DB->delete_records('assignfeedback_editpdf_cmnt', array('gradeid' => $grade->id)); // Get gradeid, annotations and comments from sourceuserid. $sourceusergrade = $assignment->get_user_grade($sourceuserid, true, $grade->attemptnumber); $annotations = $DB->get_records('assignfeedback_editpdf_annot', array('gradeid' => $sourceusergrade->id, 'draft' => 1)); $comments = $DB->get_records('assignfeedback_editpdf_cmnt', array('gradeid' => $sourceusergrade->id, 'draft' => 1)); $contextid = $assignment->get_context()->id; $sourceitemid = $sourceusergrade->id; // Add annotations and comments to current user to generate feedback file. foreach ($annotations as $annotation) { $annotation->gradeid = $grade->id; $DB->insert_record('assignfeedback_editpdf_annot', $annotation); } foreach ($comments as $comment) { $comment->gradeid = $grade->id; $DB->insert_record('assignfeedback_editpdf_cmnt', $comment); } $fs = get_file_storage(); // Copy the stamp files. self::replace_files_from_to($fs, $contextid, $sourceitemid, $grade->id, document_services::STAMPS_FILEAREA, true); // Copy the PAGE_IMAGE_FILEAREA files. self::replace_files_from_to($fs, $contextid, $sourceitemid, $grade->id, document_services::PAGE_IMAGE_FILEAREA); return true; }
$event['courseid'] = $logrecord->course; $event['timecreated'] = $logrecord->time; try { $courseinfo = get_fast_modinfo($logrecord->course); } catch (Exception $e) { $log->warning("MISSING: Unable to get modinfo for course {$logrecord->course}"); continue; } try { $mod = $courseinfo->get_cm($logrecord->cmid); } catch (Exception $e) { $log->warning("MISSING: Unable to get cm {$logrecord->cmid}"); continue; } $course = $courseinfo->get_course(); // We don't have enough info to determine the actual submission // so always get the latest grade for that assignment $assign = new assign($mod->context, $mod, $course); $grade = $assign->get_user_grade($logrecord->userid, false); $event['objectid'] = $grade->id; $event['objecttable'] = 'assign_grades'; if ($statement = $gen->generateStatement($event)) { $statements[] = $statement; } } $log->info("Sending statements {$start} to " . ($start + count($batch) - 1)); $log->info("Statement count: " . count($statements)); // Send statements as a batch $result = $lrs->saveStatements($statements); $start += count($batch); }
/** * Test upgrade minmaxgrade step. */ public function test_upgrade_mark_grading_configuration() { global $CFG, $DB; require_once $CFG->libdir . '/gradelib.php'; $initialminmax = $CFG->grade_minmaxtouse; $this->resetAfterTest(); $c1 = $this->getDataGenerator()->create_course(); $c2 = $this->getDataGenerator()->create_course(); $c3 = $this->getDataGenerator()->create_course(); $u1 = $this->getDataGenerator()->create_user(); $a1 = $this->getDataGenerator()->create_module('assign', array('course' => $c1, 'grade' => 100)); $a2 = $this->getDataGenerator()->create_module('assign', array('course' => $c2, 'grade' => 100)); $a3 = $this->getDataGenerator()->create_module('assign', array('course' => $c3, 'grade' => 100)); $cm1 = get_coursemodule_from_instance('assign', $a1->id); $ctx1 = context_module::instance($cm1->id); $assign1 = new assign($ctx1, $cm1, $c1); $cm2 = get_coursemodule_from_instance('assign', $a2->id); $ctx2 = context_module::instance($cm2->id); $assign2 = new assign($ctx2, $cm2, $c2); $cm3 = get_coursemodule_from_instance('assign', $a3->id); $ctx3 = context_module::instance($cm3->id); $assign3 = new assign($ctx3, $cm3, $c3); // Give a grade to the student. $ug = $assign1->get_user_grade($u1->id, true); $ug->grade = 10; $assign1->update_grade($ug); $ug = $assign2->get_user_grade($u1->id, true); $ug->grade = 20; $assign2->update_grade($ug); $ug = $assign3->get_user_grade($u1->id, true); $ug->grade = 30; $assign3->update_grade($ug); // Create inconsistency in c1 and c2. $giparams = array('itemtype' => 'mod', 'itemmodule' => 'assign', 'iteminstance' => $a1->id, 'courseid' => $c1->id, 'itemnumber' => 0); $gi = grade_item::fetch($giparams); $gi->grademin = 5; $gi->update(); $giparams = array('itemtype' => 'mod', 'itemmodule' => 'assign', 'iteminstance' => $a2->id, 'courseid' => $c2->id, 'itemnumber' => 0); $gi = grade_item::fetch($giparams); $gi->grademax = 50; $gi->update(); // Run the upgrade. upgrade_mark_grading_configuration(); // Nothing has happened. $this->assertEquals(GRADE_MIN_MAX_FROM_GRADE_ITEM, grade_get_setting($c1->id, 'minmaxtouse', false, true)); $this->assertEquals(GRADE_MIN_MAX_FROM_GRADE_ITEM, grade_get_setting($c2->id, 'minmaxtouse', false, true)); $this->assertEquals(false, grade_get_setting($c3->id, 'minmaxtouse', false, true)); // Restore value. $CFG->grade_minmaxtouse = $initialminmax; }
/** * This function copies annotations and comments from the source user * to the current group member being processed when using applytoall. * @param int|\assign $assignment * @param stdClass $grade * @param int $sourceuserid * @return bool */ public static function copy_drafts_from_to($assignment, $grade, $sourceuserid) { global $DB; // Delete any existing annotations and comments from current user. $DB->delete_records('assignfeedback_editpdf_annot', array('gradeid' => $grade->id)); $DB->delete_records('assignfeedback_editpdf_cmnt', array('gradeid' => $grade->id)); // Get gradeid, annotations and comments from sourceuserid. $sourceusergrade = $assignment->get_user_grade($sourceuserid, true, $grade->attemptnumber); $annotations = $DB->get_records('assignfeedback_editpdf_annot', array('gradeid' => $sourceusergrade->id, 'draft' => 1)); $comments = $DB->get_records('assignfeedback_editpdf_cmnt', array('gradeid' => $sourceusergrade->id, 'draft' => 1)); // Add annotations and comments to current user to generate feedback file. foreach ($annotations as $annotation) { $annotation->gradeid = $grade->id; $DB->insert_record('assignfeedback_editpdf_annot', $annotation); } foreach ($comments as $comment) { $comment->gradeid = $grade->id; $DB->insert_record('assignfeedback_editpdf_cmnt', $comment); } // Delete the existing stamps and copy the source ones. $fs = get_file_storage(); $fs->delete_area_files($assignment->get_context()->id, 'assignfeedback_editpdf', 'stamps', $grade->id); if ($files = $fs->get_area_files($assignment->get_context()->id, 'assignfeedback_editpdf', 'stamps', $sourceusergrade->id, "filename", false)) { foreach ($files as $file) { $newrecord = new \stdClass(); $newrecord->contextid = $assignment->get_context()->id; $newrecord->itemid = $grade->id; $fs->create_file_from_storedfile($newrecord, $file); } } return true; }