⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 questiontype.php

📁 很棒的在线教学系统
💻 PHP
📖 第 1 页 / 共 3 页
字号:
                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);            }        }        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)) {                print_error('missingoption', 'question', '', $state->question);            }            $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)) {                notify("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;    }    /**     * Runs all the code required to set up and save an essay question for testing purposes.     * Alternate DB table prefix may be used to facilitate data deletion.     */    function generate_test($name, $courseid = null) {        list($form, $question) = parent::generate_test($name, $courseid);        $question->category = $form->category;        $form->questiontext = "This question consists of some text with an answer embedded right here {1:MULTICHOICE:Wrong answer#Feedback for this wrong answer~Another wrong answer#Feedback for the other wrong answer~=Correct answer#Feedback for correct answer~%50%Answer that gives half the credit#Feedback for half credit answer} and right after that you will have to deal with this short answer {1:SHORTANSWER:Wrong answer#Feedback for this wrong answer~=Correct answer#Feedback for correct answer~%50%Answer that gives half the credit#Feedback for half credit answer} and finally we have a floating point number {2:NUMERICAL:=23.8:0.1#Feedback for correct answer 23.8~%50%23.8:2#Feedback for half credit answer in the nearby region of the correct answer}.Note that addresses like www.moodle.org and smileys :-) all work as normal: a) How good is this? {:MULTICHOICE:=Yes#Correct~No#We have a different opinion} b) What grade would you give it? {3:NUMERICAL:=3:2}Good luck!";        $form->feedback = "feedback";        $form->generalfeedback = "General feedback";        $form->fraction = 0;        $form->penalty = 0.1;        $form->versioning = 0;        if ($courseid) {            $course = get_record('course', 'id', $courseid);        }        return $this->save_question($question, $form, $course);    }}//// END OF CLASS ////////////////////////////////////////////////////////////////////////////////// INITIATION - Without this line the question type is not in use... /////////////////////////////////////////////////////////////////////////////question_register_questiontype(new embedded_cloze_qtype());///////////////////////////////////////////////////////////////// ADDITIONAL FUNCTIONS//// The functions below deal exclusivly with editing//// of questions with question type 'multianswer'.//// Therefore they are kept in this file.//// They are not in the class as they are not//// likely to be subject for overriding./////////////////////////////////////////////////////////////// ANSWER_ALTERNATIVE regexesdefine("ANSWER_ALTERNATIVE_FRACTION_REGEX",       '=|%(-?[0-9]+)%');// for the syntax '(?<!' see http://www.perl.com/doc/manual/html/pod/perlre.html#item_Cdefine("ANSWER_ALTERNATIVE_ANSWER_REGEX",        '.+?(?<!\\\\|&|&amp;)(?=[~#}]|$)');define("ANSWER_ALTERNATIVE_FEEDBACK_REGEX",        '.*?(?<!\\\\)(?=[~}]|$)');define("ANSWER_ALTERNATIVE_REGEX",       '(' . ANSWER_ALTERNATIVE_FRACTION_REGEX .')?' .       '(' . ANSWER_ALTERNATIVE_ANSWER_REGEX . ')' .       '(#(' . ANSWER_ALTERNATIVE_FEEDBACK_REGEX .'))?');// Parenthesis positions for ANSWER_ALTERNATIVE_REGEXdefine("ANSWER_ALTERNATIVE_REGEX_PERCENTILE_FRACTION", 2);define("ANSWER_ALTERNATIVE_REGEX_FRACTION", 1);define("ANSWER_ALTERNATIVE_REGEX_ANSWER", 3);define("ANSWER_ALTERNATIVE_REGEX_FEEDBACK", 5);// NUMBER_FORMATED_ALTERNATIVE_ANSWER_REGEX is used// for identifying numerical answers in ANSWER_ALTERNATIVE_REGEX_ANSWERdefine("NUMBER_REGEX",        '-?(([0-9]+[.,]?[0-9]*|[.,][0-9]+)([eE][-+]?[0-9]+)?)');define("NUMERICAL_ALTERNATIVE_REGEX",        '^(' . NUMBER_REGEX . ')(:' . NUMBER_REGEX . ')?$');// Parenthesis positions for NUMERICAL_FORMATED_ALTERNATIVE_ANSWER_REGEXdefine("NUMERICAL_CORRECT_ANSWER", 1);define("NUMERICAL_ABS_ERROR_MARGIN", 6);// Remaining ANSWER regexesdefine("ANSWER_TYPE_DEF_REGEX",       '(NUMERICAL|NM)|(MULTICHOICE|MC)|(MULTICHOICE_V|MCV)|(MULTICHOICE_H|MCH)|(SHORTANSWER|SA|MW)|(SHORTANSWER_C|SAC|MWC)');define("ANSWER_START_REGEX",       '\{([0-9]*):(' . ANSWER_TYPE_DEF_REGEX . '):');define("ANSWER_REGEX",        ANSWER_START_REGEX        . '(' . ANSWER_ALTERNATIVE_REGEX        . '(~'        . ANSWER_ALTERNATIVE_REGEX        . ')*)\}' );// Parenthesis positions for singulars in ANSWER_REGEXdefine("ANSWER_REGEX_NORM", 1);define("ANSWER_REGEX_ANSWER_TYPE_NUMERICAL", 3);define("ANSWER_REGEX_ANSWER_TYPE_MULTICHOICE", 4);define("ANSWER_REGEX_ANSWER_TYPE_MULTICHOICE_REGULAR", 5);define("ANSWER_REGEX_ANSWER_TYPE_MULTICHOICE_HORIZONTAL", 6);define("ANSWER_REGEX_ANSWER_TYPE_SHORTANSWER", 7);define("ANSWER_REGEX_ANSWER_TYPE_SHORTANSWER_C", 8);define("ANSWER_REGEX_ALTERNATIVES", 9);function qtype_multianswer_extract_question($text) {    $question = new stdClass;    $question->qtype = 'multianswer';    $question->questiontext = $text;    $question->options->questions = array();    $question->defaultgrade = 0; // Will be increased for each answer norm    for ($positionkey=1        ; preg_match('/'.ANSWER_REGEX.'/', $question->questiontext, $answerregs)        ; ++$positionkey ) {        $wrapped = new stdClass;        $wrapped->defaultgrade = $answerregs[ANSWER_REGEX_NORM]            or $wrapped->defaultgrade = '1';        if (!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_NUMERICAL])) {            $wrapped->qtype = 'numerical';            $wrapped->multiplier = array();            $wrapped->units      = array();        } else if(!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_SHORTANSWER])) {            $wrapped->qtype = 'shortanswer';            $wrapped->usecase = 0;        } else if(!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_SHORTANSWER_C])) {            $wrapped->qtype = 'shortanswer';            $wrapped->usecase = 1;        } else if(!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_MULTICHOICE])) {            $wrapped->qtype = 'multichoice';            $wrapped->single = 1;            $wrapped->answernumbering = 0;            $wrapped->correctfeedback = '';            $wrapped->partiallycorrectfeedback = '';            $wrapped->incorrectfeedback = '';            $wrapped->layout = 0;        } else if(!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_MULTICHOICE_REGULAR])) {            $wrapped->qtype = 'multichoice';            $wrapped->single = 1;            $wrapped->answernumbering = 0;            $wrapped->correctfeedback = '';            $wrapped->partiallycorrectfeedback = '';            $wrapped->incorrectfeedback = '';            $wrapped->layout = 1;        } else if(!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_MULTICHOICE_HORIZONTAL])) {            $wrapped->qtype = 'multichoice';            $wrapped->single = 1;            $wrapped->answernumbering = 0;            $wrapped->correctfeedback = '';            $wrapped->partiallycorrectfeedback = '';            $wrapped->incorrectfeedback = '';            $wrapped->layout = 2;        } else {            print_error('unknownquestiontype', 'question', '', $answerregs[2]);            return false;        }        // Each $wrapped simulates a $form that can be processed by the        // respective save_question and save_question_options methods of the        // wrapped questiontypes        $wrapped->answer   = array();        $wrapped->fraction = array();        $wrapped->feedback = array();        $wrapped->shuffleanswers = 1;        $wrapped->questiontext = $answerregs[0];        $wrapped->questiontextformat = 0;        $remainingalts = $answerregs[ANSWER_REGEX_ALTERNATIVES];        while (preg_match('/~?'.ANSWER_ALTERNATIVE_REGEX.'/', $remainingalts, $altregs)) {            if ('=' == $altregs[ANSWER_ALTERNATIVE_REGEX_FRACTION]) {                $wrapped->fraction[] = '1';            } else if ($percentile = $altregs[ANSWER_ALTERNATIVE_REGEX_PERCENTILE_FRACTION]){                $wrapped->fraction[] = .01 * $percentile;            } else {                $wrapped->fraction[] = '0';            }            if (isset($altregs[ANSWER_ALTERNATIVE_REGEX_FEEDBACK])) {                $feedback = html_entity_decode($altregs[ANSWER_ALTERNATIVE_REGEX_FEEDBACK], ENT_QUOTES, 'UTF-8');                $feedback = str_replace('\}', '}', $feedback);                $wrapped->feedback[] = str_replace('\#', '#', $feedback);            } else {                $wrapped->feedback[] = '';            }            if (!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_NUMERICAL])                    && ereg(NUMERICAL_ALTERNATIVE_REGEX, $altregs[ANSWER_ALTERNATIVE_REGEX_ANSWER], $numregs)) {                $wrapped->answer[] = $numregs[NUMERICAL_CORRECT_ANSWER];                if ($numregs[NUMERICAL_ABS_ERROR_MARGIN]) {                    $wrapped->tolerance[] =                    $numregs[NUMERICAL_ABS_ERROR_MARGIN];                } else {                    $wrapped->tolerance[] = 0;                }            } else { // Tolerance can stay undefined for non numerical questions                // Undo quoting done by the HTML editor.                $answer = html_entity_decode($altregs[ANSWER_ALTERNATIVE_REGEX_ANSWER], ENT_QUOTES, 'UTF-8');                $answer = str_replace('\}', '}', $answer);                $wrapped->answer[] = str_replace('\#', '#', $answer);            }            $tmp = explode($altregs[0], $remainingalts, 2);            $remainingalts = $tmp[1];        }        $question->defaultgrade += $wrapped->defaultgrade;        $question->options->questions[$positionkey] = clone($wrapped);        $question->questiontext = implode("{#$positionkey}",                    explode($answerregs[0], $question->questiontext, 2));    }    $question->questiontext = $question->questiontext;    return $question;}?>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -