MDL-36804 Assignment - Make sure webservice only returns the last submission/grade.
authorDamyon Wiese <damyon.wiese@gmail.com>
Fri, 22 Mar 2013 15:32:53 +0000 (23:32 +0800)
committerDamyon Wiese <damyon@moodle.com>
Tue, 2 Apr 2013 05:37:51 +0000 (13:37 +0800)
mod/assign/externallib.php
mod/assign/tests/externallib_test.php

index 15f576e..b168b20 100644 (file)
@@ -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'];
index b56ffee..bfc2ac1 100644 (file)
@@ -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;