]> git.mjollnir.org Git - moodle.git/commitdiff
Moving question restore code into questiontype classes. The restore is now temporaril...
authorgustav_delius <gustav_delius>
Tue, 21 Mar 2006 20:59:32 +0000 (20:59 +0000)
committergustav_delius <gustav_delius>
Tue, 21 Mar 2006 20:59:32 +0000 (20:59 +0000)
12 files changed:
question/questiontypes/calculated/questiontype.php
question/questiontypes/essay/questiontype.php
question/questiontypes/match/questiontype.php
question/questiontypes/multianswer/questiontype.php
question/questiontypes/multichoice/questiontype.php
question/questiontypes/numerical/questiontype.php
question/questiontypes/questiontype.php
question/questiontypes/randomsamatch/questiontype.php
question/questiontypes/rqp/questiontype.php
question/questiontypes/shortanswer/questiontype.php
question/questiontypes/truefalse/questiontype.php
question/restorelib.php

index 50cd73e695cecaede20edb338fb9603f724e6fcb..884d7bc7427bfd9267e151724a10a65f5e238359 100644 (file)
@@ -633,6 +633,71 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype
         }
         return $status;
     }
+
+/// RESTORE FUNCTIONS /////////////////
+
+    /*
+     * Restores the data in the question
+     *
+     * This is used in question/restorelib.php
+     */
+    function restore($old_question_id,$new_question_id,$info,$restore) {
+
+        $status = true;
+
+        //Get the calculated-s array
+        $calculateds = $info['#']['CALCULATED'];
+
+        //Iterate over calculateds
+        for($i = 0; $i < sizeof($calculateds); $i++) {
+            $cal_info = $calculateds[$i];
+            //traverse_xmlize($cal_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //Now, build the question_calculated record structure
+            $calculated->question = $new_question_id;
+            $calculated->answer = backup_todb($cal_info['#']['ANSWER']['0']['#']);
+            $calculated->tolerance = backup_todb($cal_info['#']['TOLERANCE']['0']['#']);
+            $calculated->tolerancetype = backup_todb($cal_info['#']['TOLERANCETYPE']['0']['#']);
+            $calculated->correctanswerlength = backup_todb($cal_info['#']['CORRECTANSWERLENGTH']['0']['#']);
+            $calculated->correctanswerformat = backup_todb($cal_info['#']['CORRECTANSWERFORMAT']['0']['#']);
+
+            ////We have to recode the answer field
+            $answer = backup_getid($restore->backup_unique_code,"question_answers",$calculated->answer);
+            if ($answer) {
+                $calculated->answer = $answer->new_id;
+            }
+
+            //The structure is equal to the db, so insert the question_calculated
+            $newid = insert_record ("question_calculated",$calculated);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo ".";
+                    if (($i+1) % 1000 == 0) {
+                        echo "<br />";
+                    }
+                }
+                backup_flush(300);
+            }
+
+            //Now restore numerical_units
+            $status = question_restore_numerical_units ($old_question_id,$new_question_id,$cal_info,$restore);
+
+            //Now restore dataset_definitions
+            if ($status && $newid) {
+                $status = question_restore_dataset_definitions ($old_question_id,$new_question_id,$cal_info,$restore);
+            }
+
+            if (!$newid) {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
 }
 //// END OF CLASS ////
 
index 03bbe2c02cd745a923ec1ac94090d3d7901c400f..dc0d6d3f2ab4086fb9ba347d4a08f6c296b95aaa 100644 (file)
@@ -335,6 +335,77 @@ class question_essay_qtype extends default_questiontype {
         return $status;
     }
 
