diff --git a/mod/assign/externallib.php b/mod/assign/externallib.php index 15f576e62ca..b168b2012fc 100644 --- a/mod/assign/externallib.php +++ b/mod/assign/externallib.php @@ -95,13 +95,23 @@ class mod_assign_external extends external_api { if (count ($requestedassignmentids) > 0) { $placeholders = array(); list($inorequalsql, $placeholders) = $DB->get_in_or_equal($requestedassignmentids, SQL_PARAMS_NAMED); + list($inorequalsql2, $placeholders2) = $DB->get_in_or_equal($requestedassignmentids, SQL_PARAMS_NAMED); + + $grademaxattempt = 'SELECT mxg.userid, MAX(mxg.attemptnumber) AS maxattempt + FROM {assign_grades} mxg + WHERE mxg.assignment ' . $inorequalsql2 . ' GROUP BY mxg.userid'; + $sql = "SELECT ag.id,ag.assignment,ag.userid,ag.timecreated,ag.timemodified,". "ag.grader,ag.grade ". "FROM {assign_grades} ag ". - "WHERE ag.assignment ".$inorequalsql. + "JOIN ( " . $grademaxattempt . " ) gmx ON ag.userid = gmx.userid". + " WHERE ag.assignment ".$inorequalsql. " AND ag.timemodified >= :since". + " AND ag.attemptnumber = gmx.maxattempt" . " ORDER BY ag.assignment, ag.id"; $placeholders['since'] = $params['since']; + // Combine the parameters. + $placeholders += $placeholders2; $rs = $DB->get_recordset_sql($sql, $placeholders); $currentassignmentid = null; $assignment = null; @@ -500,11 +510,18 @@ class mod_assign_external extends external_api { foreach ($assigns as $assign) { $submissions = array(); $submissionplugins = $assign->get_submission_plugins(); - $placeholders = array('assignment' => $assign->get_instance()->id); + $placeholders = array('assignid1' => $assign->get_instance()->id, + 'assignid2' => $assign->get_instance()->id); + + $submissionmaxattempt = 'SELECT mxs.userid, MAX(mxs.attemptnumber) AS maxattempt + FROM {assign_submission} mxs + WHERE mxs.assignment = :assignid1 GROUP BY mxs.userid'; + $sql = "SELECT mas.id, mas.assignment,mas.userid,". "mas.timecreated,mas.timemodified,mas.status,mas.groupid ". "FROM {assign_submission} mas ". - "WHERE mas.assignment = :assignment"; + "JOIN ( " . $submissionmaxattempt . " ) smx ON mas.userid = smx.userid ". + "WHERE mas.assignment = :assignid2 AND mas.attemptnumber = smx.maxattempt"; if (!empty($params['status'])) { $placeholders['status'] = $params['status']; diff --git a/mod/assign/tests/externallib_test.php b/mod/assign/tests/externallib_test.php index b56ffeea956..bfc2ac12843 100644 --- a/mod/assign/tests/externallib_test.php +++ b/mod/assign/tests/externallib_test.php @@ -75,8 +75,20 @@ class mod_assign_external_testcase extends externallib_advanced_testcase { $user_enrolment_data['userid'] = $USER->id; $DB->insert_record('user_enrolments', $user_enrolment_data); - // Create a student and give them a grade. + // Create a student and give them 2 grades (for 2 attempts). $student = self::getDataGenerator()->create_user(); + $grade = new stdClass(); + $grade->assignment = $assign->id; + $grade->userid = $student->id; + $grade->timecreated = time(); + $grade->timemodified = $grade->timecreated; + $grade->grader = $USER->id; + $grade->grade = 50; + $grade->locked = false; + $grade->mailed = true; + $grade->attemptnumber = 0; + $DB->insert_record('assign_grades', $grade); + $grade = new stdClass(); $grade->assignment = $assign->id; $grade->userid = $student->id; @@ -86,6 +98,7 @@ class mod_assign_external_testcase extends externallib_advanced_testcase { $grade->grade = 75; $grade->locked = false; $grade->mailed = true; + $grade->attemptnumber = 1; $DB->insert_record('assign_grades', $grade); $assignmentids[] = $assign->id; @@ -98,9 +111,11 @@ class mod_assign_external_testcase extends externallib_advanced_testcase { $this->assertEquals(1, count($result['assignments'])); $assignment = $result['assignments'][0]; $this->assertEquals($assign->id, $assignment['assignmentid']); + // Should only get the last grade for this student. $this->assertEquals(1, count($assignment['grades'])); $grade = $assignment['grades'][0]; $this->assertEquals($student->id, $grade['userid']); + // Should be the last grade (not the first) $this->assertEquals(75, $grade['grade']); } @@ -218,13 +233,25 @@ class mod_assign_external_testcase extends externallib_advanced_testcase { $assign1 = self::getDataGenerator()->create_module('assign', $assigndata); // Create a student with an online text submission. + // First attempt. $student = self::getDataGenerator()->create_user(); $submission = new stdClass(); $submission->assignment = $assign1->id; $submission->userid = $student->id; $submission->timecreated = time(); $submission->timemodified = $submission->timecreated; + $submission->status = 'draft'; + $submission->attemptnumber = 0; + $sid = $DB->insert_record('assign_submission', $submission); + + // Second attempt. + $submission = new stdClass(); + $submission->assignment = $assign1->id; + $submission->userid = $student->id; + $submission->timecreated = time(); + $submission->timemodified = $submission->timecreated; $submission->status = 'submitted'; + $submission->attemptnumber = 1; $sid = $DB->insert_record('assign_submission', $submission); $submission->id = $sid;