fixed addStopFieldsetElements of submitbutton
[moodle.git] / question / format / examview / format.php
CommitLineData
84769fd8 1<?php // $Id$
84769fd8 2
3// Based on default.php, included by ../import.php
4
5require_once("$CFG->libdir/xmlize.php");
84769fd8 6
7/*
8define("SHORTANSWER", "1");
9define("TRUEFALSE", "2");
10define("MULTICHOICE", "3");
11define("MATCH", "5");
12define("DESCRIPTION", "7");
13define("NUMERICAL", "8");
14define("MULTIANSWER", "9");
15define("CALCULATED", "10");
16*/
17
f5565b69 18class qformat_examview extends qformat_default {
84769fd8 19
20 var $qtypes = array('tf' => TRUEFALSE,
21 'mc' => MULTICHOICE,
22 'yn' => TRUEFALSE,
23 'co' => SHORTANSWER,
24 'ma' => MATCH,
25 'mtf' => 99,
26 'nr' => NUMERICAL,
27 'pr' => 99,
28 'es' => 99,
29 'ca' => 99,
30 'ot' => 99
31 );
32
33 var $matching_questions = array();
34
35 function provide_import() {
36 return true;
37 }
38
0b3940f8 39 /**
40 * unxmlise reconstructs part of the xml data structure in order
41 * to identify the actual data therein
42 * @param array $xml section of the xml data structure
43 * @return string data with evrything else removed
44 */
45 function unxmlise( $xml ) {
46 // if it's not an array then it's probably just data
47 if (!is_array($xml)) {
48 $text = s(addslashes($xml));
49 }
50 else {
51 // otherwise parse the array
52 $text = '';
53 foreach ($xml as $tag=>$data) {
54 // if tag is '@' then it's attributes and we don't care
55 if ($tag!=='@') {
56 $text = $text . $this->unxmlise( $data );
57 }
84769fd8 58 }
84769fd8 59 }
0b3940f8 60
61 // currently we throw the tags we found
62 $text = strip_tags($text);
63 return $text;
84769fd8 64 }
65
66 function parse_matching_groups($matching_groups)
67 {
68 if (empty($matching_groups)) {
69 return;
70 }
71 foreach($matching_groups as $match_group) {
72 $newgroup = NULL;
73 $groupname = trim($match_group['@']['name']);
0b3940f8 74 $questiontext = $this->unxmlise($match_group['#']['text'][0]['#']);
84769fd8 75 $newgroup->questiontext = trim($questiontext);
76 $newgroup->subchoices = array();
77 $newgroup->subquestions = array();
78 $newgroup->subanswers = array();
79 $choices = $match_group['#']['choices']['0']['#'];
80 foreach($choices as $key => $value) {
81 if (strpos(trim($key),'choice-') !== FALSE) {
82 $key = strtoupper(trim(str_replace('choice-', '', $key)));
83 $newgroup->subchoices[$key] = trim($value['0']['#']);
84 }
85 }
86 $this->matching_questions[$groupname] = $newgroup;
87 }
88 }
89
90 function parse_ma($qrec, $groupname)
91 {
92 $match_group = $this->matching_questions[$groupname];
0b3940f8 93 $phrase = trim($this->unxmlise($qrec['text']['0']['#']));
94 $answer = trim($this->unxmlise($qrec['answer']['0']['#']));
95 $answer = strip_tags( $answer );
84769fd8 96 $match_group->subquestions[] = $phrase;
97 $match_group->subanswers[] = $match_group->subchoices[$answer];
98 $this->matching_questions[$groupname] = $match_group;
99 return NULL;
100 }
101
102 function process_matches(&$questions)
103 {
104 if (empty($this->matching_questions)) {
105 return;
106 }
107 foreach($this->matching_questions as $match_group) {
108 $question = $this->defaultquestion();
a60b5c16 109 $htmltext = s(addslashes($match_group->questiontext));
84769fd8 110 $question->questiontext = $htmltext;
111 $question->name = $question->questiontext;
112 $question->qtype = MATCH;
84769fd8 113 $question->subquestions = array();
114 $question->subanswers = array();
115 foreach($match_group->subquestions as $key => $value) {
0b3940f8 116 $htmltext = s(addslashes($value));
84769fd8 117 $question->subquestions[] = $htmltext;
118
a60b5c16 119 $htmltext = s(addslashes($match_group->subanswers[$key]));
84769fd8 120 $question->subanswers[] = $htmltext;
121 }
122 $questions[] = $question;
123 }
124 }
125
2befe778 126 function cleanUnicode($text) {
2befe778 127 return str_replace('&#x2019;', "'", $text);
128 }
06968068 129
130 function readquestions($lines) {
84769fd8 131 /// Parses an array of lines into an array of questions,
132 /// where each item is a question object as defined by
133 /// readquestion().
06968068 134
84769fd8 135 $questions = array();
136 $currentquestion = array();
137
138 $text = implode($lines, ' ');
2befe778 139 $text = $this->cleanUnicode($text);
84769fd8 140
141 $xml = xmlize($text, 0);
06968068 142 if (!empty($xml['examview']['#']['matching-group'])) {
143 $this->parse_matching_groups($xml['examview']['#']['matching-group']);
144 }
84769fd8 145
146 $questionNode = $xml['examview']['#']['question'];
147 foreach($questionNode as $currentquestion) {
148 if ($question = $this->readquestion($currentquestion)) {
149 $questions[] = $question;
150 }
151 }
152
84769fd8 153 $this->process_matches($questions);
84769fd8 154 return $questions;
155 }
156 // end readquestions
157
84769fd8 158 function readquestion($qrec)
159 {
160
161 $type = trim($qrec['@']['type']);
162 $question = $this->defaultquestion();
a60b5c16 163 if (array_key_exists($type, $this->qtypes)) {
164 $question->qtype = $this->qtypes[$type];
165 }
166 else {
167 $question->qtype = null;
168 }
84769fd8 169 $question->single = 1;
170 // Only one answer is allowed
0b3940f8 171 $htmltext = $this->unxmlise($qrec['#']['text'][0]['#']);
84769fd8 172 $question->questiontext = $htmltext;
173 $question->name = $question->questiontext;
174
175 switch ($question->qtype) {
176 case MULTICHOICE:
177 $question = $this->parse_mc($qrec['#'], $question);
178 break;
179 case MATCH:
180 $groupname = trim($qrec['@']['group']);
181 $question = $this->parse_ma($qrec['#'], $groupname);
182 break;
183 case TRUEFALSE:
184 $question = $this->parse_tf_yn($qrec['#'], $question);
185 break;
186 case SHORTANSWER:
187 $question = $this->parse_co($qrec['#'], $question);
188 break;
189 case NUMERICAL:
190 $question = $this->parse_nr($qrec['#'], $question);
191 break;
192 break;
193 default:
194 print("<p>Question type ".$type." import not supported for ".$question->questiontext."<p>");
195 $question = NULL;
196 }
197 // end switch ($question->qtype)
198
199 return $question;
200 }
201 // end readquestion
202
203 function parse_tf_yn($qrec, $question)
204 {
205 $choices = array('T' => 1, 'Y' => 1, 'F' => 0, 'N' => 0 );
206 $answer = trim($qrec['answer'][0]['#']);
207 $question->answer = $choices[$answer];
208 if ($question->answer == 1) {
209 $question->feedbacktrue = 'Correct';
210 $question->feedbackfalse = 'Incorrect';
211 } else {
212 $question->feedbacktrue = 'Incorrect';
213 $question->feedbackfalse = 'Correct';
214 }
215 return $question;
216 }
217
218 function parse_mc($qrec, $question)
219 {
220 $answer = 'choice-'.strtolower(trim($qrec['answer'][0]['#']));
221
222 $choices = $qrec['choices'][0]['#'];
223 foreach($choices as $key => $value) {
224 if (strpos(trim($key),'choice-') !== FALSE) {
0b3940f8 225
226 $question->answer[$key] = s($this->unxmlise($value[0]['#']));
84769fd8 227 if (strcmp($key, $answer) == 0) {
228 $question->fraction[$key] = 1;
229 $question->feedback[$key] = 'Correct';
230 } else {
231 $question->fraction[$key] = 0;
232 $question->feedback[$key] = 'Incorrect';
233 }
234 }
235 }
236 return $question;
237 }
238
239 function parse_co($qrec, $question)
240 {
241 $question->usecase = 0;
0b3940f8 242 $answer = trim($this->unxmlise($qrec['answer'][0]['#']));
243 $answer = strip_tags( $answer );
84769fd8 244 $answers = explode("\n",$answer);
245
246 foreach($answers as $key => $value) {
247 $value = trim($value);
248 if (strlen($value) > 0) {
249 $question->answer[$key] = addslashes($value);
250 $question->fraction[$key] = 1;
251 $question->feedback[$key] = "Correct";
252 }
253 }
254 return $question;
255 }
256
257 function parse_nr($qrec, $question)
258 {
0b3940f8 259 $answer = trim($this->unxmlise($qrec['answer'][0]['#']));
260 $answer = strip_tags( $answer );
84769fd8 261 $answers = explode("\n",$answer);
262
263 foreach($answers as $key => $value) {
264 $value = trim($value);
265 if (is_numeric($value)) {
266 $errormargin = 0;
267 $question->answer[$key] = $value;
268 $question->fraction[$key] = 1;
269 $question->feedback[$key] = "Correct";
270 $question->min[$key] = $question->answer[$key] - $errormargin;
271 $question->max[$key] = $question->answer[$key] + $errormargin;
272 }
273 }
274 return $question;
275 }
276
277}
278// end class
279
280?>