+/// RESTORE FUNCTIONS /////////////////
+
+    /*
+     * Restores the data in the question
+     *
+     * This is used in question/restorelib.php
+     */
+    function restore($old_question_id,$new_question_id,$info,$restore) {
+
+        $status = true;
+
+        //Get the truefalse array
+        $essays = $info['#']['ESSAY'];
+
+        //Iterate over truefalse
+        for($i = 0; $i < sizeof($essays); $i++) {
+            $essay_info = $essays[$i];
+
+            //Now, build the question_essay record structure
+            $essay->question = $new_question_id;
+            $essay->answer = backup_todb($essay_info['#']['ANSWER']['0']['#']);
+
+            ////We have to recode the answer field
+            $answer = backup_getid($restore->backup_unique_code,"question_answers",$essay->answer);
+            if ($answer) {
+                $essay->answer = $answer->new_id;
+            }
+
+            //The structure is equal to the db, so insert the question_essay
+            $newid = insert_record ("question_essay",$essay);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                echo ".";
+                if (($i+1) % 1000 == 0) {
+                    echo "<br />";
+                }
+                backup_flush(300);
+            }
+
+            if (!$newid) {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+
+    //This function restores the question_essay_states
+    function restore_state($state_id,$info,$restore) {
+
+        $status = true;
+
+        //Get the question_essay_state
+        $essay_state = $info['#']['ESSAY_STATE']['0'];
+        if ($essay_state) {
+
+            //Now, build the ESSAY_STATES record structure
+            $state->stateid = $state_id;
+            $state->graded = backup_todb($essay_state['#']['GRADED']['0']['#']);
+            $state->fraction = backup_todb($essay_state['#']['FRACTION']['0']['#']);
+            $state->response = backup_todb($essay_state['#']['RESPONSE']['0']['#']);
+
+            //The structure is equal to the db, so insert the question_states
+            $newid = insert_record ("question_essay_states",$state);
+        }
+
+        return $status;
+    }
+
 }
 //// END OF CLASS ////
 
index c27c122df20ab970f0c2512509ab16a6c990b4a4..5035ba92ddaaf8687e1339261f386d79b316c463 100644 (file)
@@ -365,6 +365,167 @@ class question_match_qtype extends default_questiontype {
         return $status;
     }
 
+/// RESTORE FUNCTIONS /////////////////
+
+    /*
+     * Restores the data in the question
+     *
+     * This is used in question/restorelib.php
+     */
+    function restore($old_question_id,$new_question_id,$info,$restore) {
+
+        $status = true;
+
+        //Get the matchs array
+        $matchs = $info['#']['MATCHS']['0']['#']['MATCH'];
+
+        //We have to build the subquestions field (a list of match_sub id)
+        $subquestions_field = "";
+        $in_first = true;
+
+        //Iterate over matchs
+        for($i = 0; $i < sizeof($matchs); $i++) {
+            $mat_info = $matchs[$i];
+
+            //We'll need this later!!
+            $oldid = backup_todb($mat_info['#']['ID']['0']['#']);
+
+            //Now, build the question_match_SUB record structure
+            $match_sub->question = $new_question_id;
+            $match_sub->code = backup_todb($mat_info['#']['CODE']['0']['#']);
+            if (!$match_sub->code) {
+                $match_sub->code = $oldid;
+            }
+            $match_sub->questiontext = backup_todb($mat_info['#']['QUESTIONTEXT']['0']['#']);
+            $match_sub->answertext = backup_todb($mat_info['#']['ANSWERTEXT']['0']['#']);
+
+            //The structure is equal to the db, so insert the question_match_sub
+            $newid = insert_record ("question_match_sub",$match_sub);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo ".";
+                    if (($i+1) % 1000 == 0) {
+                        echo "<br />";
+                    }
+                }
+                backup_flush(300);
+            }
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"question_match_sub",$oldid,
+                             $newid);
+                //We have a new match_sub, append it to subquestions_field
+                if ($in_first) {
+                    $subquestions_field .= $newid;
+                    $in_first = false;
+                } else {
+                    $subquestions_field .= ",".$newid;
+                }
+            } else {
+                $status = false;
+            }
+        }
+
+        //We have created every match_sub, now create the match
+        $match->question = $new_question_id;
+        $match->subquestions = $subquestions_field;
+
+        //The structure is equal to the db, so insert the question_match_sub
+        $newid = insert_record ("question_match",$match);
+
+        if (!$newid) {
+            $status = false;
+        }
+
+        return $status;
+    }
+
+    function restore_map($old_question_id,$new_question_id,$info,$restore) {
+
+        $status = true;
+
+        //Get the matchs array
+        $matchs = $info['#']['MATCHS']['0']['#']['MATCH'];
+
+        //We have to build the subquestions field (a list of match_sub id)
+        $subquestions_field = "";
+        $in_first = true;
+
+        //Iterate over matchs
+        for($i = 0; $i < sizeof($matchs); $i++) {
+            $mat_info = $matchs[$i];
+
+            //We'll need this later!!
+            $oldid = backup_todb($mat_info['#']['ID']['0']['#']);
+
+            //Now, build the question_match_SUB record structure
+            $match_sub->question = $new_question_id;
+            $match_sub->questiontext = backup_todb($mat_info['#']['QUESTIONTEXT']['0']['#']);
+            $match_sub->answertext = backup_todb($mat_info['#']['ANSWERTEXT']['0']['#']);
+
+            //If we are in this method is because the question exists in DB, so its
+            //match_sub must exist too.
+            //Now, we are going to look for that match_sub in DB and to create the
+            //mappings in backup_ids to use them later where restoring states (user level).
+
+            //Get the match_sub from DB (by question, questiontext and answertext)
+            $db_match_sub = get_record ("question_match_sub","question",$new_question_id,
+                                                      "questiontext",$match_sub->questiontext,
+                                                      "answertext",$match_sub->answertext);
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo ".";
+                    if (($i+1) % 1000 == 0) {
+                        echo "<br />";
+                    }
+                }
+                backup_flush(300);
+            }
+
+            //We have the database match_sub, so update backup_ids
+            if ($db_match_sub) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"question_match_sub",$oldid,
+                             $db_match_sub->id);
+            } else {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+    function restore_recode_answer($state, $restore) {
+
+        //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_code = $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 />';
+            }
+            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;
+            }
+            //check for next
+            $tok = strtok(",");
+        }
+        return $answer_field;
+    }
+
 }
 //// END OF CLASS ////
 
