]> git.mjollnir.org Git - moodle.git/commitdiff
Fixed multichoice restore
authorgustav_delius <gustav_delius>
Sun, 19 Mar 2006 09:20:42 +0000 (09:20 +0000)
committergustav_delius <gustav_delius>
Sun, 19 Mar 2006 09:20:42 +0000 (09:20 +0000)
Print message when recoding fails

question/questiontypes/multichoice/questiontype.php
question/restorelib.php

index 5f14db95a1e92c7c2d056a3fc63512aa5a720d11..7f3ca8708b1d8b9c7f99c952fa8eab9d44fd0714 100644 (file)
@@ -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;
         }
 
index 6862779a1fb0d4bcf9f100a971e92d56abf1712c..d9e7bd62ab797ae2ff0ceb4a2a500f5ffd66d7de 100644 (file)
             if (!defined('RESTORE_SILENTLY')) {
                 echo '</li>';
             }
+        } else {
+            echo 'Could not get backup info for question category'. $category->id;
         }
 
         return $status;
                 $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;
             ////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.'<br />';
+                }
             }
 
             //Check if the question exists
                 $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.'<br />';
                 }
             }
 
             $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.'<br />';
             }
 
-            //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.'<br />';
+                }
             }
 
             //We have to recode the answer field
             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.'<br />';
+                    }
+                    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.'<br />';
                             }
-                            //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.'<br />';
                             }
-                            //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.'<br />';
+                    }
+                    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.'<br />';
+                        }
+                        //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.'<br />';
                         }
-                        $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.'<br />';
+                        }
+                        //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.'<br />';
+                        }
+                        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.'<br />';
+                            }
+                            $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
             $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.'<br />';
             }
 
             //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.'<br />';
             }
 
-            //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.'<br />';
+                }
             }
 
             //The structure is equal to the db, so insert the question_sessions