-<?PHP // $Id$ \r
-// Alton College, Hampshire, UK - Tom Flannaghan\r
-// Imports learnwise multiple choice quizzes\r
+<?php // $Id$ \r
+// Alton College, Hampshire, UK - Tom Flannaghan, Andrew Walker\r
+// Imports learnwise multiple choice quizzes (single and multiple answers)\r
+// currently ignores the deduct attribute for multiple answer questions\r
+// deductions are currently simply found by dividing the award for the incorrect \r
+// answer by the total number of options\r
// Based on format.php, included by ../../import.php\r
\r
-function string_between($text, $start, $end)\r
-{\r
- $startpos = strpos($text, $start) + strlen($start);\r
- $endpos = strpos($text, $end);\r
- \r
- if($startpos <= $endpos) return substr($text, $startpos, $endpos - $startpos);\r
-}\r
- \r
- \r
-\r
class quiz_file_format extends quiz_default_format {\r
\r
- function readquestions($lines) {\r
+ function readquestions($lines) {\r
$questions = array();\r
$currentquestion = array();\r
\r
- foreach($lines as $line) {\r
- $line = trim($line);\r
- $currentquestion[] = $line;\r
+ foreach($lines as $line) {\r
+ $line = trim($line);\r
+ $currentquestion[] = $line;\r
\r
- if($question = $this->readquestion($currentquestion)) {\r
- $questions[] = $question;\r
- $currentquestion = array();\r
- }\r
- }\r
- \r
- return $questions;\r
- }\r
-\r
- function unhtmlentities($string)\r
- // puts all the > etc stuff back to 'normal' \r
- // good for PHP 4.1.0 on\r
- {\r
- $trans_tbl = get_html_translation_table(HTML_ENTITIES);\r
- $trans_tbl = array_flip($trans_tbl);\r
- return strtr($string, $trans_tbl);\r
- }\r
+ if ($question = $this->readquestion($currentquestion)) {\r
+ $questions[] = $question;\r
+ $currentquestion = array();\r
+ }\r
+ } \r
+ return $questions;\r
+ }\r
\r
function readquestion($lines) {\r
- $text = '';\r
- foreach ($lines as $line) $text .= $line;\r
- $text = str_replace(array('\t','\n','\r','\''), array('','','','\\\''), $text);\r
- $len = strlen($text);\r
-\r
- $question = NULL;\r
-\r
- if($questiontype = sscanf($text, '<question type="%s">'))\r
- {\r
- if($pos = stripos($text, '</question>'))\r
- {\r
- $text = substr($text, 0, $pos);\r
- $text = stristr($text, '<question');\r
- \r
- $questiontext = '';\r
- $questionaward = '';\r
- $questionhint = '';\r
- $optionlist = '';\r
- $questiontext = string_between($text, '<text>', '</text>');\r
- $questionaward = string_between($text, '<award>', '</award>');\r
- $questionhint = string_between($text, '<hint>', '</hint>');\r
- $optionlist = string_between($text, '<answer>', '</answer>');\r
- \r
- $optionlist = explode('<option', $optionlist);\r
- $n=0;\r
- \r
- foreach($optionlist as $option)\r
- {\r
- $a = string_between($option, ' correct="', '">');\r
- $b = string_between($option, '">', '</option>');\r
- \r
- $options_correct[$n] = $a; $options_text[$n] = $b;\r
- //echo "$a, $b<br>";\r
- $n++;\r
- \r
- }\r
- \r
- $question->qtype = MULTICHOICE;\r
- $question->name = substr($this->unhtmlentities($questiontext),0,30);\r
- if(strlen($questionlen)<30) $question->name .= '...';\r
- $question->questiontext = $this->unhtmlentities($questiontext);\r
- $question->single = 1;\r
- $question->feedback[] = '';\r
- $question->usecase = 0;\r
- $question->defaultgrade = 1;\r
- $question->image = '';\r
- \r
- for($n=0; $n<sizeof($options_text); $n++)\r
- {\r
- if($options_text[$n])\r
- {\r
- if($options_correct[$n]=='yes') $fraction = (int) $questionaward; else $fraction = 0;\r
- $question->fraction[] = $fraction;\r
- $question->answer[] = $this->unhtmlentities($options_text[$n]);\r
- //echo "hello: $options_text[$n], $fraction<br>";\r
- }\r
- }\r
- }\r
- }\r
- \r
+ $text = implode(' ', $lines);\r
+ $text = str_replace(array('\t','\n','\r','\''), array('','','','\\\''), $text);\r
+\r
+ $startpos = strpos($text, '<question type');\r
+ $endpos = strpos($text, '</question>');\r
+ if ($startpos === false || $endpos === false) {\r
+ return false;\r
+ }\r
+\r
+ preg_match("/<question type=[\"\']([^\"\']+)[\"\']>/i", $text, $matches);\r
+ $type = strtolower($matches[1]); // multichoice or multianswerchoice\r
+\r
+ $questiontext = $this->unhtmlentities($this->stringbetween($text, '<text>', '</text>'));\r
+ $questionhint = $this->unhtmlentities($this->stringbetween($text, '<hint>', '</hint>'));\r
+ $questionaward = $this->stringbetween($text, '<award>', '</award>');\r
+ $optionlist = $this->stringbetween($text, '<answer>', '</answer>');\r
+\r
+ $optionlist = explode('<option', $optionlist);\r
+\r
+ $n = 0;\r
+\r
+ $optionscorrect = array();\r
+ $optionstext = array();\r
+\r
+ if ($type == 'multichoice') {\r
+ foreach ($optionlist as $option) {\r
+ $correct = $this->stringbetween($option, ' correct="', '">');\r
+ $answer = $this->stringbetween($option, '">', '</option>');\r
+ $optionscorrect[$n] = $correct; \r
+ $optionstext[$n] = $this->unhtmlentities($answer);\r
+ ++$n;\r
+ }\r
+ } else if ($type == 'multianswerchoice') {\r
+ $numcorrect = 0;\r
+ $totalaward = 0;\r
+\r
+ $optionsaward = array();\r
+\r
+ foreach ($optionlist as $option) {\r
+ preg_match("/correct=\"([^\"]*)\"/i", $option, $correctmatch);\r
+ preg_match("/award=\"([^\"]*)\"/i", $option, $awardmatch);\r
+\r
+ $correct = $correctmatch[1];\r
+ $award = $awardmatch[1];\r
+ if ($correct == 'yes') {\r
+ $totalaward += $award;\r
+ ++$numcorrect;\r
+ }\r
+\r
+ $answer = $this->stringbetween($option, '">', '</option>');\r
+\r
+ $optionscorrect[$n] = $correct; \r
+ $optionstext[$n] = $this->unhtmlentities($answer);\r
+ $optionsaward[$n] = $award;\r
+ ++$n;\r
+ }\r
+\r
+ } else {\r
+ echo "<p>I don't understand this question type (type = <strong>$type</strong>).</p>\n";\r
+ }\r
+\r
+ $question->qtype = MULTICHOICE;\r
+ $question->name = substr($questiontext, 0, 30);\r
+ if (strlen($questiontext) > 30) {\r
+ $question->name .= '...';\r
+ }\r
+\r
+ $question->questiontext = $questiontext;\r
+ $question->single = ($type == 'multichoice') ? 1 : 0;\r
+ $question->feedback[] = '';\r
+ $question->usecase = 0;\r
+ $question->defaultgrade = 1;\r
+ $question->image = '';\r
+ \r
+ $question->fraction = array();\r
+ $question->answer = array();\r
+ for ($n = 0; $n < count($optionstext); ++$n) {\r
+ if ($optionstext[$n]) {\r
+ if (!isset($numcorrect)) { // single answer\r
+ if ($optionscorrect[$n] == 'yes') {\r
+ $fraction = (int) $questionaward; \r
+ } else {\r
+ $fraction = 0;\r
+ } \r
+ } else { // mulitple answers\r
+ if ($optionscorrect[$n] == 'yes') {\r
+ $fraction = $optionsaward[$n] / $totalaward; \r
+ } else {\r
+ $fraction = -$optionsaward[$n] / count($optionstext);\r
+ }\r
+ }\r
+ $question->fraction[] = $fraction;\r
+ $question->answer[] = $optionstext[$n];\r
+ }\r
+ }\r
+\r
return $question;\r
}\r
+\r
+ function stringbetween($text, $start, $end) {\r
+ $startpos = strpos($text, $start) + strlen($start);\r
+ $endpos = strpos($text, $end);\r
+ \r
+ if ($startpos <= $endpos) {\r
+ return substr($text, $startpos, $endpos - $startpos);\r
+ }\r
+ }\r
+\r
+ function unhtmlentities($string) {\r
+ $transtable = get_html_translation_table(HTML_ENTITIES);\r
+ $transtable = array_flip($transtable);\r
+ return strtr($string, $transtable);\r
+ } \r
+\r
}\r
\r
?>\r