index a29a2b1f2e7b7ac49848f2db523c96f96e7c684e..f0fd55ea17c49861e6856f4ae1d8d6e4e46d7160 100644 (file)
@@ -412,6 +412,185 @@ class quiz_embedded_cloze_qtype extends default_questiontype {
         return $status;
     }
 
+/// RESTORE FUNCTIONS /////////////////
+
+    /*
+     * Restores the data in the question
+     *
+     * This is used in question/restorelib.php
+     */
+    function restore($old_question_id,$new_question_id,$info,$restore) {
+
+        $status = true;
+
+        //Get the multianswers array
+        $multianswers = $info['#']['MULTIANSWERS']['0']['#']['MULTIANSWER'];
+        //Iterate over multianswers
+        for($i = 0; $i < sizeof($multianswers); $i++) {
+            $mul_info = $multianswers[$i];
+
+            //We need this later
+            $oldid = backup_todb($mul_info['#']['ID']['0']['#']);
+
+            //Now, build the question_multianswer record structure
+            $multianswer->question = $new_question_id;
+            $multianswer->sequence = backup_todb($mul_info['#']['SEQUENCE']['0']['#']);
+
+            //We have to recode the sequence field (a list of question ids)
+            //Extracts question id from sequence
+            $sequence_field = "";
+            $in_first = true;
+            $tok = strtok($multianswer->sequence,",");
+            while ($tok) {
+                //Get the answer from backup_ids
+                $question = backup_getid($restore->backup_unique_code,"question",$tok);
+                if ($question) {
+                    if ($in_first) {
+                        $sequence_field .= $question->new_id;
+                        $in_first = false;
+                    } else {
+                        $sequence_field .= ",".$question->new_id;
+                    }
+                }
+                //check for next
+                $tok = strtok(",");
+            }
+            //We have the answers field recoded to its new ids
+            $multianswer->sequence = $sequence_field;
+            //The structure is equal to the db, so insert the question_multianswer
+            $newid = insert_record ("question_multianswer",$multianswer);
+
+            //Save ids in backup_ids
+            if ($newid) {
+                backup_putid($restore->backup_unique_code,"question_multianswer",
+                             $oldid, $newid);
+            }
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo ".";
+                    if (($i+1) % 1000 == 0) {
+                        echo "<br />";
+                    }
+                }
+                backup_flush(300);
+            }
+/*
+            //If we have created the question_multianswer record, now, depending of the
+            //answertype, delegate the restore to every qtype function
+            if ($newid) {
+                if ($multianswer->answertype == "1") {
+                    $status = quiz_restore_shortanswer ($old_question_id,$new_question_id,$mul_info,$restore);
+                } else if ($multianswer->answertype == "3") {
+                    $status = quiz_restore_multichoice ($old_question_id,$new_question_id,$mul_info,$restore);
+                } else if ($multianswer->answertype == "8") {
+                    $status = quiz_restore_numerical ($old_question_id,$new_question_id,$mul_info,$restore);
+                }
+            } else {
+                $status = false;
+            }
+*/
+        }
+
+        return $status;
+    }
+
+    function restore_map($old_question_id,$new_question_id,$info,$restore) {
+
+        $status = true;
+
+        //Get the multianswers array
+        $multianswers = $info['#']['MULTIANSWERS']['0']['#']['MULTIANSWER'];
+        //Iterate over multianswers
+        for($i = 0; $i < sizeof($multianswers); $i++) {
+            $mul_info = $multianswers[$i];
+
+            //We need this later
+            $oldid = backup_todb($mul_info['#']['ID']['0']['#']);
+
+            //Now, build the question_multianswer record structure
+            $multianswer->question = $new_question_id;
+            $multianswer->answers = backup_todb($mul_info['#']['ANSWERS']['0']['#']);
+            $multianswer->positionkey = backup_todb($mul_info['#']['POSITIONKEY']['0']['#']);
+            $multianswer->answertype = backup_todb($mul_info['#']['ANSWERTYPE']['0']['#']);
+            $multianswer->norm = backup_todb($mul_info['#']['NORM']['0']['#']);
+
+            //If we are in this method is because the question exists in DB, so its
+            //multianswer must exist too.
+            //Now, we are going to look for that multianswer in DB and to create the
+            //mappings in backup_ids to use them later where restoring states (user level).
+
+            //Get the multianswer from DB (by question and positionkey)
+            $db_multianswer = get_record ("question_multianswer","question",$new_question_id,
+                                                      "positionkey",$multianswer->positionkey);
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo ".";
+                    if (($i+1) % 1000 == 0) {
+                        echo "<br />";
+                    }
+                }
+                backup_flush(300);
+            }
+
+            //We have the database multianswer, so update backup_ids
+            if ($db_multianswer) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"question_multianswer",$oldid,
+                             $db_multianswer->id);
+            } else {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+    function restore_recode_answer($state, $restore) {
+        //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', $state->question)) {
+                error("The cloze question $state->question 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 $state->question");
+            }
+            // For multichoice question we need to recode the answer
+            if ($answer and $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(",");
+        }
+        return $answer_field;
+    }
+
+
 }
 //// END OF CLASS ////
 
index a7602f8fecd57f63dd44290c935b39edd0c92ba3..b63a97b484336983ebdba8afbca9dd3e0bc7b68a 100644 (file)
@@ -402,6 +402,112 @@ class question_multichoice_qtype extends default_questiontype {
         return $status;
     }
 
+/// RESTORE FUNCTIONS /////////////////
+
+    /*
+     * Restores the data in the question
+     *
+     * This is used in question/restorelib.php
+     */
+    function restore($old_question_id,$new_question_id,$info,$restore) {
+
+        $status = true;
+
+        //Get the multichoices array
+        $multichoices = $info['#']['MULTICHOICE'];
+
+        //Iterate over multichoices
+        for($i = 0; $i < sizeof($multichoices); $i++) {
+            $mul_info = $multichoices[$i];
+
+            //Now, build the question_multichoice record structure
+            $multichoice->question = $new_question_id;
+            $multichoice->layout = backup_todb($mul_info['#']['LAYOUT']['0']['#']);
+            $multichoice->answers = backup_todb($mul_info['#']['ANSWERS']['0']['#']);
+            $multichoice->single = backup_todb($mul_info['#']['SINGLE']['0']['#']);
+            $multichoice->shuffleanswers = backup_todb($mul_info['#']['SHUFFLEANSWERS']['0']['#']);
+
+            //We have to recode the answers field (a list of answers id)
+            //Extracts answer id from sequence
+            $answers_field = "";
+            $in_first = true;
+            $tok = strtok($multichoice->answers,",");
+            while ($tok) {
+                //Get the answer from backup_ids
+                $answer = backup_getid($restore->backup_unique_code,"question_answers",$tok);
+                if ($answer) {
+                    if ($in_first) {
+                        $answers_field .= $answer->new_id;
+                        $in_first = false;
+                    } else {
+                        $answers_field .= ",".$answer->new_id;
+                    }
+                }
+                //check for next
+                $tok = strtok(",");
+            }
+            //We have the answers field recoded to its new ids
+            $multichoice->answers = $answers_field;
+
+            //The structure is equal to the db, so insert the question_shortanswer
+            $newid = insert_record ("question_multichoice",$multichoice);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo ".";
+                    if (($i+1) % 1000 == 0) {
+                        echo "<br />";
+                    }
+                }
+                backup_flush(300);
+            }
+
+            if (!$newid) {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+    function restore_recode_answer($state, $restore) {
+        $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);
+            }
+        }
+        if ($order) {
+            foreach ($order as $key => $oldansid) {
+                $answer = backup_getid($restore->backup_unique_code,"question_answers",$oldansid);
+                if ($answer) {
+                    $order[$key] = $answer->new_id;
+                } else {
+                    echo 'Could not recode multichoice answer id '.$oldansid.' for state '.$oldid.'<br />';
+                }
+            }
+        }
+        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 />';
+                }
+            }
+        }
+        return implode(',', $order).':'.implode(',', $responses);
+    }
+
 }
 //// END OF CLASS ////
 
