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

📄 questiontype.php

📁 很棒的在线教学系统
💻 PHP
📖 第 1 页 / 共 3 页
字号:
<?php  // $Id: questiontype.php,v 1.41.2.17 2009/02/13 06:11:59 tjhunt Exp $////////////////////// MULTIANSWER /// (Embedded - cloze)///////////////////////// The multianswer question type is special in that it/// depends on a few other question types, i.e./// 'multichoice', 'shortanswer' and 'numerical'./// These question types have got a few special features that/// makes them useable by the 'multianswer' question type////// QUESTION TYPE CLASS ///////////////////** * @package questionbank * @subpackage questiontypes */class embedded_cloze_qtype extends default_questiontype {    function name() {        return 'multianswer';    }    function get_question_options(&$question) {        global $QTYPES;        // Get relevant data indexed by positionkey from the multianswers table        if (!$sequence = get_field('question_multianswer', 'sequence', 'question', $question->id)) {            notify(get_string('noquestions','qtype_multianswer',$question->name));            $question->options->questions['1']= '';            return true ;        }        $wrappedquestions = get_records_list('question', 'id', $sequence, 'id ASC');        // We want an array with question ids as index and the positions as values        $sequence = array_flip(explode(',', $sequence));        array_walk($sequence, create_function('&$val', '$val++;'));        //If a question is lost, the corresponding index is null        // so this null convention is used to test $question->options->questions         // before using the values.        // first all possible questions from sequence are nulled         // then filled with the data if available in  $wrappedquestions        $nbvaliquestion = 0 ;        foreach($sequence as $seq){            $question->options->questions[$seq]= '';        }        if (isset($wrappedquestions) && is_array($wrappedquestions)){            foreach ($wrappedquestions as $wrapped) {                if (!$QTYPES[$wrapped->qtype]->get_question_options($wrapped)) {                    notify("Unable to get options for questiontype {$wrapped->qtype} (id={$wrapped->id})");                                }else {                    // for wrapped questions the maxgrade is always equal to the defaultgrade,                    // there is no entry in the question_instances table for them                    $wrapped->maxgrade = $wrapped->defaultgrade;                    $nbvaliquestion++ ;                    $question->options->questions[$sequence[$wrapped->id]] = clone($wrapped); // ??? Why do we need a clone here?                }            }        }        if ($nbvaliquestion == 0 ) {            notify(get_string('noquestions','qtype_multianswer',$question->name));        }        return true;    }    function save_question_options($question) {        global $QTYPES;        $result = new stdClass;        // This function needs to be able to handle the case where the existing set of wrapped        // questions does not match the new set of wrapped questions so that some need to be        // created, some modified and some deleted        // Unfortunately the code currently simply overwrites existing ones in sequence. This        // will make re-marking after a re-ordering of wrapped questions impossible and        // will also create difficulties if questiontype specific tables reference the id.        // First we get all the existing wrapped questions        if (!$oldwrappedids = get_field('question_multianswer', 'sequence', 'question', $question->id)) {            $oldwrappedquestions = array();        } else {            $oldwrappedquestions = get_records_list('question', 'id', $oldwrappedids, 'id ASC');        }        $sequence = array();        foreach($question->options->questions as $wrapped) {            if (!empty($wrapped)){            // if we still have some old wrapped question ids, reuse the next of them                if (is_array($oldwrappedquestions) && $oldwrappedquestion = array_shift($oldwrappedquestions)) {                    $wrapped->id = $oldwrappedquestion->id;                    if($oldwrappedquestion->qtype != $wrapped->qtype ) {                        switch ($oldwrappedquestion->qtype) {                        case 'multichoice':                                 delete_records('question_multichoice', 'question' , $oldwrappedquestion->id );                            break;                        case 'shortanswer':                                 delete_records('question_shortanswer', 'question' , $oldwrappedquestion->id );                            break;                        case 'numerical':                                 delete_records('question_numerical', 'question' , $oldwrappedquestion->id );                            break;                        default:                                print_error('qtypenotrecognized', 'qtype_multianswer','',$oldwrappedquestion->qtype);                                        $wrapped->id = 0 ;                            }                    }                }else {                    $wrapped->id = 0 ;                }            }            $wrapped->name = $question->name;            $wrapped->parent = $question->id;            $previousid = $wrapped->id ;            $wrapped->category = $question->category . ',1'; // save_question strips this extra bit off again.            $wrapped = $QTYPES[$wrapped->qtype]->save_question($wrapped,                    $wrapped, $question->course);            $sequence[] = $wrapped->id;            if ($previousid != 0 && $previousid != $wrapped->id ) {                 // for some reasons a new question has been created                // so delete the old one                delete_question($previousid) ;            }        }        // Delete redundant wrapped questions        if(is_array($oldwrappedquestions) && count($oldwrappedquestions)){            foreach ($oldwrappedquestions as $oldwrappedquestion) {                delete_question($oldwrappedquestion->id) ;            }        }        if (!empty($sequence)) {            $multianswer = new stdClass;            $multianswer->question = $question->id;            $multianswer->sequence = implode(',', $sequence);            if ($oldid = get_field('question_multianswer', 'id', 'question', $question->id)) {                $multianswer->id = $oldid;                if (!update_record("question_multianswer", $multianswer)) {                    $result->error = "Could not update cloze question options! " .                            "(id=$multianswer->id)";                    return $result;                }            } else {                if (!insert_record("question_multianswer", $multianswer)) {                    $result->error = "Could not insert cloze question options!";                    return $result;                }            }        }    }    function save_question($authorizedquestion, $form, $course) {        $question = qtype_multianswer_extract_question($form->questiontext);        if (isset($authorizedquestion->id)) {            $question->id = $authorizedquestion->id;        }        $question->category = $authorizedquestion->category;        $form->course = $course; // To pass the course object to                                 // save_question_options, where it is                                 // needed to call type specific                                 // save_question methods.        $form->defaultgrade = $question->defaultgrade;        $form->questiontext = $question->questiontext;        $form->questiontextformat = 0;        $form->options = clone($question->options);        unset($question->options);        return parent::save_question($question, $form, $course);    }    function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) {        $state->responses = array();        foreach ($question->options->questions as $key => $wrapped) {            $state->responses[$key] = '';        }        return true;    }    function restore_session_and_responses(&$question, &$state) {        $responses = explode(',', $state->responses['']);        $state->responses = array();        foreach ($responses as $response) {            $tmp = explode("-", $response);            // restore encoded characters            $state->responses[$tmp[0]] = str_replace(array("&#0044;", "&#0045;"),                    array(",", "-"), $tmp[1]);        }        return true;    }    function save_session_and_responses(&$question, &$state) {        $responses = $state->responses;        // encode - (hyphen) and , (comma) to &#0045; because they are used as        // delimiters        array_walk($responses, create_function('&$val, $key',                '$val = str_replace(array(",", "-"), array("&#0044;", "&#0045;"), $val);                $val = "$key-$val";'));        $responses = implode(',', $responses);        // Set the legacy answer field        if (!set_field('question_states', 'answer', $responses, 'id', $state->id)) {            return false;        }        return true;    }    /**    * Deletes question from the question-type specific tables    *    * @return boolean Success/Failure    * @param object $question  The question being deleted    */    function delete_question($questionid) {        delete_records("question_multianswer", "question", $questionid);        return true;    }    function get_correct_responses(&$question, &$state) {        global $QTYPES;        $responses = array();        foreach($question->options->questions as $key => $wrapped) {            if (  !empty($wrapped)){                if ($correct = $QTYPES[$wrapped->qtype]->get_correct_responses($wrapped, $state)) {                    $responses[$key] = $correct[''];                } else {                    // if there is no correct answer to this subquestion then there                    // can not be a correct answer to the whole question either, so                    // we have to return null.                    return null;                }            }        }        return $responses;    }    function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options) {        global $QTYPES, $CFG, $USER;        $readonly = empty($options->readonly) ? '' : 'readonly="readonly"';        $disabled = empty($options->readonly) ? '' : 'disabled="disabled"';        $formatoptions = new stdClass;        $formatoptions->noclean = true;        $formatoptions->para = false;        $nameprefix = $question->name_prefix;        // adding an icon with alt to warn user this is a fill in the gap question        // MDL-7497        if (!empty($USER->screenreader)) {            echo "<img src=\"$CFG->wwwroot/question/type/$question->qtype/icon.gif\" ".                "class=\"icon\" alt=\"".get_string('clozeaid','qtype_multichoice')."\" />  ";        }        echo '<div class="ablock clearfix">';        // For this question type, we better print the image on top:        if ($image = get_question_image($question)) {            echo('<img class="qimage" src="' . $image . '" alt="" /><br />');        }        $qtextremaining = format_text($question->questiontext,                $question->questiontextformat, $formatoptions, $cmoptions->course);        $strfeedback = get_string('feedback', 'quiz');        // The regex will recognize text snippets of type {#X}        // where the X can be any text not containg } or white-space characters.        while (ereg('\{#([^[:space:]}]*)}', $qtextremaining, $regs)) {            $qtextsplits = explode($regs[0], $qtextremaining, 2);            echo $qtextsplits[0];            echo "<label>"; // MDL-7497            $qtextremaining = $qtextsplits[1];            $positionkey = $regs[1];            if (isset($question->options->questions[$positionkey]) && $question->options->questions[$positionkey] != ''){            $wrapped = &$question->options->questions[$positionkey];            $answers = &$wrapped->options->answers;           // $correctanswers = $QTYPES[$wrapped->qtype]->get_correct_responses($wrapped, $state);            $inputname = $nameprefix.$positionkey;            if (isset($state->responses[$positionkey])) {                $response = $state->responses[$positionkey];            } else {                $response = null;            }            // Determine feedback popup if any            $popup = '';            $style = '';            $feedbackimg = '';            $feedback = '' ;            $correctanswer = '';            $strfeedbackwrapped  = $strfeedback;                $testedstate = clone($state);                if ($correctanswers =  $QTYPES[$wrapped->qtype]->get_correct_responses($wrapped, $testedstate)) {                    if ($options->readonly && $options->correct_responses) {                        $delimiter = '';                        if ($correctanswers) {                            foreach ($correctanswers as $ca) {                                switch($wrapped->qtype){                                    case 'numerical':                                    case 'shortanswer':                                        $correctanswer .= $delimiter.$ca;                                        break ;                                    case 'multichoice':                                        if (isset($answers[$ca])){                                            $correctanswer .= $delimiter.$answers[$ca]->answer;                                        }                                        break ;                                }                                $delimiter = ', ';                            }                        }                    }                    if ($correctanswer) {                        $feedback = '<div class="correctness">';                        $feedback .= get_string('correctansweris', 'quiz', s($correctanswer, true));                        $feedback .= '</div>';                    }                }            if ($options->feedback) {                $chosenanswer = null;                switch ($wrapped->qtype) {                    case 'numerical':                    case 'shortanswer':                        $testedstate = clone($state);                        $testedstate->responses[''] = $response;                        foreach ($answers as $answer) {                            if($QTYPES[$wrapped->qtype]                                    ->test_response($wrapped, $testedstate, $answer)) {                                $chosenanswer = clone($answer);                                break;                            }                        }                        break;                    case 'multichoice':                        if (isset($answers[$response])) {

⌨️ 快捷键说明

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