merging from head so that calculated questions can be imported and other improvments

This commit is contained in:
pichetp
2007-05-11 15:29:50 +00:00
parent fc418ee754
commit 9c53d3286c
2 changed files with 304 additions and 141 deletions
+127 -131
View File
@@ -27,6 +27,10 @@
///////////////////////////////////////////////////////////////////////////
// Based on format.php, included by ../../import.php
/**
* @package questionbank
* @subpackage importexport
*/
function unhtmlentities($string){
$search = array ("'<script[?>]*?>.*?</script>'si", // remove javascript
@@ -58,91 +62,7 @@ function unhtmlentities($string){
return preg_replace ($search, $replace, $string);
}
class qformat_webct_modified_calculated_qtype extends question_calculated_qtype {
// We need to make a modification of this qtype so that
// it will be able to save webct style calculated questions
// The difference between webct and Moodle is that webct
// pass the individual data items as part of the question
// while Moodle core treat them separately
function save_question_options($question, $options = false) {
if (false !== $options) {
// function is called from save_question...
return parent::save_question_options($question, $options);
}
// function is called from format.php...
$datasetdatas = $question->datasets;
// Set dataset
$form->dataset = array();
foreach ($datasetdatas as $datasetname => $notimportant) {
// Literal - question local - name
$form->dataset[] = "1-0-$datasetname";
}
$subtypeoptions->answers = $question->answers;
$subtypeoptions->units = $question->units;
unset($question->datasets);
unset($question->answers);
unset($question->units);
$this->save_question($question, $form, 'not used', $subtypeoptions);
// Save dataset options and items...
// Get datasetdefinitions
global $CFG;
$datasetdefs = get_records_sql(
"SELECT a.*
FROM {$CFG->prefix}question_dataset_definitions a,
{$CFG->prefix}question_datasets b
WHERE a.id = b.datasetdefinition
AND b.question = '$question->id' ");
foreach ($datasetdefs as $datasetdef) {
$datasetdata = $datasetdatas[$datasetdef->name];
// Set items and retrieve ->itemcout
$item->definition = $datasetdef->id;
for ($item->number=1 ; isset($datasetdata->items["$item->number"]) ; ++$item->number) {
$item->value = $datasetdata->items["$item->number"];
if (!insert_record('question_dataset_items', $item)) {
error("Unable to insert dataset item $item->number with $item->value for $datasetdef->name");
}
}
$datasetdef->itemcount = $item->number - 1;
// Retrieve ->options
if (is_numeric($datasetdata->min) && is_numeric($datasetdata->max)
&& $datasetdata->min <= $datasetdata->max) {
if (is_numeric($datasetdata->dec)) {
$dec = max(0, ceil($datasetdata->dec));
} else {
$dec = 1; // A try
}
$datasetdef->options = "uniform:$datasetdata->min:$datasetdata->max:$dec";
} else {
$datasetdef->options = '';
}
// Save definition
if ($datasetdef->itemcount || $datasetdef->options) {
if (!update_record('question_dataset_definitions', $datasetdef)) {
error("Unable to update dataset definition $datasetdef->name on question $question->id");
}
}
}
// Done
return true;
}
}
$QTYPES[CALCULATED] = new qformat_webct_modified_calculated_qtype();
function qformat_webct_convert_formula($formula) {
@@ -246,8 +166,8 @@ class qformat_webct extends qformat_default {
}
function readquestions ($lines) {
$qtypecalculated = new qformat_webct_modified_calculated_qtype();
global $QTYPES ;
// $qtypecalculated = new qformat_webct_modified_calculated_qtype();
$webctnumberregex =
'[+-]?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)((e|E|\\*10\\*\\*)([+-]?[0-9]+|\\([+-]?[0-9]+\\)))?';
@@ -262,11 +182,11 @@ class qformat_webct extends qformat_default {
$nQuestionStartLine = 0;
$bIsHTMLText = FALSE;
$lines[] = ":EOF:"; // for an easiest processing of the last line
$question = $this->defaultquestion();
// $question = $this->defaultquestion();
foreach ($lines as $line) {
$nLineCounter++;
$line = iconv("Windows-1252","UTF-8",$line);
// Processing multiples lines strings
if (isset($questiontext) and is_string($questiontext)) {
@@ -306,7 +226,7 @@ class qformat_webct extends qformat_default {
if (isset($feedbacktext) and is_string($feedbacktext)) {
if (ereg("^:",$line)) {
$question->feedback[$currentchoice] = addslashes(trim($feedbacktext));
$question->feedback[$currentchoice] = addslashes(trim($feedbacktext));
unset($feedbacktext);
}
else {
@@ -315,6 +235,17 @@ class qformat_webct extends qformat_default {
}
}
if (isset($generalfeedbacktext) and is_string($generalfeedbacktext)) {
if (ereg("^:",$line)) {
$question->tempgeneralfeedback= addslashes(trim($generalfeedbacktext));
unset($generalfeedbacktext);
}
else {
$generalfeedbacktext .= str_replace('\:', ':', $line);
continue;
}
}
$line = trim($line);
if (eregi("^:(TYPE|EOF):",$line)) {
@@ -347,11 +278,26 @@ class qformat_webct extends qformat_default {
$QuestionOK = FALSE;
}
else {
// Create empty feedback array
$question->feedback = array();
// Create empty feedback array
foreach ($question->answer as $key => $dataanswer) {
$question->feedback[$key] = '';
if(!isset( $question->feedback[$key])){
$question->feedback[$key] = '';
}
}
// this tempgeneralfeedback allows the code to work with versions from 1.6 to 1.9
// when question->generalfeedback is undefined, the webct feedback is added to each answer feedback
if (isset($question->tempgeneralfeedback)){
if (isset($question->generalfeedback)) {
$question->generalfeedback = $question->tempgeneralfeedback;
} else {
foreach ($question->answer as $key => $dataanswer) {
if ($question->tempgeneralfeedback !=''){
$question->feedback[$key] = $question->tempgeneralfeedback.'<br/>'.$question->feedback[$key];
}
}
}
unset($question->tempgeneralfeedback);
}
$maxfraction = -1;
$totalfraction = 0;
foreach($question->fraction as $fraction) {
@@ -366,7 +312,7 @@ class qformat_webct extends qformat_default {
case SHORTANSWER:
if ($maxfraction != 1) {
$maxfraction = $maxfraction * 100;
$errors[] = "'$question->name': ".get_string("wronggrade", "quiz", $nLineCounter).get_string("fractionsnomax", "quiz", $maxfraction);
$errors[] = "'$question->name': ".get_string("wronggrade", "quiz", $nLineCounter).' '.get_string("fractionsnomax", "quiz", $maxfraction);
$QuestionOK = FALSE;
}
break;
@@ -375,15 +321,14 @@ class qformat_webct extends qformat_default {
if ($question->single) {
if ($maxfraction != 1) {
$maxfraction = $maxfraction * 100;
$errors[] = "'$question->name': ".get_string("wronggrade", "quiz", $nLineCounter).get_string("fractionsnomax", "quiz", $maxfraction);
$errors[] = "'$question->name': ".get_string("wronggrade", "quiz", $nLineCounter).' '.get_string("fractionsnomax", "quiz", $maxfraction);
$QuestionOK = FALSE;
}
} else {
$totalfraction = round($totalfraction,2);
if ($totalfraction != 1) {
echo "<p>$totalfraction</p>";
if ($totalfraction != 1) {
$totalfraction = $totalfraction * 100;
$errors[] = "'$question->name': ".get_string("wronggrade", "quiz", $nLineCounter).get_string("fractionsaddwrong", "quiz", $totalfraction);
$errors[] = "'$question->name': ".get_string("wronggrade", "quiz", $nLineCounter).' '.get_string("fractionsaddwrong", "quiz", $totalfraction);
$QuestionOK = FALSE;
}
}
@@ -391,20 +336,35 @@ class qformat_webct extends qformat_default {
case CALCULATED:
foreach ($question->answers as $answer) {
if ($formulaerror = quiz_qtype_calculated_find_formula_errors($answer->answer)) {
if ($formulaerror =qtype_calculated_find_formula_errors($answer)) { //$QTYPES['calculated']->
$warnings[] = "'$question->name': ". $formulaerror;
$QuestionOK = FALSE;
}
}
foreach ($question->dataset as $dataset) {
$dataset->itemcount=count($dataset->datasetitem);
}
$question->import_process=TRUE ;
unset($question->answer); //not used in calculated question
break;
case MATCH:
if (count($question->answer) < 3){
// add a dummy missing question
$question->name = 'Dummy question added '.$question->name ;
$question->answer[] = 'dummy';
$question->subanswers[] = 'dummy';
$question->subquestions[] = 'dummy';
$question->fraction[] = '0.0';
$question->feedback[] = '';
}
break;
default:
// No problemo
}
}
if ($QuestionOK) {
// $question->feedback = array();
if ($QuestionOK) {
// echo "<pre>"; print_r ($question);
$questions[] = $question; // store it
unset($question); // and prepare a new one
$question = $this->defaultquestion();
@@ -417,6 +377,8 @@ class qformat_webct extends qformat_default {
if (eregi("^:TYPE:MC:1(.*)",$line,$webct_options)) {
// Multiple Choice Question with only one good answer
$question = $this->defaultquestion();
$question->feedback = array();
$question->qtype = MULTICHOICE;
$question->single = 1; // Only one answer is allowed
$ignore_rest_of_question = FALSE;
@@ -425,6 +387,8 @@ class qformat_webct extends qformat_default {
if (eregi("^:TYPE:MC:N(.*)",$line,$webct_options)) {
// Multiple Choice Question with several good answers
$question = $this->defaultquestion();
$question->feedback = array();
$question->qtype = MULTICHOICE;
$question->single = 0; // Many answers allowed
$ignore_rest_of_question = FALSE;
@@ -433,6 +397,8 @@ class qformat_webct extends qformat_default {
if (eregi("^:TYPE:S",$line)) {
// Short Answer Question
$question = $this->defaultquestion();
$question->feedback = array();
$question->qtype = SHORTANSWER;
$question->usecase = 0; // Ignore case
$ignore_rest_of_question = FALSE;
@@ -441,14 +407,20 @@ class qformat_webct extends qformat_default {
if (eregi("^:TYPE:C",$line)) {
// Calculated Question
/* $warnings[] = get_string("calculatedquestion", "quiz", $nLineCounter);
unset($question);
$ignore_rest_of_question = TRUE; // Question Type not handled by Moodle
*/
$question = $this->defaultquestion();
$question->qtype = CALCULATED;
$question->answers = array(); // No problem as they go as :FORMULA: from webct
$question->units = array();
$question->datasets = array();
$question->dataset = array();
// To make us pass the end-of-question sanity checks
$question->answer = array('dummy');
$question->fraction = array('1.0');
$question->feedback = array();
$currentchoice = -1;
$ignore_rest_of_question = FALSE;
@@ -457,7 +429,9 @@ class qformat_webct extends qformat_default {
if (eregi("^:TYPE:M",$line)) {
// Match Question
$question = $this->defaultquestion();
$question->qtype = MATCH;
$question->feedback = array();
$ignore_rest_of_question = FALSE; // match question processing is not debugged
continue;
}
@@ -465,6 +439,7 @@ class qformat_webct extends qformat_default {
if (eregi("^:TYPE:P",$line)) {
// Paragraph Question
$warnings[] = get_string("paragraphquestion", "quiz", $nLineCounter);
unset($question);
$ignore_rest_of_question = TRUE; // Question Type not handled by Moodle
continue;
}
@@ -472,6 +447,7 @@ class qformat_webct extends qformat_default {
if (eregi("^:TYPE:",$line)) {
// Unknow Question
$warnings[] = get_string("unknowntype", "quiz", $nLineCounter);
unset($question);
$ignore_rest_of_question = TRUE; // Question Type not handled by Moodle
continue;
}
@@ -502,25 +478,27 @@ class qformat_webct extends qformat_default {
// if question isn't defined yet there is nothing to do here (avoid notices)
if (!isset($question)) {
continue;
}
if (CALCULATED == $question->qtype && ereg(
}
if (isset($question->qtype ) && CALCULATED == $question->qtype && ereg(
"^:([[:lower:]].*|::.*)-(MIN|MAX|DEC|VAL([0-9]+))::?:?($webctnumberregex)", $line, $webct_options)) {
$datasetname = ereg_replace('^::', '', $webct_options[1]);
$datasetvalue = qformat_webct_convert_formula($webct_options[4]);
switch ($webct_options[2]) {
case 'MIN':
$question->datasets[$datasetname]->min = $datasetvalue;
$question->dataset[$datasetname]->min = $datasetvalue;
break;
case 'MAX':
$question->datasets[$datasetname]->max = $datasetvalue;
$question->dataset[$datasetname]->max = $datasetvalue;
break;
case 'DEC':
$datasetvalue = floor($datasetvalue); // int only!
$question->datasets[$datasetname]->dec = max(0, $datasetvalue);
$question->dataset[$datasetname]->length = max(0, $datasetvalue);
break;
default:
// The VAL case:
$question->datasets[$datasetname]->items[$webct_options[3]] = $datasetvalue;
$question->dataset[$datasetname]->datasetitem[$webct_options[3]] = new stdClass();
$question->dataset[$datasetname]->datasetitem[$webct_options[3]]->itemnumber = $webct_options[3];
$question->dataset[$datasetname]->datasetitem[$webct_options[3]]->value = $datasetvalue;
break;
}
continue;
@@ -550,19 +528,23 @@ class qformat_webct extends qformat_default {
if (eregi('^:FORMULA:(.*)', $line, $webct_options)) {
// Answer for a CALCULATED question
++$currentchoice;
$question->answers[$currentchoice]->answer =
$question->answers[$currentchoice] =
qformat_webct_convert_formula($webct_options[1]);
// Default settings:
$question->answers[$currentchoice]->fraction = 1.0;
$question->answers[$currentchoice]->tolerance = 0.0;
$question->answers[$currentchoice]->tolerancetype = 2; // nominal (units in webct)
$question->answers[$currentchoice]->feedback = '';
$question->answers[$currentchoice]->correctanswerlength = 4;
$question->fraction[$currentchoice] = 1.0;
$question->tolerance[$currentchoice] = 0.0;
$question->tolerancetype[$currentchoice] = 2; // nominal (units in webct)
$question->feedback[$currentchoice] = '';
$question->correctanswerlength[$currentchoice] = 4;
$datasetnames = $qtypecalculated->find_dataset_names($webct_options[1]);
$datasetnames = $QTYPES[CALCULATED]->find_dataset_names($webct_options[1]);
foreach ($datasetnames as $datasetname) {
$question->datasets[$datasetname]->items = array();
$question->dataset[$datasetname] = new stdClass();
$question->dataset[$datasetname]->datesetitem = array();
$question->dataset[$datasetname]->name = $datasetname ;
$question->dataset[$datasetname]->distribution = 'uniform';
$question->dataset[$datasetname]->status ='private';
}
continue;
}
@@ -585,24 +567,38 @@ class qformat_webct extends qformat_default {
$currentchoice=$webct_options[1];
continue;
}
if (CALCULATED == $question->qtype && eregi('^:ANS-DEC:([1-9][0-9]*)', $line, $webct_options)) {
// We can but hope that this always appear before the ANSTYPE property
$question->answers[$currentchoice]->correctanswerlength = $webct_options[1];
if (eregi("^:FEEDBACK([0-9]+):?",$line,$webct_options)) {
$generalfeedbacktext=""; // Start gathering next lines
$currentchoice=$webct_options[1];
continue;
}
if (eregi('^:FEEDBACK:(.*)',$line,$webct_options)) {
$generalfeedbacktext=""; // Start gathering next lines
continue;
}
if (eregi('^:LAYOUT:(.*)',$line,$webct_options)) {
// ignore since layout in question_multichoice is no more used in moodle
// $webct_options[1] contains either vertical or horizontal ;
continue;
}
if (CALCULATED == $question->qtype && eregi("^:TOL:($webctnumberregex)", $line, $webct_options)) {
if (isset($question->qtype ) && CALCULATED == $question->qtype && eregi('^:ANS-DEC:([1-9][0-9]*)', $line, $webct_options)) {
// We can but hope that this always appear before the ANSTYPE property
$question->correctanswerlength[$currentchoice] = $webct_options[1];
continue;
}
if (isset($question->qtype )&& CALCULATED == $question->qtype && eregi("^:TOL:($webctnumberregex)", $line, $webct_options)) {
// We can but hope that this always appear before the TOL property
$question->answers[$currentchoice]->tolerance =
$question->tolerance[$currentchoice] =
qformat_webct_convert_formula($webct_options[1]);
continue;
}
if (CALCULATED == $question->qtype && eregi('^:TOLTYPE:percent', $line)) {
if (isset($question->qtype )&& CALCULATED == $question->qtype && eregi('^:TOLTYPE:percent', $line)) {
// Percentage case is handled as relative in Moodle:
$question->answers[$currentchoice]->tolerance /= 100;
$question->answers[$currentchoice]->tolerancetype = 1; // Relative
$question->tolerance[$currentchoice] /= 100;
$question->tolerancetype[$currentchoice] = 1; // Relative
continue;
}
@@ -634,12 +630,12 @@ class qformat_webct extends qformat_default {
continue;
}
if (CALCULATED == $question->qtype && eregi('^:ANSTYPE:dec', $line)) {
// Houston - we have a problem
// Moodle does not support this - we try something defensively by
// setting the correct answer length to 5, it shoud be enough for
// most cases
$question->answers[$currentchoice]->correctanswerlength = 5;
if (isset($question->qtype )&& CALCULATED == $question->qtype && eregi('^:ANSTYPE:dec', $line)) {
$question->correctanswerformat[$currentchoice]='1';
continue;
}
if (isset($question->qtype )&& CALCULATED == $question->qtype && eregi('^:ANSTYPE:sig', $line)) {
$question->correctanswerformat[$currentchoice]='2';
continue;
}
}
+177 -10
View File
@@ -5,7 +5,10 @@
//
//////////////////////////////////////////////////////////////////////////
// Based on default.php, included by ../import.php
/**
* @package questionbank
* @subpackage importexport
*/
require_once( "$CFG->libdir/xmlize.php" );
class qformat_xml extends qformat_default {
@@ -20,11 +23,11 @@ class qformat_xml extends qformat_default {
// 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
* @param string name format name from xml file
* @return int Moodle format code
*/
function trans_format( $name ) {
$name = trim($name);
@@ -53,8 +56,8 @@ class qformat_xml extends qformat_default {
/*
* Translate human readable single answer option
* to internal code number
* @PARAM string name true/false
* @RETURN int internal code number
* @param string name true/false
* @return int internal code number
*/
function trans_single( $name ) {
$name = trim($name);
@@ -65,14 +68,17 @@ class qformat_xml extends qformat_default {
}
}
/*
/**
* 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]['#'];
$data = html_entity_decode( $data );
return addslashes(trim( $data ));
}
@@ -381,8 +387,102 @@ class qformat_xml extends qformat_default {
// get feedback
$qo->feedback = $this->import_text( $question['#']['answer'][0]['#']['feedback'][0]['#']['text'] );
// get fraction
$qo->fraction = $question['#']['answer'][0]['#']['fraction'][0]['#'];
// handle answer
$answer = $question['#']['answer'][0];
// get fraction - <fraction> tag is deprecated
if (!empty($answer['#']['fraction'][0]['#'])) {
$qo->fraction = $answer['#']['fraction'][0]['#'];
}
else {
$qo->fraction = $answer['@']['fraction'] / 100;
}
return $qo;
}
function import_calculated( $question ) {
// import numerical question
// get common parts
$qo = $this->import_headers( $question );
// header parts particular to numerical
$qo->qtype = CALCULATED ;//CALCULATED;
// get answers array
$answers = $question['#']['answer'];
$qo->answers = array();
$qo->feedback = array();
$qo->fraction = array();
$qo->tolerance = array();
$qo->tolerancetype = array();
$qo->correctanswerformat = array();
$qo->correctanswerlength = array();
$qo->feedback = array();
foreach ($answers as $answer) {
// answer outside of <text> is deprecated
if (!empty( $answer['#']['text'] )) {
$answertext = $this->import_text( $answer['#']['text'] );
}
else {
$answertext = trim($answer['#'][0]);
}
if ($answertext == '') {
$qo->answers[] = '*';
} else {
$qo->answers[] = $answertext;
}
$qo->feedback[] = $this->import_text( $answer['#']['feedback'][0]['#']['text'] );
$qo->tolerance[] = $answer['#']['tolerance'][0]['#'];
// fraction as a tag is deprecated
if (!empty($answer['#']['fraction'][0]['#'])) {
$qo->fraction[] = $answer['#']['fraction'][0]['#'];
}
else {
$qo->fraction[] = $answer['@']['fraction'] / 100;
}
$qo->tolerancetype[] = $answer['#']['tolerancetype'][0]['#'];
$qo->correctanswerformat[] = $answer['#']['correctanswerformat'][0]['#'];
$qo->correctanswerlength[] = $answer['#']['correctanswerlength'][0]['#'];
}
// get units array
$qo->unit = array();
if (isset($question['#']['units'][0]['#']['unit'])) {
$units = $question['#']['units'][0]['#']['unit'];
$qo->multiplier = array();
foreach ($units as $unit) {
$qo->multiplier[] = $unit['#']['multiplier'][0]['#'];
$qo->unit[] = $unit['#']['unit_name'][0]['#'];
}
}
$datasets = $question['#']['dataset_definitions'][0]['#']['dataset_definition'];
$qo->dataset = array();
$qo->datasetindex= 0 ;
foreach ($datasets as $dataset) {
$qo->datasetindex++;
$qo->dataset[$qo->datasetindex] = new stdClass();
$qo->dataset[$qo->datasetindex]->status = $this->import_text( $dataset['#']['status'][0]['#']['text']);
$qo->dataset[$qo->datasetindex]->name = $this->import_text( $dataset['#']['name'][0]['#']['text']);
$qo->dataset[$qo->datasetindex]->type = $dataset['#']['type'][0]['#'];
$qo->dataset[$qo->datasetindex]->distribution = $this->import_text( $dataset['#']['distribution'][0]['#']['text']);
$qo->dataset[$qo->datasetindex]->max = $this->import_text( $dataset['#']['maximum'][0]['#']['text']);
$qo->dataset[$qo->datasetindex]->min = $this->import_text( $dataset['#']['minimum'][0]['#']['text']);
$qo->dataset[$qo->datasetindex]->length = $this->import_text( $dataset['#']['decimals'][0]['#']['text']);
$qo->dataset[$qo->datasetindex]->distribution = $this->import_text( $dataset['#']['distribution'][0]['#']['text']);
$qo->dataset[$qo->datasetindex]->itemcount = $dataset['#']['itemcount'][0]['#'];
$qo->dataset[$qo->datasetindex]->datasetitem = array();
$qo->dataset[$qo->datasetindex]->itemindex = 0;
$qo->dataset[$qo->datasetindex]->number_of_items=$dataset['#']['number_of_items'][0]['#'];
$datasetitems = $dataset['#']['dataset_items'][0]['#']['dataset_item'];
foreach ($datasetitems as $datasetitem) {
$qo->dataset[$qo->datasetindex]->itemindex++;
$qo->dataset[$qo->datasetindex]->datasetitem[$qo->dataset[$qo->datasetindex]->itemindex] = new stdClass();
$qo->dataset[$qo->datasetindex]->datasetitem[$qo->dataset[$qo->datasetindex]->itemindex]->itemnumber = $datasetitem['#']['number'][0]['#']; //[0]['#']['number'][0]['#'] ; // [0]['numberitems'] ;//['#']['number'][0]['#'];// $datasetitems['#']['number'][0]['#'];
$qo->dataset[$qo->datasetindex]->datasetitem[$qo->dataset[$qo->datasetindex]->itemindex]->value = $datasetitem['#']['value'][0]['#'] ;//$datasetitem['#']['value'][0]['#'];
}
}
// echo "<pre>loaded qo";print_r($qo);echo "</pre>";
return $qo;
}
@@ -439,6 +539,9 @@ class qformat_xml extends qformat_default {
elseif ($question_type=='essay') {
$qo = $this->import_essay( $question );
}
elseif ($question_type=='calculated') {
$qo = $this->import_calculated( $question );
}
else {
$notsupported = get_string( 'xmltypeunsupported','quiz',$question_type );
echo "<p>$notsupported</p>";
@@ -499,6 +602,9 @@ class qformat_xml extends qformat_default {
case ESSAY:
$name = 'essay';
break;
case CALCULATED:
$name = 'calculated';
break;
default:
$name = 'unknown';
}
@@ -764,6 +870,67 @@ class qformat_xml extends qformat_default {
$expout .= "</answer>\n";
}
break;
case CALCULATED:
foreach ($question->options->answers as $answer) {
$tolerance = $answer->tolerance;
$tolerancetype = $answer->tolerancetype;
$correctanswerlength= $answer->correctanswerlength ;
$correctanswerformat= $answer->correctanswerformat;
$percent = 100 * $answer->fraction;
$expout .= "<answer fraction=\"$percent\">\n";
// "<text/>" tags are an added feature, old files won't have them
$expout .= " <text>{$answer->answer}</text>\n";
$expout .= " <tolerance>$tolerance</tolerance>\n";
$expout .= " <tolerancetype>$tolerancetype</tolerancetype>\n";
$expout .= " <correctanswerformat>$correctanswerformat</correctanswerformat>\n";
$expout .= " <correctanswerlength>$correctanswerformat</correctanswerlength>\n";
$expout .= " <feedback>".$this->writetext( $answer->feedback )."</feedback>\n";
$expout .= "</answer>\n";
}
$units = $question->options->units;
if (count($units)) {
$expout .= "<units>\n";
foreach ($units as $unit) {
$expout .= " <unit>\n";
$expout .= " <multiplier>{$unit->multiplier}</multiplier>\n";
$expout .= " <unit_name>{$unit->unit}</unit_name>\n";
$expout .= " </unit>\n";
}
$expout .= "</units>\n";
}
//echo "<pre> question calc";print_r($question);echo "</pre>";
//First, we a new function to get all the data itmes in the database
// $question_datasetdefs =$QTYPES['calculated']->get_datasets_for_export ($question);
// echo "<pre> question defs";print_r($question_datasetdefs);echo "</pre>";
//If there are question_datasets
if( isset($question->options->datasets)&&count($question->options->datasets)){// there should be
$expout .= "<dataset_definitions>\n";
foreach ($question->options->datasets as $def) {
$expout .= "<dataset_definition>\n";
$expout .= " <status>".$this->writetext($def->status)."</status>\n";
$expout .= " <name>".$this->writetext($def->name)."</name>\n";
$expout .= " <type>calculated</type>\n";
$expout .= " <distribution>".$this->writetext($def->distribution)."</distribution>\n";
$expout .= " <minimum>".$this->writetext($def->minimum)."</minimum>\n";
$expout .= " <maximum>".$this->writetext($def->maximum)."</maximum>\n";
$expout .= " <decimals>".$this->writetext($def->decimals)."</decimals>\n";
$expout .= " <itemcount>$def->itemcount</itemcount>\n";
if ($def->itemcount > 0 ) {
$expout .= " <dataset_items>\n";
foreach ($def->items as $item ){
$expout .= " <dataset_item>\n";
$expout .= " <number>".$item->itemnumber."</number>\n";
$expout .= " <value>".$item->value."</value>\n";
$expout .= " </dataset_item>\n";
}
$expout .= " </dataset_items>\n";
$expout .= " <number_of_items>".$def-> number_of_items."</number_of_items>\n";
}
$expout .= "</dataset_definition>\n";
}
$expout .= "</dataset_definitions>\n";
}
break;
default:
$expout .= "<!-- Question type is unknown or not supported (Type=$question->qtype) -->\n";