index a8c3b620f768754d1ce1ef3025761859dda150db..6231c205c297ef2597e913707c2887d567ed51eb 100644 (file)
@@ -437,6 +437,60 @@ class question_numerical_qtype extends question_shortanswer_qtype {
         return $status;
     }
 
+/// RESTORE FUNCTIONS /////////////////
+
+    /*
+     * Restores the data in the question
+     *
+     * This is used in question/restorelib.php
+     */
+    function restore($old_question_id,$new_question_id,$info,$restore) {
+
+        $status = true;
+
+        //Get the numerical array
+        $numericals = $info['#']['NUMERICAL'];
+
+        //Iterate over numericals
+        for($i = 0; $i < sizeof($numericals); $i++) {
+            $num_info = $numericals[$i];
+
+            //Now, build the question_numerical record structure
+            $numerical->question = $new_question_id;
+            $numerical->answer = backup_todb($num_info['#']['ANSWER']['0']['#']);
+            $numerical->tolerance = backup_todb($num_info['#']['TOLERANCE']['0']['#']);
+
+            ////We have to recode the answer field
+            $answer = backup_getid($restore->backup_unique_code,"question_answers",$numerical->answer);
+            if ($answer) {
+                $numerical->answer = $answer->new_id;
+            }
+
+            //The structure is equal to the db, so insert the question_numerical
+            $newid = insert_record ("question_numerical",$numerical);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo ".";
+                    if (($i+1) % 1000 == 0) {
+                        echo "<br />";
+                    }
+                }
+                backup_flush(300);
+            }
+
+            //Now restore numerical_units
+            $status = question_restore_numerical_units ($old_question_id,$new_question_id,$num_info,$restore);
+
+            if (!$newid) {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
 }
 //// END OF CLASS ////
 
index 1f9b1e922bcf239eedac86a0fe4a38a84b8256c0..44ed8ddaf941fbcd9a46eb764936147ff65df1ab 100644 (file)
@@ -955,6 +955,33 @@ class default_questiontype {
         return true;
     }
 
+/// RESTORE FUNCTIONS /////////////////
+
+    /*
+     * Restores the data in the question
+     *
+     * This is used in question/restorelib.php
+     */
+    function restore($old_question_id,$new_question_id,$info,$restore) {
+        // The default question type has nothing to restore
+        return true;
+    }
+
+    function restore_map($old_question_id,$new_question_id,$info,$restore) {
+        // There is nothing to decode
+        return true;
+    }
+
+    function restore_recode_answer($state, $restore) {
+        // There is nothing to decode
+        return true;
+    }    
+
+    //This function restores the question_rqp_states
+    function restore_state($state_id,$info,$restore) {
+        // The default question type does not keep its own state information
+        return true;
+    }
 
 }
 
index a888901a096e1da2ce45b415b9976d246dc5d1bc..25ee59fc40a147a6852e8953bef2cea624584100 100644 (file)
@@ -267,6 +267,88 @@ class question_randomsamatch_qtype extends question_match_qtype {
         }
         return $status;
     }
