📄 format.php
字号:
<?php // $Id: format.php,v 1.41.2.9 2009/03/16 14:20:24 thepurpleblob Exp $/////////////////////////////////////////////////////////////////// XML import/export////////////////////////////////////////////////////////////////////////////// Based on default.php, included by ../import.php/** * @package questionbank * @subpackage importexport */require_once( "$CFG->libdir/xmlize.php" );class qformat_xml extends qformat_default { function provide_import() { return true; } function provide_export() { return true; } // IMPORT FUNCTIONS START HERE /** * Translate human readable format name * into internal Moodle code number * @param string name format name from xml file * @return int Moodle format code */ function trans_format( $name ) { $name = trim($name); if ($name=='moodle_auto_format') { $id = 0; } elseif ($name=='html') { $id = 1; } elseif ($name=='plain_text') { $id = 2; } elseif ($name=='wiki_like') { $id = 3; } elseif ($name=='markdown') { $id = 4; } else { $id = 0; // or maybe warning required } return $id; } /** * Translate human readable single answer option * to internal code number * @param string name true/false * @return int internal code number */ function trans_single( $name ) { $name = trim($name); if ($name == "false" || !$name) { return 0; } else { return 1; } } /** * process text string from xml file * @param array $text bit of xml tree after ['text'] * @return string processed text */ function import_text( $text ) { // quick sanity check if (empty($text)) { return ''; } $data = $text[0]['#']; return addslashes(trim( $data )); } /** * return the value of a node, given a path to the node * if it doesn't exist return the default value * @param array xml data to read * @param array path path to node expressed as array * @param mixed default * @param bool istext process as text * @param string error if set value must exist, return false and issue message if not * @return mixed value */ function getpath( $xml, $path, $default, $istext=false, $error='' ) { foreach ($path as $index) { if (!isset($xml[$index])) { if (!empty($error)) { $this->error( $error ); return false; } else { return $default; } } else $xml = $xml[$index]; } if ($istext) { if (!is_string($xml)) { $this->error( get_string('invalidxml','qformat_xml') ); } $xml = addslashes( trim( $xml ) ); } return $xml; } /** * import parts of question common to all types * @param $question array question question array from xml tree * @return object question object */ function import_headers( $question ) { // get some error strings $error_noname = get_string( 'xmlimportnoname','quiz' ); $error_noquestion = get_string( 'xmlimportnoquestion','quiz' ); // this routine initialises the question object $qo = $this->defaultquestion(); // question name $qo->name = $this->getpath( $question, array('#','name',0,'#','text',0,'#'), '', true, $error_noname ); $qo->questiontext = $this->getpath( $question, array('#','questiontext',0,'#','text',0,'#'), '', true ); $qo->questiontextformat = $this->getpath( $question, array('#','questiontext',0,'@','format'), '' ); $qo->image = $this->getpath( $question, array('#','image',0,'#'), $qo->image ); $image_base64 = $this->getpath( $question, array('#','image_base64','0','#'),'' ); if (!empty($image_base64)) { $qo->image = $this->importimagefile( $qo->image, stripslashes($image_base64) ); } $qo->generalfeedback = $this->getpath( $question, array('#','generalfeedback',0,'#','text',0,'#'), $qo->generalfeedback, true ); $qo->defaultgrade = $this->getpath( $question, array('#','defaultgrade',0,'#'), $qo->defaultgrade ); $qo->penalty = $this->getpath( $question, array('#','penalty',0,'#'), $qo->penalty ); return $qo; } /** * import the common parts of a single answer * @param array answer xml tree for single answer * @return object answer object */ function import_answer( $answer ) { $fraction = $this->getpath( $answer, array('@','fraction'),0 ); $text = $this->getpath( $answer, array('#','text',0,'#'), '', true ); $feedback = $this->getpath( $answer, array('#','feedback',0,'#','text',0,'#'), '', true ); $ans = null; $ans->answer = $text; $ans->fraction = $fraction / 100; $ans->feedback = $feedback; return $ans; } /** * import multiple choice question * @param array question question array from xml tree * @return object question object */ function import_multichoice( $question ) { // get common parts $qo = $this->import_headers( $question ); // 'header' parts particular to multichoice $qo->qtype = MULTICHOICE; $single = $this->getpath( $question, array('#','single',0,'#'), 'true' ); $qo->single = $this->trans_single( $single ); $shuffleanswers = $this->getpath( $question, array('#','shuffleanswers',0,'#'), 'false' ); $qo->answernumbering = $this->getpath( $question, array('#','answernumbering',0,'#'), 'abc' ); $qo->shuffleanswers = $this->trans_single($shuffleanswers); $qo->correctfeedback = $this->getpath( $question, array('#','correctfeedback',0,'#','text',0,'#'), '', true ); $qo->partiallycorrectfeedback = $this->getpath( $question, array('#','partiallycorrectfeedback',0,'#','text',0,'#'), '', true ); $qo->incorrectfeedback = $this->getpath( $question, array('#','incorrectfeedback',0,'#','text',0,'#'), '', true ); // There was a time on the 1.8 branch when it could output an empty answernumbering tag, so fix up any found. if (empty($qo->answernumbering)) { $qo->answernumbering = 'abc'; } // run through the answers $answers = $question['#']['answer']; $a_count = 0; foreach ($answers as $answer) { $ans = $this->import_answer( $answer ); $qo->answer[$a_count] = $ans->answer; $qo->fraction[$a_count] = $ans->fraction; $qo->feedback[$a_count] = $ans->feedback; ++$a_count; } return $qo; } /** * import cloze type question * @param array question question array from xml tree * @return object question object */ function import_multianswer( $questions ) { $questiontext = $questions['#']['questiontext'][0]['#']['text']; $qo = qtype_multianswer_extract_question($this->import_text($questiontext)); // 'header' parts particular to multianswer $qo->qtype = MULTIANSWER; $qo->course = $this->course; $qo->generalfeedback = $this->getpath( $questions, array('#','generalfeedback',0,'#','text',0,'#'), '', true ); if (!empty($questions)) { $qo->name = $this->import_text( $questions['#']['name'][0]['#']['text'] ); } return $qo; } /** * import true/false type question * @param array question question array from xml tree * @return object question object */ function import_truefalse( $question ) { // get common parts $qo = $this->import_headers( $question ); // 'header' parts particular to true/false $qo->qtype = TRUEFALSE; // get answer info // // In the past, it used to be assumed that the two answers were in the file // true first, then false. Howevever that was not always true. Now, we // try to match on the answer text, but in old exports, this will be a localised // string, so if we don't find true or false, we fall back to the old system. $first = true; $warning = false; foreach ($question['#']['answer'] as $answer) { $answertext = $this->getpath( $answer, array('#','text',0,'#'), '', true ); $feedback = $this->getpath($answer, array('#','feedback',0,'#','text',0,'#'), '', true ); if ($answertext != 'true' && $answertext != 'false') { $warning = true; $answertext = $first ? 'true' : 'false'; // Old style file, assume order is true/false. } if ($answertext == 'true') { $qo->answer = ($answer['@']['fraction'] == 100); $qo->correctanswer = $qo->answer; $qo->feedbacktrue = $feedback; } else { $qo->answer = ($answer['@']['fraction'] != 100); $qo->correctanswer = $qo->answer; $qo->feedbackfalse = $feedback; } $first = false; } if ($warning) { $a = new stdClass; $a->questiontext = $qo->questiontext; $a->answer = get_string($qo->answer ? 'true' : 'false', 'quiz'); notify(get_string('truefalseimporterror', 'quiz', $a)); } return $qo; } /** * import short answer type question * @param array question question array from xml tree * @return object question object */ function import_shortanswer( $question ) { // get common parts $qo = $this->import_headers( $question ); // header parts particular to shortanswer $qo->qtype = SHORTANSWER; // get usecase $qo->usecase = $this->getpath($question, array('#','usecase',0,'#'), $qo->usecase ); // run through the answers $answers = $question['#']['answer']; $a_count = 0; foreach ($answers as $answer) { $ans = $this->import_answer( $answer ); $qo->answer[$a_count] = $ans->answer; $qo->fraction[$a_count] = $ans->fraction; $qo->feedback[$a_count] = $ans->feedback; ++$a_count; } return $qo; } /** * import description type question * @param array question question array from xml tree * @return object question object */ function import_description( $question ) { // get common parts $qo = $this->import_headers( $question ); // header parts particular to shortanswer $qo->qtype = DESCRIPTION; $qo->defaultgrade = 0; $qo->length = 0; return $qo; } /** * import numerical type question * @param array question question array from xml tree * @return object question object */ function import_numerical( $question ) { // get common parts $qo = $this->import_headers( $question ); // header parts particular to numerical $qo->qtype = NUMERICAL; // get answers array $answers = $question['#']['answer']; $qo->answer = array(); $qo->feedback = array(); $qo->fraction = array(); $qo->tolerance = array(); foreach ($answers as $answer) { // answer outside of <text> is deprecated $answertext = trim( $this->getpath( $answer, array('#',0), '' ) ); $qo->answer[] = $this->getpath( $answer, array('#','text',0,'#'), $answertext, true ); if (empty($qo->answer)) { $qo->answer = '*'; } $qo->feedback[] = $this->getpath( $answer, array('#','feedback',0,'#','text',0,'#'), '', true );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -