14e31fa3 |
1 | <?php |
f5565b69 |
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 |
aeb15530 |
5 | // deductions are currently simply found by dividing the award for the incorrect |
f5565b69 |
6 | // answer by the total number of options |
7 | // Based on format.php, included by ../../import.php |
41a89a07 |
8 | /** |
9 | * @package questionbank |
10 | * @subpackage importexport |
11 | */ |
f5565b69 |
12 | |
13 | class qformat_learnwise extends qformat_default { |
14 | |
15 | function provide_import() { |
16 | return true; |
17 | } |
18 | |
19 | function readquestions($lines) { |
20 | $questions = array(); |
21 | $currentquestion = array(); |
2befe778 |
22 | |
f5565b69 |
23 | foreach($lines as $line) { |
24 | $line = trim($line); |
25 | $currentquestion[] = $line; |
2befe778 |
26 | |
f5565b69 |
27 | if ($question = $this->readquestion($currentquestion)) { |
28 | $questions[] = $question; |
29 | $currentquestion = array(); |
30 | } |
2befe778 |
31 | } |
f5565b69 |
32 | return $questions; |
33 | } |
34 | |
35 | function readquestion($lines) { |
36 | $text = implode(' ', $lines); |
37 | $text = str_replace(array('\t','\n','\r','\''), array('','','','\\\''), $text); |
38 | |
39 | $startpos = strpos($text, '<question type'); |
40 | $endpos = strpos($text, '</question>'); |
41 | if ($startpos === false || $endpos === false) { |
42 | return false; |
43 | } |
44 | |
45 | preg_match("/<question type=[\"\']([^\"\']+)[\"\']>/i", $text, $matches); |
46 | $type = strtolower($matches[1]); // multichoice or multianswerchoice |
47 | |
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>'); |
52 | |
53 | $optionlist = explode('<option', $optionlist); |
54 | |
55 | $n = 0; |
56 | |
57 | $optionscorrect = array(); |
58 | $optionstext = array(); |
59 | |
60 | if ($type == 'multichoice') { |
61 | foreach ($optionlist as $option) { |
62 | $correct = $this->stringbetween($option, ' correct="', '">'); |
63 | $answer = $this->stringbetween($option, '">', '</option>'); |
aeb15530 |
64 | $optionscorrect[$n] = $correct; |
f5565b69 |
65 | $optionstext[$n] = $this->unhtmlentities($answer); |
66 | ++$n; |
67 | } |
68 | } else if ($type == 'multianswerchoice') { |
69 | $numcorrect = 0; |
70 | $totalaward = 0; |
71 | |
72 | $optionsaward = array(); |
73 | |
74 | foreach ($optionlist as $option) { |
75 | preg_match("/correct=\"([^\"]*)\"/i", $option, $correctmatch); |
76 | preg_match("/award=\"([^\"]*)\"/i", $option, $awardmatch); |
77 | |
78 | $correct = $correctmatch[1]; |
79 | $award = $awardmatch[1]; |
80 | if ($correct == 'yes') { |
81 | $totalaward += $award; |
82 | ++$numcorrect; |
83 | } |
84 | |
85 | $answer = $this->stringbetween($option, '">', '</option>'); |
86 | |
aeb15530 |
87 | $optionscorrect[$n] = $correct; |
f5565b69 |
88 | $optionstext[$n] = $this->unhtmlentities($answer); |
89 | $optionsaward[$n] = $award; |
90 | ++$n; |
91 | } |
92 | |
93 | } else { |
94 | echo "<p>I don't understand this question type (type = <strong>$type</strong>).</p>\n"; |
95 | } |
96 | |
97 | $question = $this->defaultquestion(); |
98 | $question->qtype = MULTICHOICE; |
99 | $question->name = substr($questiontext, 0, 30); |
100 | if (strlen($questiontext) > 30) { |
101 | $question->name .= '...'; |
102 | } |
103 | |
104 | $question->questiontext = $questiontext; |
105 | $question->single = ($type == 'multichoice') ? 1 : 0; |
106 | $question->feedback[] = ''; |
2befe778 |
107 | |
f5565b69 |
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') { |
aeb15530 |
114 | $fraction = (int) $questionaward; |
f5565b69 |
115 | } else { |
116 | $fraction = 0; |
aeb15530 |
117 | } |
f5565b69 |
118 | } else { // mulitple answers |
119 | if ($optionscorrect[$n] == 'yes') { |
aeb15530 |
120 | $fraction = $optionsaward[$n] / $totalaward; |
f5565b69 |
121 | } else { |
122 | $fraction = -$optionsaward[$n] / count($optionstext); |
123 | } |
124 | } |
125 | $question->fraction[] = $fraction; |
126 | $question->answer[] = $optionstext[$n]; |
127 | $question->feedback[] = ''; // no feedback in this type |
128 | } |
129 | } |
130 | |
131 | return $question; |
132 | } |
133 | |
134 | function stringbetween($text, $start, $end) { |
135 | $startpos = strpos($text, $start) + strlen($start); |
136 | $endpos = strpos($text, $end); |
2befe778 |
137 | |
f5565b69 |
138 | if ($startpos <= $endpos) { |
139 | return substr($text, $startpos, $endpos - $startpos); |
140 | } |
141 | } |
142 | |
143 | function unhtmlentities($string) { |
144 | $transtable = get_html_translation_table(HTML_ENTITIES); |
145 | $transtable = array_flip($transtable); |
146 | return strtr($string, $transtable); |
aeb15530 |
147 | } |
f5565b69 |
148 | |
149 | } |
150 | |
aeb15530 |
151 | |