+
+/// RESTORE FUNCTIONS /////////////////
+
+    /*
+     * Restores the data in the question
+     *
+     * This is used in question/restorelib.php
+     */
+    function restore($old_question_id,$new_question_id,$info,$restore) {
+
+        $status = true;
+
+        //Get the randomsamatchs array
+        $randomsamatchs = $info['#']['RANDOMSAMATCH'];
+
+        //Iterate over randomsamatchs
+        for($i = 0; $i < sizeof($randomsamatchs); $i++) {
+            $ran_info = $randomsamatchs[$i];
+
+            //Now, build the question_randomsamatch record structure
+            $randomsamatch->question = $new_question_id;
+            $randomsamatch->choose = backup_todb($ran_info['#']['CHOOSE']['0']['#']);
+            $randomsamatch->shuffleanswers = backup_todb($ran_info['#']['SHUFFLEANSWERS']['0']['#']);
+
+            //The structure is equal to the db, so insert the question_randomsamatch
+            $newid = insert_record ("question_randomsamatch",$randomsamatch);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo ".";
+                    if (($i+1) % 1000 == 0) {
+                        echo "<br />";
+                    }
+                }
+                backup_flush(300);
+            }
+
+            if (!$newid) {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+    function restore_recode_answer($state, $restore) {
+
+        //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 />';
+            }
+            
+            if ($answer_id == 0) { // no response yet
+                $ans->new_id = 0;
+            } else {
+                //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 ($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(",");
+        }
+        return $answer_field;
+    }
+
 }
 
 //// END OF CLASS ////
