MDL-46171 Assign: Update code so latest field on assign_submission table is always set correctly

This commit is contained in:
Damyon Wiese 2014-07-24 15:13:11 +08:00
parent 587341138f
commit 1523f9e0fb
7 changed files with 126 additions and 3 deletions

View File

@ -88,7 +88,8 @@ class backup_assign_activity_structure_step extends backup_activity_structure_st
'timemodified',
'status',
'groupid',
'attemptnumber'));
'attemptnumber',
'latest'));
$grades = new backup_nested_element('grades');

View File

@ -231,6 +231,54 @@ class restore_assign_activity_structure_step extends restore_activity_structure_
$newitemid = $DB->insert_record('assign_plugin_config', $data);
}
/**
* For all submissions in this assignment, either set the submission->latest field to 1 for the latest attempts.
*
* @return void
*/
protected function set_latest_submission_field() {
global $DB;
$assignmentid = $this->get_new_parentid('assign');
// This code could be rewritten as a monster SQL - but the point of adding this "latest" field
// to the submissions table in the first place was to get away from those hard to maintain SQL queries.
// First user submissions.
$sql = 'SELECT DISTINCT userid FROM {assign_submission} WHERE assignment = ? AND groupid = ?';
$params = array($assignmentid, 0);
$users = $DB->get_records_sql($sql, $params);
foreach ($users as $userid => $unused) {
$params = array('assignment'=>$assignmentid, 'groupid'=>0, 'userid'=>$userid);
// Only return the row with the highest attemptnumber.
$submission = null;
$submissions = $DB->get_records('assign_submission', $params, 'attemptnumber DESC', '*', 0, 1);
if ($submissions) {
$submission = reset($submissions);
$submission->latest = 1;
$DB->update_record('assign_submission', $submission);
}
}
// Then group submissions (if any).
$sql = 'SELECT DISTINCT groupid FROM {assign_submission} WHERE assignment = ? AND userid = ?';
$params = array($assignmentid, 0);
$groups = $DB->get_records_sql($sql, $params);
foreach ($groups as $groupid => $unused) {
$params = array('assignment'=>$assignmentid, 'userid'=>0, 'groupid'=>$groupid);
// Only return the row with the highest attemptnumber.
$submission = null;
$submissions = $DB->get_records('assign_submission', $params, 'attemptnumber DESC', '*', 0, 1);
if ($submissions) {
$submission = reset($submissions);
$submission->latest = 1;
$DB->update_record('assign_submission', $submission);
}
}
}
/**
* Once the database tables have been fully restored, restore the files
* @return void
@ -238,5 +286,7 @@ class restore_assign_activity_structure_step extends restore_activity_structure_
protected function after_execute() {
$this->add_related_files('mod_assign', 'intro', null);
$this->add_related_files('mod_assign', 'introattachment', null);
$this->set_latest_submission_field();
}
}

View File

@ -523,6 +523,35 @@ function xmldb_assign_upgrade($oldversion) {
// Assign savepoint reached.
upgrade_mod_savepoint(true, 2014072401, 'assign');
}
if ($oldversion < 2014072403) {
// Prevent running this multiple times.
$countsql = 'SELECT COUNT(id) FROM {assign_submission} WHERE latest = ?;';
$count = $DB->count_records_sql($countsql, array(1));
if ($count == 0) {
// Mark the latest attempt for every submission in mod_assign.
$maxattemptsql = 'SELECT assignment, userid, groupid, max(attemptnumber) AS maxattempt
FROM mdl23_assign_submission
GROUP BY assignment, groupid, userid';
$maxattemptidssql = 'SELECT souter.id
FROM mdl23_assign_submission souter
JOIN (' . $maxattemptsql . ') sinner
ON souter.assignment = sinner.assignment
AND souter.userid = sinner.userid
AND souter.groupid = sinner.groupid
AND souter.attemptnumber = sinner.maxattempt';
$select = 'id IN(' . $maxattemptidssql . ')';
$DB->set_field_select('assign_submission', 'latest', 1, $select);
}
// Assign savepoint reached.
upgrade_mod_savepoint(true, 2014072403, 'assign');
}
return true;
}

View File

@ -2082,7 +2082,26 @@ class assign {
} else {
$submission->attemptnumber = 0;
}
// Work out if this is the latest submission.
$submission->latest = 0;
$params = array('assignment'=>$this->get_instance()->id, 'groupid'=>$groupid, 'userid'=>0);
if ($attemptnumber == -1) {
// This is a new submission so it must be the latest.
$submission->latest = 1;
} else {
// We need to work this out.
$result = $DB->get_records('assign_submission', $params, 'attemptnumber DESC', 'attemptnumber', 0, 1);
if ($result) {
$latestsubmission = reset($result);
}
if (!$latestsubmission || ($attemptnumber == $latestsubmission->attemptnumber)) {
$submission->latest = 1;
}
}
if ($submission->latest) {
// This is the case when we need to set latest to 0 for all the other attempts.
$DB->set_field('assign_submission', 'latest', 0, $params);
}
$submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
$sid = $DB->insert_record('assign_submission', $submission);
return $DB->get_record('assign_submission', array('id' => $sid));
@ -2690,6 +2709,26 @@ class assign {
} else {
$submission->attemptnumber = 0;
}
// Work out if this is the latest submission.
$submission->latest = 0;
$params = array('assignment'=>$this->get_instance()->id, 'userid'=>$userid, 'groupid'=>0);
if ($attemptnumber == -1) {
// This is a new submission so it must be the latest.
$submission->latest = 1;
} else {
// We need to work this out.
$result = $DB->get_records('assign_submission', $params, 'attemptnumber DESC', 'attemptnumber', 0, 1);
if ($result) {
$latestsubmission = reset($result);
}
if (!$latestsubmission || ($attemptnumber == $latestsubmission->attemptnumber)) {
$submission->latest = 1;
}
}
if ($submission->latest) {
// This is the case when we need to set latest to 0 for all the other attempts.
$DB->set_field('assign_submission', 'latest', 0, $params);
}
$sid = $DB->insert_record('assign_submission', $submission);
return $DB->get_record('assign_submission', array('id' => $sid));
}

View File

@ -244,6 +244,7 @@ class mod_assign_external_testcase extends externallib_advanced_testcase {
$submission->timemodified = $submission->timecreated;
$submission->status = 'draft';
$submission->attemptnumber = 0;
$submission->latest = 0;
$sid = $DB->insert_record('assign_submission', $submission);
// Second attempt.
@ -254,6 +255,7 @@ class mod_assign_external_testcase extends externallib_advanced_testcase {
$submission->timemodified = $submission->timecreated;
$submission->status = 'submitted';
$submission->attemptnumber = 1;
$submission->latest = 1;
$sid = $DB->insert_record('assign_submission', $submission);
$submission->id = $sid;

View File

@ -212,6 +212,8 @@ class assign_upgrade_manager {
$submission->timecreated = $oldsubmission->timecreated;
$submission->timemodified = $oldsubmission->timemodified;
$submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
// Because in mod_assignment there could only be one submission per student, it is always the latest.
$submission->latest = 1;
$submission->id = $DB->insert_record('assign_submission', $submission);
if (!$submission->id) {
$log .= get_string('couldnotinsertsubmission', 'mod_assign', $submission->userid);

View File

@ -25,7 +25,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'mod_assign'; // Full name of the plugin (used for diagnostics).
$plugin->version = 2014072401; // The current module version (Date: YYYYMMDDXX).
$plugin->version = 2014072403; // The current module version (Date: YYYYMMDDXX).
$plugin->requires = 2014050800; // Requires this Moodle version.
$plugin->cron = 60;