public static function graded() { global $USER, $PAGE; $output = $PAGE->get_renderer('theme_snap', 'core', RENDERER_TARGET_GENERAL); $grades = activity::events_graded(); $o = ''; foreach ($grades as $grade) { $modinfo = get_fast_modinfo($grade->courseid); $course = $modinfo->get_course(); $modtype = $grade->itemmodule; $cm = $modinfo->instances[$modtype][$grade->iteminstance]; $coursecontext = \context_course::instance($grade->courseid); $canviewhiddengrade = has_capability('moodle/grade:viewhidden', $coursecontext); $url = new \moodle_url('/grade/report/user/index.php', ['id' => $grade->courseid]); if (in_array($modtype, ['quiz', 'assign']) && (!empty($grade->rawgrade) || !empty($grade->feedback))) { // Only use the course module url if the activity was graded in the module, not in the gradebook, etc. $url = $cm->url; } $modimageurl = $output->pix_url('icon', $cm->modname); $modname = get_string('modulename', 'mod_' . $cm->modname); $modimage = \html_writer::img($modimageurl, $modname); $gradetitle = "<small>{$course->fullname} / </small> {$cm->name}"; $releasedon = isset($grade->timemodified) ? $grade->timemodified : $grade->timecreated; $meta = get_string('released', 'theme_snap', $output->friendly_datetime($releasedon)); $grade = new \grade_grade(array('itemid' => $grade->itemid, 'userid' => $USER->id)); if (!$grade->is_hidden() || $canviewhiddengrade) { $o .= $output->snap_media_object($url, $modimage, $gradetitle, $meta, ''); } } if (empty($o)) { return '<p>' . get_string('nograded', 'theme_snap') . '</p>'; } return $o; }
public function test_events_graded() { $this->setUser($this->editingteachers[0]); $this->create_instance(); $assign = $this->create_instance(array('duedate' => time(), 'submissiondrafts' => 1, 'assignsubmission_onlinetext_enabled' => 1)); // Add a submission. $this->setUser($this->students[0]); $submission = $assign->get_user_submission($this->students[0]->id, true); $data = new stdClass(); $data->onlinetext_editor = array('itemid' => file_get_unused_draft_itemid(), 'text' => 'Submission text', 'format' => FORMAT_HTML); $plugin = $assign->get_submission_plugin_by_type('onlinetext'); $plugin->save($submission, $data); // And now submit it for marking. $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; $assign->testable_update_submission($submission, $this->students[0]->id, true, false); // Mark the submission. $this->setUser($this->teachers[0]); $data = new stdClass(); $data->grade = '50.0'; $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0); // TODO remove this next line when the above is fixed to stop triggering debug messages. $this->resetDebugging(); $this->setUser($this->students[0]); $actual = activity::events_graded(); $this->assertCount(1, $actual); $this->setUser($this->students[1]); $actual = activity::events_graded(); $this->assertCount(0, $actual); }
/** * Test feedback with assignment restricted to future date. * * @throws \coding_exception */ public function test_feedback_restricted() { global $DB; $this->resetAfterTest(); $generator = $this->getDataGenerator(); $course = $generator->create_course(); $student = $generator->create_user(); // Enrol student. $studentrole = $DB->get_record('role', array('shortname' => 'student')); $generator->enrol_user($student->id, $course->id, $studentrole->id); // Create assign instance. $this->create_assignment($course->id, time() + DAYSECS * 2); $actual = local::upcoming_deadlines($student->id); $expected = 1; $this->assertCount($expected, $actual); // Create restricted assign instance. $opts = ['availability' => $this->get_date_condition_json(time() + WEEKSECS)]; $assign = $this->create_assignment($course->id, time() + DAYSECS * 2, $opts); // Mark restricted assign instasnce. $data = $assign->get_user_grade($student->id, true); $data->grade = '50.5'; $assign->update_grade($data); // Student should only see 1 feedback item as one is normal and one is restricted until next week. $this->setUser($student); $actual = activity::events_graded(); $expected = 1; $this->assertCount($expected, $actual); }
/** * Get the module meta data for a specific module. * * @param cm_info $mod * @return string */ protected function module_meta_html(cm_info $mod) { global $COURSE; $content = ''; if (is_guest(context_course::instance($COURSE->id))) { return ''; } // Do we have an activity function for this module for returning meta data? // @todo - check module lib.php for a meta function (won't work for core mods but will for ours if we wish). $meta = activity::module_meta($mod); if (!$meta->is_set(true)) { // Can't get meta data for this module. return ''; } $content .= ''; if ($meta->isteacher) { // Teacher - useful teacher meta data. if (!empty($meta->timeclose)) { $due = get_string('due', 'theme_snap'); $dateformat = get_string('strftimedate', 'langconfig'); $labeltext = $due . ' ' . userdate($meta->timeclose, $dateformat); $labelclass = 'label label-info'; $url = new \moodle_url("/mod/{$mod->modname}/view.php", ['id' => $mod->id]); $content .= html_writer::link($url, $labeltext, ['class' => $labelclass]); } $engagementmeta = array(); $gradedlabel = "info"; // Below, !== false means we get 0 out of x submissions. if (!$meta->submissionnotrequired && $meta->numsubmissions !== false) { $engagementmeta[] = get_string('xofy' . $meta->submitstrkey, 'theme_snap', (object) array('completed' => $meta->numsubmissions, 'participants' => \theme_snap\local::course_participant_count($COURSE->id, $mod->modname))); } if ($meta->numrequiregrading) { $gradedlabel = "warning"; $engagementmeta[] = get_string('xungraded', 'theme_snap', $meta->numrequiregrading); } if (!empty($engagementmeta)) { $engagementstr = implode(', ', $engagementmeta); $params = array('action' => 'grading', 'id' => $mod->id, 'tsort' => 'timesubmitted', 'filter' => 'require_grading'); $url = new moodle_url("/mod/{$mod->modname}/view.php", $params); $content .= html_writer::link($url, $engagementstr, ['class' => "label label-{$gradedlabel}"]); } } else { // Student - useful student meta data. if (!empty($meta->timeopen) && $meta->timeopen > time()) { // TODO - spit out a 'submissions allowed form' tag. return $content; } // Note, due date is rendered seperately for students as it has a warning class if overdue. if (!empty($meta->timeclose)) { if ($meta->overdue) { $dueinfo = $meta->overduestr; $status = 'danger'; } else { $dueinfo = $meta->duestr; $status = 'info'; } $url = new \moodle_url("/mod/{$mod->modname}/view.php", ['id' => $mod->id]); $dateformat = get_string('strftimedate', 'langconfig'); $labeltext = $dueinfo . ' ' . userdate($meta->timeclose, $dateformat); $labelclass = "label label-{$status}"; $content .= html_writer::link($url, $labeltext, ['class' => $labelclass]); } // Feedback meta. if (!empty($meta->grade)) { // Note - the link that a module takes you to would be better off defined by a function in // theme/snap/activity - for now its just hard coded. $url = new \moodle_url('/grade/report/user/index.php', ['id' => $COURSE->id]); if (in_array($mod->modname, ['quiz', 'assign'])) { $url = new \moodle_url('/mod/' . $mod->modname . '/view.php?id=' . $mod->id); } $feedbackavailable = get_string('feedbackavailable', 'theme_snap'); $content .= html_writer::link($url, $feedbackavailable, ['class' => 'label label-info']); } $content .= $this->submission_cta($mod, $meta); } return $content; }