index 3546e9e5a49f487fb2f1eb7a19ea7b4c4dcc0278..22135ee03eadfcc3cb1fdbacb4d0e1388ba2a5da 100644 (file)
@@ -426,7 +426,6 @@ class question_rqp_qtype extends default_questiontype {
     *                  be included on the quiz module admin page.
     */
     function get_config_options() {
-        global $CFG;
 
         // for the time being disable rqp unless we have php 5
         if(!check_php_version('5.0.0')) {
@@ -467,6 +466,78 @@ class question_rqp_qtype extends default_questiontype {
         return $status;
     }
 
+/// RESTORE FUNCTIONS /////////////////
+
+    /*
+     * Restores the data in the question
+     *
+     * This is used in question/restorelib.php
+     */
+    function restore($old_question_id,$new_question_id,$info,$restore) {
+
+        $status = true;
+
+        //Get the truefalse array
+        $rqps = $info['#']['RQP'];
+
+        //Iterate over rqp
+        for($i = 0; $i < sizeof($rqps); $i++) {
+            $tru_info = $rqps[$i];
+
+            //Now, build the question_rqp record structure
+            $rqp->question = $new_question_id;
+            $rqp->type = backup_todb($tru_info['#']['TYPE']['0']['#']);
+            $rqp->source = backup_todb($tru_info['#']['SOURCE']['0']['#']);
+            $rqp->format = backup_todb($tru_info['#']['FORMAT']['0']['#']);
+            $rqp->flags = backup_todb($tru_info['#']['FLAGS']['0']['#']);
+            $rqp->maxscore = backup_todb($tru_info['#']['MAXSCORE']['0']['#']);
+
+            //The structure is equal to the db, so insert the question_rqp
+            $newid = insert_record ("question_rqp",$rqp);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo ".";
+                    if (($i+1) % 1000 == 0) {
+                        echo "<br />";
+                    }
+                }
+                backup_flush(300);
+            }
+
+            if (!$newid) {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+
+    //This function restores the question_rqp_state
+    function restore_state($state_id,$info,$restore) {
+
+        $status = true;
+
+        //Get the question_rqp_state
+        $rqp_state = $info['#']['RQP_STATE']['0'];
+        if ($rqp_state) {
+
+            //Now, build the RQP_STATES record structure
+            $state->stateid = $state_id;
+            $state->responses = backup_todb($rqp_state['#']['RESPONSES']['0']['#']);
+            $state->persistent_data = backup_todb($rqp_state['#']['PERSISTENT_DATA']['0']['#']);
+            $state->template_vars = backup_todb($rqp_state['#']['TEMPLATE_VARS']['0']['#']);
+
+            //The structure is equal to the db, so insert the question_states
+            $newid = insert_record ("question_rqp_states",$state);
+        }
+
+        return $status;
+    }
+
+
 }
 //////////////////////////////////////////////////////////////////////////
 //// INITIATION - Without this line the question type is not in use... ///
index 1392702cd7466af5fa34052dc0c42539a4626be0..c6c8c866810acf2d334f90d5e957ed0a48398c86 100644 (file)
@@ -272,6 +272,73 @@ class question_shortanswer_qtype extends default_questiontype {
         return $status;
     }
 
+/// RESTORE FUNCTIONS /////////////////
+
+    /*
+     * Restores the data in the question
+     *
+     * This is used in question/restorelib.php
+     */
+    function restore($old_question_id,$new_question_id,$info,$restore) {
+
+        $status = true;
+
+        //Get the shortanswers array
+        $shortanswers = $info['#']['SHORTANSWER'];
+
+        //Iterate over shortanswers
+        for($i = 0; $i < sizeof($shortanswers); $i++) {
+            $sho_info = $shortanswers[$i];
+
+            //Now, build the question_shortanswer record structure
+            $shortanswer->question = $new_question_id;
+            $shortanswer->answers = backup_todb($sho_info['#']['ANSWERS']['0']['#']);
+            $shortanswer->usecase = backup_todb($sho_info['#']['USECASE']['0']['#']);
+
+            //We have to recode the answers field (a list of answers id)
+            //Extracts answer id from sequence
+            $answers_field = "";
+            $in_first = true;
+            $tok = strtok($shortanswer->answers,",");
+            while ($tok) {
+                //Get the answer from backup_ids
+                $answer = backup_getid($restore->backup_unique_code,"question_answers",$tok);
+                if ($answer) {
+                    if ($in_first) {
+                        $answers_field .= $answer->new_id;
+                        $in_first = false;
+                    } else {
+                        $answers_field .= ",".$answer->new_id;
+                    }
+                }
+                //check for next
+                $tok = strtok(",");
+            }
+            //We have the answers field recoded to its new ids
+            $shortanswer->answers = $answers_field;
+
+            //The structure is equal to the db, so insert the question_shortanswer
+            $newid = insert_record ("question_shortanswer",$shortanswer);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo ".";
+                    if (($i+1) % 1000 == 0) {
+                        echo "<br />";
+                    }
+                }
+                backup_flush(300);
+            }
+
+            if (!$newid) {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
 }
 //// END OF CLASS ////
 
index 7fd126e77b7c149b706433bae040b60d32776eac..32edb27d54e1c9f9bcfeb2dfd909f8f9864d2fd1 100644 (file)
@@ -239,6 +239,73 @@ class question_truefalse_qtype extends default_questiontype {
         return $status;
     }
 
+/// RESTORE FUNCTIONS /////////////////
+
+    /*
+     * Restores the data in the question
+     *
+     * This is used in question/restorelib.php
+     */
+    function restore($old_question_id,$new_question_id,$info,$restore) {
+
+        $status = true;
+
+        //Get the truefalse array
+        $truefalses = $info['#']['TRUEFALSE'];
+
+        //Iterate over truefalse
+        for($i = 0; $i < sizeof($truefalses); $i++) {
+            $tru_info = $truefalses[$i];
+
+            //Now, build the question_truefalse record structure
+            $truefalse->question = $new_question_id;
+            $truefalse->trueanswer = backup_todb($tru_info['#']['TRUEANSWER']['0']['#']);
+            $truefalse->falseanswer = backup_todb($tru_info['#']['FALSEANSWER']['0']['#']);
+
+            ////We have to recode the trueanswer field
+            $answer = backup_getid($restore->backup_unique_code,"question_answers",$truefalse->trueanswer);
+            if ($answer) {
+                $truefalse->trueanswer = $answer->new_id;
+            }
+
+            ////We have to recode the falseanswer field
+            $answer = backup_getid($restore->backup_unique_code,"question_answers",$truefalse->falseanswer);
+            if ($answer) {
+                $truefalse->falseanswer = $answer->new_id;
+            }
+
+            //The structure is equal to the db, so insert the question_truefalse
+            $newid = insert_record ("question_truefalse",$truefalse);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo ".";
+                    if (($i+1) % 1000 == 0) {
+                        echo "<br />";
+                    }
+                }
+                backup_flush(300);
+            }
+
+            if (!$newid) {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+    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 '.$oldid.'<br />';
+        }
+        return '';
+    }
+
 }
 //// END OF CLASS ////
 
index 82aee138d0496f95ed6d1da6007fa2e45fa37d8c..b4ec6893ba2ee0a394a29a42408902302e9eb908 100644 (file)
 
         global $CFG, $QTYPES;
 
-        // load questiontype-specific functions
-        unset($restorefns);
-        unset($restoremapfns);
-        unset($recodeansfns);
-        foreach ($QTYPES as $key => $qtype) {
-            $restorelib = $CFG->dirroot.'/question/questiontypes/'.$qtype->name().'/restorelib.php';
-            if (file_exists($restorelib)) {
-                include_once($restorelib);
-                $restorefn = 'question_'.$qtype->name().'_restore';
-                if (function_exists($restorefn)) {
-                    $restorefns[$key] = $restorefn;
-                }
-                $restoremapfn = 'question_'.$qtype->name().'_restore_map';
-                if (function_exists($restoremapfn)) {
-                    $restoremapfns[$key] = $restoremapfn;
-                }
-                $recodeansfn = 'question_'.$qtype->name().'_recode_answer';
-                if (function_exists($recodeansfn)) {
-                    $recodeansfns[$key] = $recodeansfn;
-                }
-            }
-        }
         $status = true;
         $restored_questions = array();
 
             if ($restored_questions[$i]->is_new) {
                 //Now, restore every question_answers in this question
                 $status = question_restore_answers($oldid,$newid,$que_info,$restore);
-                //Now, depending of the type of questions, invoke different functions
-                if (isset($restorefns[$question->qtype])) {
-                    $status = $restorefns[$question->qtype]($oldid,$newid,$que_info,$restore);
-                }
+                // Restore questiontype specific data
+                $status = $QTYPES[$question->qtype]->restore($oldid,$newid,$que_info,$restore);
             } else {
                 //We are NOT creating the question, but we need to know every question_answers
                 //map between the XML file and the database to be able to restore the states
                 //in each attempt.
                 $status = question_restore_map_answers($oldid,$newid,$que_info,$restore);
-                //Now, depending of the type of questions, invoke different functions
-                //to create the necessary mappings in backup_ids, because we are not
-                //creating the question, but need some records in backup table
-                if (isset($restoremapfns[$question->qtype])) {
-                    $status = $restoremapfns[$question->qtype]($oldid,$newid,$que_info,$restore);
-                }
+                // Do the questiontype specific mapping
+                $status = $QTYPE[$question->qtype]->restore_map($oldid,$newid,$que_info,$restore);
             }
 
             //Do some output
     //This function restores the question_states
     function question_states_restore_mods($attempt_id,$info,$restore) {
 
-        global $CFG, $restorestatefns;
+        global $CFG, $QTYPES;
 
         $status = true;
 
             }
             //Depending on the qtype, we make different recodes
             if ($state->answer) {
-                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);
-                            }
-                        }
-                        if ($order) {
-                            foreach ($order as $key => $oldansid) {
-                                $answer = backup_getid($restore->backup_unique_code,"question_answers",$oldansid);
-                                if ($answer) {
-                                    $order[$key] = $answer->new_id;
-                                } else {
-                                    echo 'Could not recode multichoice answer id '.$oldansid.' for state '.$oldid.'<br />';
-                                }
-                            }
-                        }
-                        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 />';
-                                }
-                            }
-                        }
-                        $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_code = $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 />';
-                            }
-                            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;
-                            }
-                            //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 />';
-                            }
-                            
-                            if ($answer_id == 0) { // no response yet
-                                $ans->new_id = 0;
-                            } else {
-                                //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 ($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 = $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 ($answer and $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;
-                }
+                $state->answer = $QTYPES[$question->qtype]->restore_recode_answer($state, $restore);
             }
 
             //The structure is equal to the db, so insert the question_states
                 backup_putid($restore->backup_unique_code,"question_states",$oldid,
                              $newid);
                 //Now process question type specific state information
-
-                if ($qtypes = get_list_of_plugins('question/questiontypes')) {
-                    foreach ($qtypes as $name) {
-                        $qtype->name = $name;
-                        $restorelib = $CFG->dirroot.'/question/questiontypes/'.$qtype->name.'/restorelib.php';
-                        if (file_exists($restorelib)) {
-                            include_once($restorelib);
-                            $restorestatefn = 'question_'.$qtype->name.'_states_restore';
-                            if (function_exists($restorestatefn)) {
-                                $restorestatefn($newid,$res_info,$restore);
-                            }
-                        }
-                    }
-                }
+                $qtype = get_field('question', 'qtype', 'id', $state->question);
+                $status = $QTYPES[$qtype]->restore_state($newid,$res_info,$restore);
             } else {
                 $status = false;
             }