MDL-5482 - Backup and restore problems for match, random and truefalse question types.

All the credit goes to Paulo Matos who carefully worked out and tested this fix, and updated the patch several times over more than a year while I very slowly got around to reviewing it and checking it in.
This commit is contained in:
tjhunt 2008-05-07 12:32:03 +00:00
parent 932f9b6f8d
commit 3ff8a1877a
4 changed files with 81 additions and 13 deletions

View File

@ -390,6 +390,15 @@
}
}
// Fixing bug #5482: random questions have parent field set to its own id,
// see: $QTYPES['random']->get_question_options()
if ($question->qtype == 'random') {
$question->parent = $newid;
//we have to update the random question if the question has been inserted
if ($creatingnewquestion && $newid)
$status = set_field('question', 'parent', $question->parent, 'id', $newid);
}
//Save newid to backup tables
if ($question->id) {
//We have the newid, update backup_ids

View File

@ -596,16 +596,30 @@ class question_match_qtype extends default_questiontype {
//Extract the match_sub for the question and the answer
$exploded = explode("-",$tok);
$match_question_id = $exploded[0];
$match_answer_code = $exploded[1];
$match_answer_id = $exploded[1];
//Get the match_sub from backup_ids (for the question)
if (!$match_que = backup_getid($restore->backup_unique_code,"question_match_sub",$match_question_id)) {
echo 'Could not recode question_match_sub '.$match_question_id.'<br />';
echo 'Could not recode question in question_match_sub '.$match_question_id.'<br />';
}
if ($in_first) {
$answer_field .= $match_que->new_id."-".$match_answer_code;
$in_first = false;
} else {
$answer_field .= ",".$match_que->new_id."-".$match_answer_code;
//Get the match_sub from backup_ids (for the answer)
if ($match_answer_id) { // only recode answer if not 0, not answered yet
if (!$match_ans = backup_getid($restore->backup_unique_code,"question_match_sub",$match_answer_id)) {
echo 'Could not recode answer in question_match_sub '.$match_answer_id.'<br />';
}
}
if ($match_que) {
//If the question hasn't response, it must be 0
if (!$match_ans and $match_answer_id == 0) {
$match_ans->new_id = 0;
}
if ($in_first) {
$answer_field .= $match_que->new_id."-".$match_ans->new_id;
$in_first = false;
} else {
$answer_field .= ",".$match_que->new_id."-".$match_ans->new_id;
}
}
//check for next
$tok = strtok(",");

View File

@ -284,6 +284,49 @@ class random_qtype extends default_questiontype {
->compare_responses($wrappedquestion, $state, $teststate);
}
function restore_recode_answer($state, $restore) {
// The answer looks like 'randomXX-ANSWER', where XX is
// the id of the used question and ANSWER the actual
// response to that question.
// However, there may still be old-style states around,
// which store the id of the wrapped question in the
// state of the random question and store the response
// in a separate state for the wrapped question
global $QTYPES;
$answer_field = "";
if (ereg('^random([0-9]+)-(.*)$', $state->answer, $answerregs)) {
// Recode the question id in $answerregs[1]
// Get the question from backup_ids
if(!$wrapped = backup_getid($restore->backup_unique_code,"question",$answerregs[1])) {
echo 'Could not recode question in random-'.$answerregs[1].'<br />';
return($answer_field);
}
// Get the question type for recursion
if (!$wrappedquestion->qtype = get_field('question', 'qtype', 'id', $wrapped->new_id)) {
echo 'Could not get qtype while recoding question random-'.$answerregs[1].'<br />';
return($answer_field);
}
$newstate = $state;
$newstate->question = $wrapped->new_id;
$newstate->answer = $answerregs[2];
$answer_field = 'random'.$wrapped->new_id.'-';
// Recode the answer field in $answerregs[2] depending on
// the qtype of question with id $answerregs[1]
$answer_field .= $QTYPES[$wrappedquestion->qtype]->restore_recode_answer($newstate, $restore);
} else {
// Handle old-style states
$answer_link = backup_getid($restore->backup_unique_code,"question",$state->answer);
if ($answer_link) {
$answer_field = $answer_link->new_id;
}
}
return $answer_field;
}
}
//// END OF CLASS ////

View File

@ -334,13 +334,15 @@ class question_truefalse_qtype extends default_questiontype {
}
function restore_recode_answer($state, $restore) {
$answer = backup_getid($restore->backup_unique_code,"question_answers",$state->answer);
if ($answer) {
return $answer->new_id;
} else {
echo 'Could not recode truefalse answer id '.$state->answer.' for state '.$state->oldid.'<br />';
//answer may be empty
if ($state->answer) {
$answer = backup_getid($restore->backup_unique_code,"question_answers",$state->answer);
if ($answer) {
return $answer->new_id;
} else {
echo 'Could not recode truefalse answer id '.$state->answer.' for state '.$state->oldid.'<br />';
}
}
return '';
}
}