From: gustav_delius Date: Sun, 19 Mar 2006 09:20:42 +0000 (+0000) Subject: Fixed multichoice restore X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=28b904c8c2bef4a42061270aeab12423434f493d;p=moodle.git Fixed multichoice restore Print message when recoding fails --- diff --git a/question/questiontypes/multichoice/questiontype.php b/question/questiontypes/multichoice/questiontype.php index 5f14db95a1..7f3ca8708b 100644 --- a/question/questiontypes/multichoice/questiontype.php +++ b/question/questiontypes/multichoice/questiontype.php @@ -22,12 +22,12 @@ class question_multichoice_qtype extends quiz_default_questiontype { // and attach it to the question object if (!$question->options = get_record('question_multichoice', 'question', $question->id)) { - notify('Error: Missing question options!'); + notify('Error: Missing question options for multichoice question'.$question->id.'!'); return false; } if (!$question->options->answers = get_records_select('question_answers', 'id IN ('.$question->options->answers.')')) { - notify('Error: Missing question answers!'); + notify('Error: Missing question answers for multichoice question'.$question->id.'!'); return false; } diff --git a/question/restorelib.php b/question/restorelib.php index 6862779a1f..d9e7bd62ab 100644 --- a/question/restorelib.php +++ b/question/restorelib.php @@ -150,6 +150,8 @@ if (!defined('RESTORE_SILENTLY')) { echo ''; } + } else { + echo 'Could not get backup info for question category'. $category->id; } return $status; @@ -170,7 +172,7 @@ $restorefn = 'question_'.$qtype->name().'_restore'; if (function_exists($restorefn)) { $restorefns[$key] = $restorefn; - }else {echo $restorefn;} + } $restoremapfn = 'question_'.$qtype->name().'_restore_map'; if (function_exists($restoremapfn)) { $restoremapfns[$key] = $restoremapfn; @@ -215,8 +217,12 @@ ////We have to recode the parent field // This should work alright because we ordered the questions appropriately during backup so that // questions that can be parents are restored first - if ($question->parent and $parent = backup_getid($restore->backup_unique_code,"question",$question->parent)) { - $question->parent = $parent->new_id; + if ($question->parent) { + if ($parent = backup_getid($restore->backup_unique_code,"question",$question->parent)) { + $question->parent = $parent->new_id; + } else { + echo 'Could not recode parent '.$question->parent.' for question '.$question->id.'
'; + } } //Check if the question exists @@ -468,6 +474,8 @@ $category = backup_getid($restore->backup_unique_code,"question_categories",$dataset_definition->category); if ($category) { $dataset_definition->category = $category->new_id; + } else { + echo 'Could not recode category id '.$dataset_definition->category.' for dataset definition'.$dataset_definition->name.'
'; } } @@ -595,12 +603,18 @@ $question = backup_getid($restore->backup_unique_code,"question",$state->question); if ($question) { $state->question = $question->new_id; + } else { + echo 'Could not recode question id '.$state->question.' for state '.$oldid.'
'; } - //We have to recode the originalquestion field - $question = backup_getid($restore->backup_unique_code,"question",$state->originalquestion); - if ($question) { - $state->originalquestion = $question->new_id; + //We have to recode the originalquestion field if it is nonzero + if ($state->originalquestion) { + $question = backup_getid($restore->backup_unique_code,"question",$state->originalquestion); + if ($question) { + $state->originalquestion = $question->new_id; + } else { + echo 'Could not recode originalquestion id '.$state->question.' for state '.$oldid.'
'; + } } //We have to recode the answer field @@ -609,166 +623,190 @@ if (!$question = get_record("question","id",$state->question)) { error("Can't find the record for question $state->question for which I am trying to restore a state"); } - //It exists - if ($question) { - //Depending on the qtype, we make different recodes - switch ($question->qtype) { - case 1: //SHORTANSWER QTYPE - //Nothing to do. The response is a text. - break; - case 2: //TRUEFALSE QTYPE - //The answer is one answer id. We must recode it - $answer = backup_getid($restore->backup_unique_code,"question_answers",$state->answer); - if ($answer) { - $state->answer = $answer->new_id; + //Depending on the qtype, we make different recodes + switch ($question->qtype) { + case 1: //SHORTANSWER QTYPE + //Nothing to do. The response is a text. + break; + case 2: //TRUEFALSE QTYPE + //The answer is one answer id. We must recode it + $answer = backup_getid($restore->backup_unique_code,"question_answers",$state->answer); + if ($answer) { + $state->answer = $answer->new_id; + } else { + echo 'Could not recode truefalse answer id '.$state->answer.' for state '.$oldid.'
'; + } + break; + case 3: //MULTICHOICE QTYPE + $pos = strpos($state->answer, ':'); + $order = array(); + $responses = array(); + if (false === $pos) { // No order of answers is given, so use the default + if ($state->answer) { + $responses = explode(',', $state->answer); + } + } else { + $order = explode(',', substr($state->answer, 0, $pos)); + if ($responsestring = substr($state->answer, $pos + 1)) { + $responses = explode(',', $responsestring); } - break; - case 3: //MULTICHOICE QTYPE - //The answer is a comma separated list of answers. We must recode them - $answer_field = ""; - $in_first = true; - $tok = strtok($state->answer,","); - while ($tok) { - //Get the answer from backup_ids - $answer = backup_getid($restore->backup_unique_code,"question_answers",$tok); + } + if ($order) { + foreach ($order as $key => $oldansid) { + $answer = backup_getid($restore->backup_unique_code,"question_answers",$oldansid); if ($answer) { - if ($in_first) { - $answer_field .= $answer->new_id; - $in_first = false; - } else { - $answer_field .= ",".$answer->new_id; - } + $order[$key] = $answer->new_id; + } else { + echo 'Could not recode multichoice answer id '.$oldansid.' for state '.$oldid.'
'; } - //check for next - $tok = strtok(","); } - $state->answer = $answer_field; - break; - case 4: //RANDOM QTYPE - //The answer links to another question id, we must recode it - $answer_link = backup_getid($restore->backup_unique_code,"question",$state->answer); - if ($answer_link) { - $state->answer = $answer_link->new_id; - } - break; - case 5: //MATCH QTYPE - //The answer is a comma separated list of hypen separated math_subs (for question and answer) - $answer_field = ""; - $in_first = true; - $tok = strtok($state->answer,","); - while ($tok) { - //Extract the match_sub for the question and the answer - $exploded = explode("-",$tok); - $match_question_id = $exploded[0]; - $match_answer_id = $exploded[1]; - //Get the match_sub from backup_ids (for the question) - $match_que = backup_getid($restore->backup_unique_code,"question_match_sub",$match_question_id); - //Get the match_sub from backup_ids (for the answer) - $match_ans = backup_getid($restore->backup_unique_code,"question_match_sub",$match_answer_id); - if ($match_que) { - //It 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; - } + } + if ($responses) { + foreach ($responses as $key => $oldansid) { + $answer = backup_getid($restore->backup_unique_code,"question_answers",$oldansid); + if ($answer) { + $responses[$key] = $answer->new_id; + } else { + echo 'Could not recode multichoice response answer id '.$oldansid.' for state '.$oldid.'
'; } - //check for next - $tok = strtok(","); } - $state->answer = $answer_field; - break; - case 6: //RANDOMSAMATCH QTYPE - //The answer is a comma separated list of hypen separated question_id and answer_id. We must recode them - $answer_field = ""; - $in_first = true; - $tok = strtok($state->answer,","); - while ($tok) { - //Extract the question_id and the answer_id - $exploded = explode("-",$tok); - $question_id = $exploded[0]; - $answer_id = $exploded[1]; - //Get the question from backup_ids - $que = backup_getid($restore->backup_unique_code,"question",$question_id); - //Get the answer from backup_ids - $ans = backup_getid($restore->backup_unique_code,"question_answers",$answer_id); - if ($que) { - //It the question hasn't response, it must be 0 - if (!$ans and $answer_id == 0) { - $ans->new_id = 0; - } - if ($in_first) { - $answer_field .= $que->new_id."-".$ans->new_id; - $in_first = false; - } else { - $answer_field .= ",".$que->new_id."-".$ans->new_id; - } - } - //check for next - $tok = strtok(","); + } + $state->answer = implode(',', $order).':'.implode(',', $responses); + break; + case 4: //RANDOM QTYPE + //The answer links to another question id, we must recode it + $answer_link = backup_getid($restore->backup_unique_code,"question",$state->answer); + if ($answer_link) { + $state->answer = $answer_link->new_id; + } else { + echo 'Could not recode random question link '.$state->answer.' for state '.$oldid.'
'; + } + break; + case 5: //MATCH QTYPE + //The answer is a comma separated list of hypen separated math_subs (for question and answer) + $answer_field = ""; + $in_first = true; + $tok = strtok($state->answer,","); + while ($tok) { + //Extract the match_sub for the question and the answer + $exploded = explode("-",$tok); + $match_question_id = $exploded[0]; + $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.'
'; + } + //Get the match_sub from backup_ids (for the answer) + if (!$match_ans = backup_getid($restore->backup_unique_code,"question_match_sub",$match_answer_id)) { + echo 'Could not recode question_match_sub '.$match_answer_id.'
'; } - $state->answer = $answer_field; - break; - case 7: //DESCRIPTION QTYPE - //Nothing to do (there is no awser to this qtype) - //But this case must exist !! - break; - case 8: //NUMERICAL QTYPE - //Nothing to do. The response is a text. - break; - case 9: //MULTIANSWER QTYPE - //The answer is a comma separated list of hypen separated sequence number and answers. We may have to recode the answers - $answer_field = ""; - $in_first = true; - $tok = strtok($state->answer,","); - while ($tok) { - //Extract the multianswer_id and the answer - $exploded = explode("-",$tok); - $seqnum = $exploded[0]; - $answer = $exploded[1]; - // $sequence is an ordered array of the question ids. - if (!$sequence = get_field('question_multianswer', 'sequence', 'question', $question->id)) { - error("The cloze question $question->id is missing its options"); + if ($match_que) { + //It the question hasn't response, it must be 0 + if (!$match_ans and $match_answer_id == 0) { + $match_ans->new_id = 0; } - $sequence = explode(',', $sequence); - // The id of the current question. - $wrappedquestionid = $sequence[$seqnum-1]; - // now we can find the question - if (!$wrappedquestion = get_record('question', 'id', $wrappedquestionid)) { - error("Can't find the subquestion $wrappedquestionid that is used as part $seqnum in cloze question $question->id"); + 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; } - // For multichoice question we need to recode the answer - if ($wrappedquestion->qtype == MULTICHOICE) { - //The answer is an answer_id, look for it in backup_ids - $ans = backup_getid($restore->backup_unique_code,"question_answers",$answer); - $answer = $ans->new_id; + } + //check for next + $tok = strtok(","); + } + $state->answer = $answer_field; + break; + case 6: //RANDOMSAMATCH QTYPE + //The answer is a comma separated list of hypen separated question_id and answer_id. We must recode them + $answer_field = ""; + $in_first = true; + $tok = strtok($state->answer,","); + while ($tok) { + //Extract the question_id and the answer_id + $exploded = explode("-",$tok); + $question_id = $exploded[0]; + $answer_id = $exploded[1]; + //Get the question from backup_ids + if (!$que = backup_getid($restore->backup_unique_code,"question",$question_id)) { + echo 'Could not recode randomsamatch question '.$question_id.'
'; + } + //Get the answer from backup_ids + if (!$ans = backup_getid($restore->backup_unique_code,"question_answers",$answer_id)) { + echo 'Could not recode randomsamatch answer '.$answer_id.'
'; + } + if ($que) { + //It the question hasn't response, it must be 0 + if (!$ans and $answer_id == 0) { + $ans->new_id = 0; } - //build the new answer field for each pair if ($in_first) { - $answer_field .= $seqnum."-".$answer; + $answer_field .= $que->new_id."-".$ans->new_id; $in_first = false; } else { - $answer_field .= ",".$seqnum."-".$answer; + $answer_field .= ",".$que->new_id."-".$ans->new_id; } - //check for next - $tok = strtok(","); } - $state->answer = $answer_field; - break; - case 10: //CALCULATED QTYPE - //Nothing to do. The response is a text. - break; - default: //UNMATCHED QTYPE. - //This is an error (unimplemented qtype) - $status = false; - break; - } - } else { - $status = false; + //check for next + $tok = strtok(","); + } + $state->answer = $answer_field; + break; + case 7: //DESCRIPTION QTYPE + //Nothing to do (there is no awser to this qtype) + //But this case must exist !! + break; + case 8: //NUMERICAL QTYPE + //Nothing to do. The response is a text. + break; + case 9: //MULTIANSWER QTYPE + //The answer is a comma separated list of hypen separated sequence number and answers. We may have to recode the answers + $answer_field = ""; + $in_first = true; + $tok = strtok($state->answer,","); + while ($tok) { + //Extract the multianswer_id and the answer + $exploded = explode("-",$tok); + $seqnum = $exploded[0]; + $answer = $exploded[1]; + // $sequence is an ordered array of the question ids. + if (!$sequence = get_field('question_multianswer', 'sequence', 'question', $question->id)) { + error("The cloze question $question->id is missing its options"); + } + $sequence = explode(',', $sequence); + // The id of the current question. + $wrappedquestionid = $sequence[$seqnum-1]; + // now we can find the question + if (!$wrappedquestion = get_record('question', 'id', $wrappedquestionid)) { + error("Can't find the subquestion $wrappedquestionid that is used as part $seqnum in cloze question $question->id"); + } + // For multichoice question we need to recode the answer + if ($wrappedquestion->qtype == MULTICHOICE) { + //The answer is an answer_id, look for it in backup_ids + if (!$ans = backup_getid($restore->backup_unique_code,"question_answers",$answer)) { + echo 'Could not recode cloze multichoice answer '.$answer.'
'; + } + $answer = $ans->new_id; + } + //build the new answer field for each pair + if ($in_first) { + $answer_field .= $seqnum."-".$answer; + $in_first = false; + } else { + $answer_field .= ",".$seqnum."-".$answer; + } + //check for next + $tok = strtok(","); + } + $state->answer = $answer_field; + break; + case 10: //CALCULATED QTYPE + //Nothing to do. The response is a text. + break; + default: //UNMATCHED QTYPE. + //This is an error (unimplemented qtype) + $status = false; + break; } //The structure is equal to the db, so insert the question_states @@ -829,18 +867,26 @@ $question = backup_getid($restore->backup_unique_code,"question",$session->questionid); if ($question) { $session->questionid = $question->new_id; + } else { + echo 'Could not recode question id '.$session->questionid.'
'; } //We have to recode the newest field $state = backup_getid($restore->backup_unique_code,"question_states",$session->newest); if ($state) { $session->newest = $state->new_id; + } else { + echo 'Could not recode newest state id '.$session->newest.'
'; } - //We have to recode the newgraded field - $state = backup_getid($restore->backup_unique_code,"question_states",$session->newgraded); - if ($state) { - $session->newgraded = $state->new_id; + //If the session has been graded we have to recode the newgraded field + if ($session->newgraded) { + $state = backup_getid($restore->backup_unique_code,"question_states",$session->newgraded); + if ($state) { + $session->newgraded = $state->new_id; + } else { + echo 'Could not recode newest graded state id '.$session->newgraded.'
'; + } } //The structure is equal to the db, so insert the question_sessions