2 // Alton College, Hampshire, UK - Tom Flannaghan, Andrew Walker
3 // Imports learnwise multiple choice quizzes (single and multiple answers)
4 // currently ignores the deduct attribute for multiple answer questions
5 // deductions are currently simply found by dividing the award for the incorrect
6 // answer by the total number of options
7 // Based on format.php, included by ../../import.php
9 * @package questionbank
10 * @subpackage importexport
13 class qformat_learnwise
extends qformat_default
{
15 function provide_import() {
19 function readquestions($lines) {
21 $currentquestion = array();
23 foreach($lines as $line) {
25 $currentquestion[] = $line;
27 if ($question = $this->readquestion($currentquestion)) {
28 $questions[] = $question;
29 $currentquestion = array();
35 function readquestion($lines) {
36 $text = implode(' ', $lines);
37 $text = str_replace(array('\t','\n','\r','\''), array('','','','\\\''), $text);
39 $startpos = strpos($text, '<question type');
40 $endpos = strpos($text, '</question>');
41 if ($startpos === false ||
$endpos === false) {
45 preg_match("/<question type=[\"\']([^\"\']+)[\"\']>/i", $text, $matches);
46 $type = strtolower($matches[1]); // multichoice or multianswerchoice
48 $questiontext = $this->unhtmlentities($this->stringbetween($text, '<text>', '</text>'));
49 $questionhint = $this->unhtmlentities($this->stringbetween($text, '<hint>', '</hint>'));
50 $questionaward = $this->stringbetween($text, '<award>', '</award>');
51 $optionlist = $this->stringbetween($text, '<answer>', '</answer>');
53 $optionlist = explode('<option', $optionlist);
57 $optionscorrect = array();
58 $optionstext = array();
60 if ($type == 'multichoice') {
61 foreach ($optionlist as $option) {
62 $correct = $this->stringbetween($option, ' correct="', '">');
63 $answer = $this->stringbetween($option, '">', '</option>');
64 $optionscorrect[$n] = $correct;
65 $optionstext[$n] = $this->unhtmlentities($answer);
68 } else if ($type == 'multianswerchoice') {
72 $optionsaward = array();
74 foreach ($optionlist as $option) {
75 preg_match("/correct=\"([^\"]*)\"/i", $option, $correctmatch);
76 preg_match("/award=\"([^\"]*)\"/i", $option, $awardmatch);
78 $correct = $correctmatch[1];
79 $award = $awardmatch[1];
80 if ($correct == 'yes') {
81 $totalaward +
= $award;
85 $answer = $this->stringbetween($option, '">', '</option>');
87 $optionscorrect[$n] = $correct;
88 $optionstext[$n] = $this->unhtmlentities($answer);
89 $optionsaward[$n] = $award;
94 echo "<p>I don't understand this question type (type = <strong>$type</strong>).</p>\n";
97 $question = $this->defaultquestion();
98 $question->qtype
= MULTICHOICE
;
99 $question->name
= substr($questiontext, 0, 30);
100 if (strlen($questiontext) > 30) {
101 $question->name
.= '...';
104 $question->questiontext
= $questiontext;
105 $question->single
= ($type == 'multichoice') ?
1 : 0;
106 $question->feedback
[] = '';
108 $question->fraction
= array();
109 $question->answer
= array();
110 for ($n = 0; $n < count($optionstext); ++
$n) {
111 if ($optionstext[$n]) {
112 if (!isset($numcorrect)) { // single answer
113 if ($optionscorrect[$n] == 'yes') {
114 $fraction = (int) $questionaward;
118 } else { // mulitple answers
119 if ($optionscorrect[$n] == 'yes') {
120 $fraction = $optionsaward[$n] / $totalaward;
122 $fraction = -$optionsaward[$n] / count($optionstext);
125 $question->fraction
[] = $fraction;
126 $question->answer
[] = $optionstext[$n];
127 $question->feedback
[] = ''; // no feedback in this type
134 function stringbetween($text, $start, $end) {
135 $startpos = strpos($text, $start) +
strlen($start);
136 $endpos = strpos($text, $end);
138 if ($startpos <= $endpos) {
139 return substr($text, $startpos, $endpos - $startpos);
143 function unhtmlentities($string) {
144 $transtable = get_html_translation_table(HTML_ENTITIES
);
145 $transtable = array_flip($transtable);
146 return strtr($string, $transtable);