public function test_grade_edit_tree_column_range_get_item_cell() { global $DB, $CFG; $this->resetAfterTest(true); // Make some things we need. $scale = $this->getDataGenerator()->create_scale(); $course = $this->getDataGenerator()->create_course(); $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); $modulecontext = context_module::instance($assign->id); // The generator returns a dummy object, lets get the real assign object. $assign = new assign($modulecontext, false, false); $cm = $assign->get_course_module(); // Get range column. $column = grade_edit_tree_column::factory('range'); $gradeitemparams = array('itemtype' => 'mod', 'itemmodule' => $cm->modname, 'iteminstance' => $cm->instance, 'courseid' => $cm->course, 'itemnumber' => 0); // Lets set the grade to something we know. $instance = $assign->get_instance(); $instance->grade = 70; $instance->instance = $instance->id; $assign->update_instance($instance); $gradeitem = grade_item::fetch($gradeitemparams); $cell = $column->get_item_cell($gradeitem, array()); $this->assertEquals(GRADE_TYPE_VALUE, $gradeitem->gradetype); $this->assertEquals(null, $gradeitem->scaleid); $this->assertEquals(70.0, (double) $cell->text, "Grade text is 70", 0.01); // Now change it to a scale. $instance = $assign->get_instance(); $instance->grade = -$scale->id; $instance->instance = $instance->id; $assign->update_instance($instance); $gradeitem = grade_item::fetch($gradeitemparams); $cell = $column->get_item_cell($gradeitem, array()); // Make the expected scale text. $scaleitems = null; $scaleitems = explode(',', $scale->scale); $scalestring = end($scaleitems) . ' (' . count($scaleitems) . ')'; $this->assertEquals(GRADE_TYPE_SCALE, $gradeitem->gradetype); $this->assertEquals($scale->id, $gradeitem->scaleid); $this->assertEquals($scalestring, $cell->text, "Grade text matches scale"); // Now change it to no grade. $instance = $assign->get_instance(); $instance->grade = 0; $instance->instance = $instance->id; $assign->update_instance($instance); $gradeitem = grade_item::fetch($gradeitemparams); $cell = $column->get_item_cell($gradeitem, array()); $this->assertEquals(GRADE_TYPE_TEXT, $gradeitem->gradetype); $this->assertEquals(null, $gradeitem->scaleid); $this->assertEquals(' - ', $cell->text, 'Grade text matches empty value of " - "'); }
/** * Return things to the renderer. * * @return int the course module id */ public function get_course_module_id() { return $this->assignment->get_course_module()->id; }
/** * Tests the is_available and get_description functions. */ public function test_usage() { global $CFG, $DB; require_once $CFG->dirroot . '/mod/assign/locallib.php'; $this->resetAfterTest(); // Create course with completion turned on. $CFG->enablecompletion = true; $CFG->enableavailability = true; $generator = $this->getDataGenerator(); $course = $generator->create_course(array('enablecompletion' => 1)); $user = $generator->create_user(); $generator->enrol_user($user->id, $course->id); $this->setUser($user); // Create a Page with manual completion for basic checks. $page = $generator->get_plugin_generator('mod_page')->create_instance(array('course' => $course->id, 'name' => 'Page!', 'completion' => COMPLETION_TRACKING_MANUAL)); // Create an assignment - we need to have something that can be graded // so as to test the PASS/FAIL states. Set it up to be completed based // on its grade item. $assignrow = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, 'name' => 'Assign!', 'completion' => COMPLETION_TRACKING_AUTOMATIC)); $DB->set_field('course_modules', 'completiongradeitemnumber', 0, array('id' => $assignrow->cmid)); $assign = new assign(context_module::instance($assignrow->cmid), false, false); // Get basic details. $modinfo = get_fast_modinfo($course); $pagecm = $modinfo->get_cm($page->cmid); $assigncm = $assign->get_course_module(); $info = new \core_availability\mock_info($course, $user->id); // COMPLETE state (false), positive and NOT. $cond = new condition((object) array('cm' => (int) $pagecm->id, 'e' => COMPLETION_COMPLETE)); $this->assertFalse($cond->is_available(false, $info, true, $user->id)); $information = $cond->get_description(false, false, $info); $information = \core_availability\info::format_info($information, $course); $this->assertRegExp('~Page!.*is marked complete~', $information); $this->assertTrue($cond->is_available(true, $info, true, $user->id)); // INCOMPLETE state (true). $cond = new condition((object) array('cm' => (int) $pagecm->id, 'e' => COMPLETION_INCOMPLETE)); $this->assertTrue($cond->is_available(false, $info, true, $user->id)); $this->assertFalse($cond->is_available(true, $info, true, $user->id)); $information = $cond->get_description(false, true, $info); $information = \core_availability\info::format_info($information, $course); $this->assertRegExp('~Page!.*is marked complete~', $information); // Mark page complete. $completion = new completion_info($course); $completion->update_state($pagecm, COMPLETION_COMPLETE); // COMPLETE state (true). $cond = new condition((object) array('cm' => (int) $pagecm->id, 'e' => COMPLETION_COMPLETE)); $this->assertTrue($cond->is_available(false, $info, true, $user->id)); $this->assertFalse($cond->is_available(true, $info, true, $user->id)); $information = $cond->get_description(false, true, $info); $information = \core_availability\info::format_info($information, $course); $this->assertRegExp('~Page!.*is incomplete~', $information); // INCOMPLETE state (false). $cond = new condition((object) array('cm' => (int) $pagecm->id, 'e' => COMPLETION_INCOMPLETE)); $this->assertFalse($cond->is_available(false, $info, true, $user->id)); $information = $cond->get_description(false, false, $info); $information = \core_availability\info::format_info($information, $course); $this->assertRegExp('~Page!.*is incomplete~', $information); $this->assertTrue($cond->is_available(true, $info, true, $user->id)); // We are going to need the grade item so that we can get pass/fails. $gradeitem = $assign->get_grade_item(); grade_object::set_properties($gradeitem, array('gradepass' => 50.0)); $gradeitem->update(); // With no grade, it should return true for INCOMPLETE and false for // the other three. $cond = new condition((object) array('cm' => (int) $assigncm->id, 'e' => COMPLETION_INCOMPLETE)); $this->assertTrue($cond->is_available(false, $info, true, $user->id)); $this->assertFalse($cond->is_available(true, $info, true, $user->id)); $cond = new condition((object) array('cm' => (int) $assigncm->id, 'e' => COMPLETION_COMPLETE)); $this->assertFalse($cond->is_available(false, $info, true, $user->id)); $this->assertTrue($cond->is_available(true, $info, true, $user->id)); // Check $information for COMPLETE_PASS and _FAIL as we haven't yet. $cond = new condition((object) array('cm' => (int) $assigncm->id, 'e' => COMPLETION_COMPLETE_PASS)); $this->assertFalse($cond->is_available(false, $info, true, $user->id)); $information = $cond->get_description(false, false, $info); $information = \core_availability\info::format_info($information, $course); $this->assertRegExp('~Assign!.*is complete and passed~', $information); $this->assertTrue($cond->is_available(true, $info, true, $user->id)); $cond = new condition((object) array('cm' => (int) $assigncm->id, 'e' => COMPLETION_COMPLETE_FAIL)); $this->assertFalse($cond->is_available(false, $info, true, $user->id)); $information = $cond->get_description(false, false, $info); $information = \core_availability\info::format_info($information, $course); $this->assertRegExp('~Assign!.*is complete and failed~', $information); $this->assertTrue($cond->is_available(true, $info, true, $user->id)); // Change the grade to be complete and failed. self::set_grade($assignrow, $user->id, 40); $cond = new condition((object) array('cm' => (int) $assigncm->id, 'e' => COMPLETION_INCOMPLETE)); $this->assertFalse($cond->is_available(false, $info, true, $user->id)); $this->assertTrue($cond->is_available(true, $info, true, $user->id)); $cond = new condition((object) array('cm' => (int) $assigncm->id, 'e' => COMPLETION_COMPLETE)); $this->assertTrue($cond->is_available(false, $info, true, $user->id)); $this->assertFalse($cond->is_available(true, $info, true, $user->id)); $cond = new condition((object) array('cm' => (int) $assigncm->id, 'e' => COMPLETION_COMPLETE_PASS)); $this->assertFalse($cond->is_available(false, $info, true, $user->id)); $information = $cond->get_description(false, false, $info); $information = \core_availability\info::format_info($information, $course); $this->assertRegExp('~Assign!.*is complete and passed~', $information); $this->assertTrue($cond->is_available(true, $info, true, $user->id)); $cond = new condition((object) array('cm' => (int) $assigncm->id, 'e' => COMPLETION_COMPLETE_FAIL)); $this->assertTrue($cond->is_available(false, $info, true, $user->id)); $this->assertFalse($cond->is_available(true, $info, true, $user->id)); $information = $cond->get_description(false, true, $info); $information = \core_availability\info::format_info($information, $course); $this->assertRegExp('~Assign!.*is not complete and failed~', $information); // Now change it to pass. self::set_grade($assignrow, $user->id, 60); $cond = new condition((object) array('cm' => (int) $assigncm->id, 'e' => COMPLETION_INCOMPLETE)); $this->assertFalse($cond->is_available(false, $info, true, $user->id)); $this->assertTrue($cond->is_available(true, $info, true, $user->id)); $cond = new condition((object) array('cm' => (int) $assigncm->id, 'e' => COMPLETION_COMPLETE)); $this->assertTrue($cond->is_available(false, $info, true, $user->id)); $this->assertFalse($cond->is_available(true, $info, true, $user->id)); $cond = new condition((object) array('cm' => (int) $assigncm->id, 'e' => COMPLETION_COMPLETE_PASS)); $this->assertTrue($cond->is_available(false, $info, true, $user->id)); $this->assertFalse($cond->is_available(true, $info, true, $user->id)); $information = $cond->get_description(false, true, $info); $information = \core_availability\info::format_info($information, $course); $this->assertRegExp('~Assign!.*is not complete and passed~', $information); $cond = new condition((object) array('cm' => (int) $assigncm->id, 'e' => COMPLETION_COMPLETE_FAIL)); $this->assertFalse($cond->is_available(false, $info, true, $user->id)); $information = $cond->get_description(false, false, $info); $information = \core_availability\info::format_info($information, $course); $this->assertRegExp('~Assign!.*is complete and failed~', $information); $this->assertTrue($cond->is_available(true, $info, true, $user->id)); // Simulate deletion of an activity by using an invalid cmid. These // conditions always fail, regardless of NOT flag or INCOMPLETE. $cond = new condition((object) array('cm' => $assigncm->id + 100, 'e' => COMPLETION_COMPLETE)); $this->assertFalse($cond->is_available(false, $info, true, $user->id)); $information = $cond->get_description(false, false, $info); $information = \core_availability\info::format_info($information, $course); $this->assertRegExp('~(Missing activity).*is marked complete~', $information); $this->assertFalse($cond->is_available(true, $info, true, $user->id)); $cond = new condition((object) array('cm' => $assigncm->id + 100, 'e' => COMPLETION_INCOMPLETE)); $this->assertFalse($cond->is_available(false, $info, true, $user->id)); }
/** * Process an uploaded zip file * * @param assign $assignment - The assignment instance * @param assign_feedback_file $fileplugin - The file feedback plugin * @return string - The html response */ public function import_zip_files($assignment, $fileplugin) { global $USER, $CFG, $PAGE, $DB; @set_time_limit(ASSIGNFEEDBACK_FILE_MAXFILEUNZIPTIME); $packer = get_file_packer('application/zip'); $feedbackfilesupdated = 0; $feedbackfilesadded = 0; $userswithnewfeedback = array(); $contextid = $assignment->get_context()->id; $fs = get_file_storage(); $files = $fs->get_directory_files($contextid, 'assignfeedback_file', ASSIGNFEEDBACK_FILE_IMPORT_FILEAREA, $USER->id, '/import/'); $currentgroup = groups_get_activity_group($assignment->get_course_module(), true); $allusers = $assignment->list_participants($currentgroup, false); $participants = array(); foreach ($allusers as $user) { $participants[$assignment->get_uniqueid_for_user($user->id)] = $user; } foreach ($files as $unzippedfile) { // Set the timeout for unzipping each file. $user = null; $plugin = null; $filename = ''; if ($this->is_valid_filename_for_import($assignment, $unzippedfile, $participants, $user, $plugin, $filename)) { if ($this->is_file_modified($assignment, $user, $plugin, $filename, $unzippedfile)) { $grade = $assignment->get_user_grade($user->id, true); if ($oldfile = $fs->get_file($contextid, 'assignfeedback_file', ASSIGNFEEDBACK_FILE_FILEAREA, $grade->id, '/', $filename)) { // Update existing feedback file. $oldfile->replace_content_with($unzippedfile); $feedbackfilesupdated++; } else { // Create a new feedback file. $newfilerecord = new stdClass(); $newfilerecord->contextid = $contextid; $newfilerecord->component = 'assignfeedback_file'; $newfilerecord->filearea = ASSIGNFEEDBACK_FILE_FILEAREA; $newfilerecord->filename = $filename; $newfilerecord->filepath = '/'; $newfilerecord->itemid = $grade->id; $fs->create_file_from_storedfile($newfilerecord, $unzippedfile); $feedbackfilesadded++; } $userswithnewfeedback[$user->id] = 1; // Update the number of feedback files for this user. $fileplugin->update_file_count($grade); // Update the last modified time on the grade which will trigger student notifications. $assignment->notify_grade_modified($grade); } } } require_once($CFG->dirroot . '/mod/assign/feedback/file/renderable.php'); $importsummary = new assignfeedback_file_import_summary($assignment->get_course_module()->id, count($userswithnewfeedback), $feedbackfilesadded, $feedbackfilesupdated); $assignrenderer = $assignment->get_renderer(); $renderer = $PAGE->get_renderer('assignfeedback_file'); $o = ''; $o .= $assignrenderer->render(new assign_header($assignment->get_instance(), $assignment->get_context(), false, $assignment->get_course_module()->id, get_string('uploadzipsummary', 'assignfeedback_file'))); $o .= $renderer->render($importsummary); $o .= $assignrenderer->render_footer(); return $o; }
/** * Tests for importing grades from an external source. */ public function test_grade_import_commit() { global $USER, $DB, $CFG; $this->resetAfterTest(); $importcode = get_new_importcode(); $user1 = $this->getDataGenerator()->create_user(); $user2 = $this->getDataGenerator()->create_user(); $course = $this->getDataGenerator()->create_course(); $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); $itemname = $assign->name; $modulecontext = context_module::instance($assign->cmid); // The generator returns a dummy object, lets get the real assign object. $assign = new assign($modulecontext, false, false); $cm = $assign->get_course_module(); // Enrol users in the course. $this->getDataGenerator()->enrol_user($user1->id, $course->id); $this->getDataGenerator()->enrol_user($user2->id, $course->id); // Enter a new grade into an existing grade item. $gradeitem = grade_item::fetch(array('courseid' => $course->id, 'itemtype' => 'mod')); // Keep this value around for a test further down. $originalgrade = 55; $this->import_grades(array('importcode' => $importcode, 'itemid' => $gradeitem->id, 'userid' => $user1->id, 'finalgrade' => $originalgrade)); $status = grade_import_commit($course->id, $importcode, false, false); $this->assertTrue($status); // Get imported grade_grade. $gradegrade = grade_grade::fetch(array('itemid' => $gradeitem->id, 'userid' => $user1->id)); $this->assertEquals($originalgrade, $gradegrade->finalgrade); // Overriden field will be a timestamp and will evaluate out to true. $this->assertTrue($gradegrade->is_overridden()); // Create a new grade item and import into that. $importcode = get_new_importcode(); $record = new stdClass(); $record->itemname = 'New grade item'; $record->importcode = $importcode; $record->importer = $USER->id; $insertid = $DB->insert_record('grade_import_newitem', $record); $finalgrade = 75; $this->import_grades(array('importcode' => $importcode, 'userid' => $user1->id, 'finalgrade' => $finalgrade, 'newgradeitem' => $insertid)); $status = grade_import_commit($course->id, $importcode, false, false); $this->assertTrue($status); // Check that we have a new grade_item. $gradeitem = grade_item::fetch(array('courseid' => $course->id, 'itemtype' => 'manual')); $this->assertEquals($record->itemname, $gradeitem->itemname); // Grades were imported. $gradegrade = grade_grade::fetch(array('itemid' => $gradeitem->id, 'userid' => $user1->id)); $this->assertEquals($finalgrade, $gradegrade->finalgrade); // As this is a new item the grade has not been overridden. $this->assertFalse($gradegrade->is_overridden()); // Import feedback only. $importcode = get_new_importcode(); $gradeitem = grade_item::fetch(array('courseid' => $course->id, 'itemtype' => 'mod')); $originalfeedback = 'feedback can be useful'; $this->import_grades(array('importcode' => $importcode, 'userid' => $user1->id, 'itemid' => $gradeitem->id, 'feedback' => $originalfeedback, 'importonlyfeedback' => true)); $status = grade_import_commit($course->id, $importcode, true, false); $this->assertTrue($status); $gradegrade = grade_grade::fetch(array('itemid' => $gradeitem->id, 'userid' => $user1->id)); // The final grade should be the same as the first record further up. We are only altering the feedback. $this->assertEquals($originalgrade, $gradegrade->finalgrade); $this->assertTrue($gradegrade->is_overridden()); // Import grades only. $importcode = get_new_importcode(); $gradeitem = grade_item::fetch(array('courseid' => $course->id, 'itemtype' => 'mod')); $finalgrade = 60; $this->import_grades(array('importcode' => $importcode, 'userid' => $user1->id, 'itemid' => $gradeitem->id, 'finalgrade' => $finalgrade, 'feedback' => 'feedback can still be useful')); $status = grade_import_commit($course->id, $importcode, false, false); $this->assertTrue($status); $gradegrade = grade_grade::fetch(array('itemid' => $gradeitem->id, 'userid' => $user1->id)); $this->assertEquals($finalgrade, $gradegrade->finalgrade); // The final feedback should not have changed. $this->assertEquals($originalfeedback, $gradegrade->feedback); $this->assertTrue($gradegrade->is_overridden()); // Check that printing of import status is correct. $importcode = get_new_importcode(); $gradeitem = grade_item::fetch(array('courseid' => $course->id, 'itemtype' => 'mod')); $this->import_grades(array('importcode' => $importcode, 'userid' => $user1->id, 'itemid' => $gradeitem->id)); $url = $CFG->wwwroot . '/grade/index.php'; $expectedresponse = "++ Grade import success ++\n<div class=\"continuebutton\"><form method=\"get\" action=\"{$url}\"><div><input type=\"submit\" value=\"Continue\" /><input type=\"hidden\" name=\"id\" value=\"{$course->id}\" /></div></form></div>"; ob_start(); $status = grade_import_commit($course->id, $importcode); $output = ob_get_contents(); ob_end_clean(); $this->assertTrue($status); $this->assertEquals($expectedresponse, $output); }
/** * Process an uploaded zip file * * @param assign $assignment - The assignment instance * @param assign_feedback_file $fileplugin - The file feedback plugin * @return string - The html response */ public function import_zip_files($assignment, $fileplugin) { global $CFG, $PAGE, $DB; core_php_time_limit::raise(ASSIGNFEEDBACK_FILE_MAXFILEUNZIPTIME); $packer = get_file_packer('application/zip'); $feedbackfilesupdated = 0; $feedbackfilesadded = 0; $userswithnewfeedback = array(); $contextid = $assignment->get_context()->id; $fs = get_file_storage(); $files = $this->get_import_files($contextid); $currentgroup = groups_get_activity_group($assignment->get_course_module(), true); $allusers = $assignment->list_participants($currentgroup, false); $participants = array(); foreach ($allusers as $user) { $participants[$assignment->get_uniqueid_for_user($user->id)] = $user; } foreach ($files as $unzippedfile) { // Set the timeout for unzipping each file. $user = null; $plugin = null; $filename = ''; if ($this->is_valid_filename_for_import($assignment, $unzippedfile, $participants, $user, $plugin, $filename)) { if ($this->is_file_modified($assignment, $user, $plugin, $filename, $unzippedfile)) { $grade = $assignment->get_user_grade($user->id, true); // In 3.1 the default download structure of the submission files changed so that each student had their own // separate folder, the files were not renamed and the folder structure was kept. It is possible that // a user downloaded the submission files in 3.0 (or earlier) and edited the zip to add feedback or // changed the behavior back to the previous format, the following code means that we will still support the // old file structure. For more information please see - MDL-52489 / MDL-56022. $path = pathinfo($filename); if ($path['dirname'] == '.') { // Student submissions are not in separate folders. $basename = $filename; $dirname = "/"; $dirnamewslash = "/"; } else { $basename = $path['basename']; $dirname = $path['dirname']; $dirnamewslash = $dirname . "/"; } if ($oldfile = $fs->get_file($contextid, 'assignfeedback_file', ASSIGNFEEDBACK_FILE_FILEAREA, $grade->id, $dirname, $basename)) { // Update existing feedback file. $oldfile->replace_file_with($unzippedfile); $feedbackfilesupdated++; } else { // Create a new feedback file. $newfilerecord = new stdClass(); $newfilerecord->contextid = $contextid; $newfilerecord->component = 'assignfeedback_file'; $newfilerecord->filearea = ASSIGNFEEDBACK_FILE_FILEAREA; $newfilerecord->filename = $basename; $newfilerecord->filepath = $dirnamewslash; $newfilerecord->itemid = $grade->id; $fs->create_file_from_storedfile($newfilerecord, $unzippedfile); $feedbackfilesadded++; } $userswithnewfeedback[$user->id] = 1; // Update the number of feedback files for this user. $fileplugin->update_file_count($grade); // Update the last modified time on the grade which will trigger student notifications. $assignment->notify_grade_modified($grade); } } } require_once $CFG->dirroot . '/mod/assign/feedback/file/renderable.php'; $importsummary = new assignfeedback_file_import_summary($assignment->get_course_module()->id, count($userswithnewfeedback), $feedbackfilesadded, $feedbackfilesupdated); $assignrenderer = $assignment->get_renderer(); $renderer = $PAGE->get_renderer('assignfeedback_file'); $o = ''; $o .= $assignrenderer->render(new assign_header($assignment->get_instance(), $assignment->get_context(), false, $assignment->get_course_module()->id, get_string('uploadzipsummary', 'assignfeedback_file'))); $o .= $renderer->render($importsummary); $o .= $assignrenderer->render_footer(); return $o; }
/** * Makes the grading interface for the pop up. Robbed from /mod/assign/locallib.php * line 1583ish - view_single_grade_page(). * * @param array $params From $_GET * @param object $coursemodule The coursemodule object that the user has been authenticated * against * @param bool $data * @throws coding_exception * @global $PAGE * @global stdClass $CFG * @global moodle_database $DB * @global $OUTPUT * @global stdClass $USER * @return string */ public function grading_popup($params, $coursemodule, $data = false) { global $PAGE, $CFG, $DB; $modulecontext = context_module::instance($coursemodule->id); $course = $DB->get_record('course', array('id' => $coursemodule->course)); $coursecontext = context_course::instance($course->id); $assign = new assign($modulecontext, $coursemodule, $course); /* @var mod_assign_renderer $renderer */ $renderer = $PAGE->get_renderer('mod_assign'); $output = ''; // Include grade form. require_once $CFG->dirroot . '/mod/assign/gradeform.php'; // Need submit permission to submit an assignment. require_capability('mod/assign:grade', $modulecontext); /* Pinched from private method assign::get_grading_userid_list() */ $filter = get_user_preferences('assign_filter', ''); $table = new assign_grading_table($assign, 0, $filter, 0, false); $useridlist = $table->get_column_data('userid'); $userid = $params['userid']; $rownum = 0; foreach ($useridlist as $key => $useridinlist) { if ($useridinlist == $userid) { $rownum = $key; reset($useridlist); // Just in case. break; } } $last = false; if ($rownum == count($useridlist) - 1) { $last = true; } $user = $DB->get_record('user', array('id' => $userid)); if ($user) { $output .= $renderer->render(new assign_user_summary($user, $course->id, has_capability('moodle/site:viewfullnames', $coursecontext))); } $submission = $DB->get_record('assign_submission', array('assignment' => $assign->get_instance()->id, 'userid' => $userid)); // Get the current grade. Pinched from assign::get_user_grade(). $grade = $DB->get_record('assign_grades', array('assignment' => $assign->get_instance()->id, 'userid' => $userid)); // Pinched from assign::is_graded(). $isgraded = !empty($grade) && $grade->grade !== null && $grade->grade >= 0; if ($assign->can_view_submission($userid)) { $gradelocked = $grade && $grade->locked || $assign->grading_disabled($userid); $widget = new assign_submission_status($assign->get_instance()->allowsubmissionsfromdate, $assign->get_instance()->alwaysshowdescription, $submission, $assign->is_any_submission_plugin_enabled(), $gradelocked, $isgraded, $assign->get_instance()->duedate, $assign->get_submission_plugins(), $assign->get_return_action(), $assign->get_return_params(), $assign->get_course_module()->id, assign_submission_status::GRADER_VIEW, false, false); $output .= $renderer->render($widget); } if ($grade) { $data = new stdClass(); if ($grade->grade !== null && $grade->grade >= 0) { $data->grade = format_float($grade->grade, 2); } } else { $data = new stdClass(); $data->grade = ''; } // Now show the grading form. $customdata = array('useridlist' => $useridlist, 'rownum' => $rownum, 'last' => $last); $mform = new mod_assign_grade_form(block_ajax_marking_form_url($params), array($assign, $data, $customdata), 'post', '', array('class' => 'gradeform')); $output .= $renderer->render(new assign_form('gradingform', $mform)); $assign->add_to_log('view grading form', get_string('viewgradingformforstudent', 'assign', array('id' => $user->id, 'fullname' => fullname($user)))); return $output; }