diff --git a/mod/assign/lib.php b/mod/assign/lib.php
index 8e031efd186..b337327b063 100644
--- a/mod/assign/lib.php
+++ b/mod/assign/lib.php
@@ -390,9 +390,14 @@ function assign_print_overview($courses, &$htmlarray) {
$context = context_module::instance($assignment->coursemodule);
if (has_capability('mod/assign:grade', $context)) {
if (!isset($unmarkedsubmissions)) {
+ $submissionmaxattempt = 'SELECT mxs.userid, MAX(mxs.attemptnumber) AS maxattempt, mxs.assignment
+ FROM {assign_submission} mxs
+ WHERE mxs.assignment ' . $sqlassignmentids . '
+ GROUP BY mxs.userid, mxs.assignment';
+
// Build up and array of unmarked submissions indexed by assignment id/ userid
// for use where the user has grading rights on assignment.
- $dbparams = array_merge(array(ASSIGN_SUBMISSION_STATUS_SUBMITTED), $assignmentidparams);
+ $dbparams = array_merge($assignmentidparams, array(ASSIGN_SUBMISSION_STATUS_SUBMITTED), $assignmentidparams);
$rs = $DB->get_recordset_sql('SELECT
s.assignment as assignment,
s.userid as userid,
@@ -400,14 +405,19 @@ function assign_print_overview($courses, &$htmlarray) {
s.status as status,
g.timemodified as timegraded
FROM {assign_submission} s
+ LEFT JOIN ( ' . $submissionmaxattempt . ' ) smx ON
+ smx.userid = s.userid AND
+ smx.assignment = s.id
LEFT JOIN {assign_grades} g ON
s.userid = g.userid AND
- s.assignment = g.assignment
+ s.assignment = g.assignment AND
+ g.attemptnumber = smx.maxattempt
WHERE
( g.timemodified is NULL OR
s.timemodified > g.timemodified ) AND
s.timemodified IS NOT NULL AND
s.status = ? AND
+ s.attemptnumber = smx.maxattempt AND
s.assignment ' . $sqlassignmentids, $dbparams);
$unmarkedsubmissions = array();
@@ -438,8 +448,16 @@ function assign_print_overview($courses, &$htmlarray) {
}
if (has_capability('mod/assign:submit', $context)) {
if (!isset($mysubmissions)) {
+
+ // This is nasty because we only want the last attempt.
+ $submissionmaxattempt = 'SELECT mxs.userid, MAX(mxs.attemptnumber) AS maxattempt, mxs.assignment
+ FROM {assign_submission} mxs
+ WHERE mxs.assignment ' . $sqlassignmentids . '
+ AND mxs.userid = ?
+ GROUP BY mxs.userid, mxs.assignment';
+
// Get all user submissions, indexed by assignment id.
- $dbparams = array_merge(array($USER->id, $USER->id), $assignmentidparams);
+ $dbparams = array_merge($assignmentidparams, array($USER->id, $USER->id, $USER->id), $assignmentidparams);
$mysubmissions = $DB->get_records_sql('SELECT
a.id AS assignment,
a.nosubmissions AS nosubmissions,
@@ -448,10 +466,14 @@ function assign_print_overview($courses, &$htmlarray) {
g.grade AS grade,
s.status AS status
FROM {assign} a
+ LEFT JOIN ( ' . $submissionmaxattempt . ' ) smx ON
+ smx.assignment = a.id
LEFT JOIN {assign_grades} g ON
g.assignment = a.id AND
- g.userid = ?
+ g.userid = ? AND
+ g.attemptnumber = smx.maxattempt
LEFT JOIN {assign_submission} s ON
+ s.attemptnumber = smx.maxattempt AND
s.assignment = a.id AND
s.userid = ?
WHERE a.id ' . $sqlassignmentids, $dbparams);
@@ -459,15 +481,18 @@ function assign_print_overview($courses, &$htmlarray) {
$str .= '
';
$str .= get_string('mysubmission', 'assign');
- $submission = $mysubmissions[$assignment->id];
- if ($submission->nosubmissions) {
- $str .= get_string('offline', 'assign');
- } else if (!$submission->status || $submission->status == 'draft') {
+ $submission = false;
+ if (isset($mysubmissions[$assignment->id])) {
+ $submission = $mysubmissions[$assignment->id];
+ }
+ if (!$submission || !$submission->status || $submission->status == 'draft') {
$str .= $strnotsubmittedyet;
+ } else if ($submission->nosubmissions) {
+ $str .= get_string('offline', 'assign');
} else {
$str .= get_string('submissionstatus_' . $submission->status, 'assign');
}
- if (!$submission->grade || $submission->grade < 0) {
+ if (!$submission || !$submission->grade || $submission->grade < 0) {
$str .= ', ' . get_string('notgraded', 'assign');
} else {
$str .= ', ' . get_string('graded', 'assign');
diff --git a/mod/assign/tests/lib_test.php b/mod/assign/tests/lib_test.php
index 290191cd743..f24a792218f 100644
--- a/mod/assign/tests/lib_test.php
+++ b/mod/assign/tests/lib_test.php
@@ -39,14 +39,74 @@ require_once($CFG->dirroot . '/mod/assign/tests/base_test.php');
*/
class mod_assign_lib_testcase extends mod_assign_base_testcase {
- public function test_assign_print_overview() {
- global $DB;
+ protected function setUp() {
+ parent::setUp();
+
+ // Add additional default data (some real attempts and stuff).
$this->setUser($this->editingteachers[0]);
$this->create_instance();
- $this->create_instance(array('duedate'=>time()));
+ $assign = $this->create_instance(array('duedate' => time(),
+ 'attemptreopenmethod' => ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL,
+ 'maxattempts' => 3,
+ '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);
+
+ // This is required so that the submissions timemodified > the grade timemodified.
+ sleep(2);
+
+ // Edit the submission again.
+ $this->setUser($this->students[0]);
+ $submission = $assign->get_user_submission($this->students[0]->id, true);
+ $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
+
+ // This is required so that the submissions timemodified > the grade timemodified.
+ sleep(2);
+
+ // Allow the student another attempt.
+ $this->teachers[0]->ignoresesskey = true;
+ $this->setUser($this->teachers[0]);
+ $result = $assign->testable_process_add_attempt($this->students[0]->id);
+ // Add another 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 2',
+ 'format' => FORMAT_HTML);
+ $plugin = $assign->get_submission_plugin_by_type('onlinetext');
+ $plugin->save($submission, $data);
+
+ // And now submit it for marking (again).
+ $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
+ $assign->testable_update_submission($submission, $this->students[0]->id, true, false);
+ }
+
+ public function test_assign_print_overview() {
+ global $DB;
$courses = $DB->get_records('course', array('id' => $this->course->id));
+
+ // Check the overview as the different users.
$this->setUser($this->students[0]);
$overview = array();
assign_print_overview($courses, $overview);
@@ -113,7 +173,7 @@ class mod_assign_lib_testcase extends mod_assign_base_testcase {
$this->setUser($this->editingteachers[0]);
$assign = $this->create_instance(array('submissiondrafts' => 1));
- $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id'=>$assign->get_course_module()->id)));
+ $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
$submission = $assign->get_user_submission($this->students[0]->id, true);
@@ -137,7 +197,7 @@ class mod_assign_lib_testcase extends mod_assign_base_testcase {
public function test_assign_get_completion_state() {
global $DB;
- $assign = $this->create_instance(array('submissiondrafts'=>0, 'completionsubmit'=>1));
+ $assign = $this->create_instance(array('submissiondrafts' => 0, 'completionsubmit' => 1));
$this->setUser($this->students[0]);
$result = assign_get_completion_state($this->course, $assign->get_course_module(), $this->students[0]->id, false);