516cf3eb |
1 | <?php // $Id$ |
2 | |
3 | ///////////// |
4 | /// MATCH /// |
5 | ///////////// |
6 | |
7 | /// QUESTION TYPE CLASS ////////////////// |
af3830ee |
8 | class question_match_qtype extends default_questiontype { |
516cf3eb |
9 | |
10 | function name() { |
11 | return 'match'; |
12 | } |
13 | |
14 | function get_question_options(&$question) { |
32a189d6 |
15 | $question->options = get_record('question_match', 'question', $question->id); |
16 | $question->options->subquestions = get_records("question_match_sub", "question", $question->id, "id ASC" ); |
516cf3eb |
17 | return true; |
18 | } |
19 | |
20 | function save_question_options($question) { |
a58ffe3f |
21 | $result = new stdClass; |
22 | |
32a189d6 |
23 | if (!$oldsubquestions = get_records("question_match_sub", "question", $question->id, "id ASC")) { |
516cf3eb |
24 | $oldsubquestions = array(); |
25 | } |
26 | |
516cf3eb |
27 | // $subquestions will be an array with subquestion ids |
28 | $subquestions = array(); |
29 | |
30 | // Insert all the new question+answer pairs |
31 | foreach ($question->subquestions as $key => $questiontext) { |
32 | $answertext = $question->subanswers[$key]; |
33 | if (!empty($questiontext) or !empty($answertext)) { |
34 | if ($subquestion = array_shift($oldsubquestions)) { // Existing answer, so reuse it |
35 | $subquestion->questiontext = $questiontext; |
36 | $subquestion->answertext = $answertext; |
32a189d6 |
37 | if (!update_record("question_match_sub", $subquestion)) { |
7518b645 |
38 | $result->error = "Could not insert match subquestion! (id=$subquestion->id)"; |
516cf3eb |
39 | return $result; |
40 | } |
41 | } else { |
a58ffe3f |
42 | $subquestion = new stdClass; |
516cf3eb |
43 | // Determine a unique random code |
44 | $subquestion->code = rand(1,999999999); |
18bd0d68 |
45 | while (record_exists('question_match_sub', 'code', $subquestion->code, 'question', $question->id)) { |
516cf3eb |
46 | $subquestion->code = rand(); |
47 | } |
48 | $subquestion->question = $question->id; |
49 | $subquestion->questiontext = $questiontext; |
50 | $subquestion->answertext = $answertext; |
32a189d6 |
51 | if (!$subquestion->id = insert_record("question_match_sub", $subquestion)) { |
7518b645 |
52 | $result->error = "Could not insert match subquestion!"; |
516cf3eb |
53 | return $result; |
54 | } |
55 | } |
56 | $subquestions[] = $subquestion->id; |
57 | } |
a58ffe3f |
58 | if (!empty($questiontext) && empty($answertext)) { |
59 | $result->notice = get_string('nomatchinganswer', 'quiz', $questiontext); |
60 | } |
516cf3eb |
61 | } |
62 | |
63 | // delete old subquestions records |
64 | if (!empty($oldsubquestions)) { |
65 | foreach($oldsubquestions as $os) { |
32a189d6 |
66 | delete_records('question_match_sub', 'id', $os->id); |
516cf3eb |
67 | } |
68 | } |
69 | |
32a189d6 |
70 | if ($options = get_record("question_match", "question", $question->id)) { |
516cf3eb |
71 | $options->subquestions = implode(",",$subquestions); |
72 | $options->shuffleanswers = $question->shuffleanswers; |
32a189d6 |
73 | if (!update_record("question_match", $options)) { |
7518b645 |
74 | $result->error = "Could not update match options! (id=$options->id)"; |
516cf3eb |
75 | return $result; |
76 | } |
77 | } else { |
78 | unset($options); |
79 | $options->question = $question->id; |
80 | $options->subquestions = implode(",",$subquestions); |
81 | $options->shuffleanswers = $question->shuffleanswers; |
32a189d6 |
82 | if (!insert_record("question_match", $options)) { |
7518b645 |
83 | $result->error = "Could not insert match options!"; |
516cf3eb |
84 | return $result; |
85 | } |
86 | } |
a58ffe3f |
87 | |
88 | if (!empty($result->notice)) { |
89 | return $result; |
90 | } |
91 | |
92 | if (count($subquestions) < 3) { |
93 | $result->notice = get_string('notenoughanswers', 'quiz', 3); |
94 | return $result; |
95 | } |
96 | |
516cf3eb |
97 | return true; |
98 | } |
99 | |
100 | /** |
101 | * Deletes question from the question-type specific tables |
102 | * |
103 | * @return boolean Success/Failure |
104 | * @param integer $question->id |
105 | */ |
90c3f310 |
106 | function delete_question($questionid) { |
107 | delete_records("question_match", "question", $questionid); |
108 | delete_records("question_match_sub", "question", $questionid); |
516cf3eb |
109 | return true; |
110 | } |
111 | |
112 | function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) { |
32a189d6 |
113 | if (!$state->options->subquestions = get_records('question_match_sub', |
00c30069 |
114 | 'question', $question->id)) { |
115 | notify('Error: Missing subquestions!'); |
116 | return false; |
516cf3eb |
117 | } |
118 | |
119 | foreach ($state->options->subquestions as $key => $subquestion) { |
120 | // This seems rather over complicated, but it is useful for the |
121 | // randomsamatch questiontype, which can then inherit the print |
122 | // and grading functions. This way it is possible to define multiple |
123 | // answers per question, each with different marks and feedback. |
124 | $answer = new stdClass(); |
125 | $answer->id = $subquestion->code; |
126 | $answer->answer = $subquestion->answertext; |
127 | $answer->fraction = 1.0; |
128 | $state->options->subquestions[$key]->options |
00c30069 |
129 | ->answers[$subquestion->code] = clone($answer); |
516cf3eb |
130 | |
131 | $state->responses[$key] = ''; |
132 | } |
133 | |
134 | // Shuffle the answers if required |
135 | if ($cmoptions->shuffleanswers and $question->options->shuffleanswers) { |
136 | $state->options->subquestions = swapshuffle_assoc($state->options->subquestions); |
137 | } |
138 | |
139 | return true; |
140 | } |
141 | |
142 | function restore_session_and_responses(&$question, &$state) { |
143 | // The serialized format for matching questions is a comma separated |
144 | // list of question answer pairs (e.g. 1-1,2-3,3-2), where the ids of |
32a189d6 |
145 | // both refer to the id in the table question_match_sub. |
516cf3eb |
146 | $responses = explode(',', $state->responses['']); |
147 | $responses = array_map(create_function('$val', |
148 | 'return explode("-", $val);'), $responses); |
149 | |
32a189d6 |
150 | if (!$questions = get_records('question_match_sub', |
516cf3eb |
151 | 'question', $question->id)) { |
152 | notify('Error: Missing subquestions!'); |
153 | return false; |
154 | } |
155 | |
156 | // Restore the previous responses and place the questions into the state options |
157 | $state->responses = array(); |
158 | $state->options->subquestions = array(); |
159 | foreach ($responses as $response) { |
160 | $state->responses[$response[0]] = $response[1]; |
161 | $state->options->subquestions[$response[0]] = $questions[$response[0]]; |
162 | } |
163 | |
164 | foreach ($state->options->subquestions as $key => $subquestion) { |
165 | // This seems rather over complicated, but it is useful for the |
166 | // randomsamatch questiontype, which can then inherit the print |
167 | // and grading functions. This way it is possible to define multiple |
168 | // answers per question, each with different marks and feedback. |
169 | $answer = new stdClass(); |
170 | $answer->id = $subquestion->code; |
171 | $answer->answer = $subquestion->answertext; |
172 | $answer->fraction = 1.0; |
173 | $state->options->subquestions[$key]->options |
174 | ->answers[$subquestion->code] = clone($answer); |
175 | } |
176 | |
177 | return true; |
178 | } |
179 | |
180 | function save_session_and_responses(&$question, &$state) { |
87ee4968 |
181 | $subquestions = &$state->options->subquestions; |
182 | |
183 | // Prepare an array to help when disambiguating equal answers. |
184 | $answertexts = array(); |
185 | foreach ($subquestions as $subquestion) { |
186 | $ans = reset($subquestion->options->answers); |
187 | $answertexts[$ans->id] = $ans->answer; |
188 | } |
189 | |
516cf3eb |
190 | // Serialize responses |
191 | $responses = array(); |
87ee4968 |
192 | foreach ($subquestions as $key => $subquestion) { |
7d6af8ca |
193 | $response = 0; |
0c24ee0f |
194 | if ($subquestion->questiontext) { |
87ee4968 |
195 | if ($state->responses[$key]) { |
196 | $response = $state->responses[$key]; |
197 | if (!array_key_exists($response, $subquestion->options->answers)) { |
198 | // If studen's answer did not match by id, but there may be |
199 | // two answers with the same text, but different ids, |
200 | // so we need to try matching the answer text. |
201 | $expected_answer = reset($subquestion->options->answers); |
202 | if ($answertexts[$response] == $expected_answer->answer) { |
203 | $response = $expected_answer->id; |
204 | $state->responses[$key] = $response; |
205 | } |
206 | } |
87ee4968 |
207 | } |
0c24ee0f |
208 | } |
7d6af8ca |
209 | $responses[] = $key.'-'.$response; |
516cf3eb |
210 | } |
211 | $responses = implode(',', $responses); |
212 | |
213 | // Set the legacy answer field |
0c24ee0f |
214 | if (!set_field('question_states', 'answer', $responses, 'id', $state->id)) { |
516cf3eb |
215 | return false; |
216 | } |
217 | return true; |
218 | } |
219 | |
220 | function get_correct_responses(&$question, &$state) { |
221 | $responses = array(); |
222 | foreach ($state->options->subquestions as $sub) { |
223 | foreach ($sub->options->answers as $answer) { |
a58ffe3f |
224 | if (1 == $answer->fraction && $sub->questiontext) { |
516cf3eb |
225 | $responses[$sub->id] = $answer->id; |
226 | } |
227 | } |
228 | } |
229 | return empty($responses) ? null : $responses; |
230 | } |
231 | |
232 | function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options) { |
37a12367 |
233 | global $CFG; |
516cf3eb |
234 | $subquestions = $state->options->subquestions; |
235 | $correctanswers = $this->get_correct_responses($question, $state); |
236 | $nameprefix = $question->name_prefix; |
237 | $answers = array(); |
0b4ce29d |
238 | $allanswers = array(); |
87ee4968 |
239 | $answerids = array(); |
516cf3eb |
240 | $responses = &$state->responses; |
241 | |
0b4ce29d |
242 | // Prepare a list of answers, removing duplicates. |
516cf3eb |
243 | foreach ($subquestions as $subquestion) { |
244 | foreach ($subquestion->options->answers as $ans) { |
0b4ce29d |
245 | $allanswers[$ans->id] = $ans->answer; |
87ee4968 |
246 | if (!in_array($ans->answer, $answers)) { |
247 | $answers[$ans->id] = $ans->answer; |
248 | $answerids[$ans->answer] = $ans->id; |
87ee4968 |
249 | } |
516cf3eb |
250 | } |
251 | } |
0b4ce29d |
252 | |
253 | // Fix up the ids of any responses that point the the eliminated duplicates. |
254 | foreach ($responses as $subquestionid => $ignored) { |
255 | if ($responses[$subquestionid]) { |
256 | $responses[$subquestionid] = $answerids[$allanswers[$responses[$subquestionid]]]; |
257 | } |
258 | } |
259 | foreach ($correctanswers as $subquestionid => $ignored) { |
260 | $correctanswers[$subquestionid] = $answerids[$allanswers[$correctanswers[$subquestionid]]]; |
261 | } |
516cf3eb |
262 | |
263 | // Shuffle the answers |
264 | $answers = draw_rand_array($answers, count($answers)); |
265 | |
37a12367 |
266 | // Print formulation |
1b8a7434 |
267 | $questiontext = $this->format_text($question->questiontext, |
268 | $question->questiontextformat, $cmoptions); |
37a12367 |
269 | $image = get_question_image($question, $cmoptions->course); |
516cf3eb |
270 | |
271 | ///// Print the input controls ////// |
516cf3eb |
272 | foreach ($subquestions as $key => $subquestion) { |
a58ffe3f |
273 | if ($subquestion->questiontext) { |
274 | /// Subquestion text: |
275 | $a = new stdClass; |
1b8a7434 |
276 | $a->text = $this->format_text($subquestion->questiontext, |
277 | $question->questiontextformat, $cmoptions); |
2b087056 |
278 | |
a58ffe3f |
279 | /// Drop-down list: |
280 | $menuname = $nameprefix.$subquestion->id; |
281 | $response = isset($state->responses[$subquestion->id]) |
282 | ? $state->responses[$subquestion->id] : '0'; |
2b087056 |
283 | |
284 | $a->class = ' '; |
285 | $a->feedbackimg = ' '; |
286 | |
a58ffe3f |
287 | if ($options->readonly |
2b087056 |
288 | and $options->correct_responses |
289 | and isset($correctanswers[$subquestion->id]) |
290 | and ($correctanswers[$subquestion->id] == $response)) { |
291 | |
292 | $correctresponse = 1; |
a58ffe3f |
293 | } else { |
2b087056 |
294 | $correctresponse = 0; |
295 | } |
296 | |
297 | if ($response) { |
298 | $a->class = question_get_feedback_class($correctresponse); |
299 | $a->feedbackimg = question_get_feedback_image($correctresponse); |
300 | } |
301 | |
302 | $a->control = choose_from_menu($answers, $menuname, $response, 'choose', |
303 | '', 0, true, $options->readonly); |
a58ffe3f |
304 | |
305 | // Neither the editing interface or the database allow to provide |
306 | // fedback for this question type. |
307 | // However (as was pointed out in bug bug 3294) the randomsamatch |
308 | // type which reuses this method can have feedback defined for |
309 | // the wrapped shortanswer questions. |
310 | //if ($options->feedback |
311 | // && !empty($subquestion->options->answers[$responses[$key]]->feedback)) { |
312 | // print_comment($subquestion->options->answers[$responses[$key]]->feedback); |
313 | //} |
2b087056 |
314 | |
a58ffe3f |
315 | $anss[] = $a; |
516cf3eb |
316 | } |
516cf3eb |
317 | } |
aaae75b0 |
318 | include("$CFG->dirroot/question/type/match/display.html"); |
516cf3eb |
319 | } |
320 | |
321 | function grade_responses(&$question, &$state, $cmoptions) { |
322 | $subquestions = &$state->options->subquestions; |
323 | $responses = &$state->responses; |
324 | |
87ee4968 |
325 | // Prepare an array to help when disambiguating equal answers. |
326 | $answertexts = array(); |
327 | foreach ($subquestions as $subquestion) { |
328 | $ans = reset($subquestion->options->answers); |
329 | $answertexts[$ans->id] = $ans->answer; |
330 | } |
331 | |
332 | // Add up the grades from each subquestion. |
516cf3eb |
333 | $sumgrade = 0; |
a58ffe3f |
334 | $totalgrade = 0; |
516cf3eb |
335 | foreach ($subquestions as $key => $sub) { |
a58ffe3f |
336 | if ($sub->questiontext) { |
337 | $totalgrade += 1; |
87ee4968 |
338 | $response = $responses[$key]; |
339 | if ($response && !array_key_exists($response, $sub->options->answers)) { |
340 | // If studen's answer did not match by id, but there may be |
341 | // two answers with the same text, but different ids, |
342 | // so we need to try matching the answer text. |
343 | $expected_answer = reset($sub->options->answers); |
344 | if ($answertexts[$response] == $expected_answer->answer) { |
345 | $response = $expected_answer->id; |
346 | } |
347 | } |
348 | if (array_key_exists($response, $sub->options->answers)) { |
349 | $sumgrade += $sub->options->answers[$response]->fraction; |
a58ffe3f |
350 | } |
516cf3eb |
351 | } |
352 | } |
353 | |
a58ffe3f |
354 | $state->raw_grade = $sumgrade/$totalgrade; |
516cf3eb |
355 | if (empty($state->raw_grade)) { |
356 | $state->raw_grade = 0; |
357 | } |
358 | |
359 | // Make sure we don't assign negative or too high marks |
360 | $state->raw_grade = min(max((float) $state->raw_grade, |
361 | 0.0), 1.0) * $question->maxgrade; |
362 | $state->penalty = $question->penalty * $question->maxgrade; |
363 | |
f30bbcaf |
364 | // mark the state as graded |
365 | $state->event = ($state->event == QUESTION_EVENTCLOSE) ? QUESTION_EVENTCLOSEANDGRADE : QUESTION_EVENTGRADE; |
366 | |
516cf3eb |
367 | return true; |
368 | } |
369 | |
370 | // ULPGC ecastro for stats report |
371 | function get_all_responses($question, $state) { |
974383f9 |
372 | $answers = array(); |
516cf3eb |
373 | if (is_array($question->options->subquestions)) { |
645d7610 |
374 | foreach ($question->options->subquestions as $aid => $answer) { |
375 | if ($answer->questiontext) { |
376 | $r = new stdClass; |
377 | $r->answer = $answer->questiontext . ": " . $answer->answertext; |
378 | $r->credit = 1; |
379 | $answers[$aid] = $r; |
380 | } |
516cf3eb |
381 | } |
516cf3eb |
382 | } |
a58ffe3f |
383 | $result = new stdClass; |
516cf3eb |
384 | $result->id = $question->id; |
385 | $result->responses = $answers; |
386 | return $result; |
387 | } |
388 | |
389 | // ULPGC ecastro |
390 | function get_actual_response($question, $state) { |
01bd54e0 |
391 | $subquestions = &$state->options->subquestions; |
392 | $responses = &$state->responses; |
393 | $results=array(); |
394 | foreach ($subquestions as $key => $sub) { |
395 | foreach ($responses as $ind => $code) { |
396 | if (isset($sub->options->answers[$code])) { |
645d7610 |
397 | $results[$ind] = $subquestions[$ind]->questiontext . ": " . $sub->options->answers[$code]->answer; |
01bd54e0 |
398 | } |
399 | } |
400 | } |
401 | return $results; |
402 | } |
0a5b58af |
403 | |
404 | function response_summary($question, $state, $length=80) { |
405 | // This should almost certainly be overridden |
755bddf1 |
406 | return substr(implode(', ', $this->get_actual_response($question, $state)), 0, $length); |
0a5b58af |
407 | } |
c5d94c41 |
408 | |
409 | /// BACKUP FUNCTIONS //////////////////////////// |
410 | |
411 | /* |
412 | * Backup the data in the question |
413 | * |
414 | * This is used in question/backuplib.php |
415 | */ |
416 | function backup($bf,$preferences,$question,$level=6) { |
417 | |
418 | $status = true; |
419 | |
420 | $matchs = get_records("question_match_sub","question",$question,"id"); |
421 | //If there are matchs |
422 | if ($matchs) { |
423 | $status = fwrite ($bf,start_tag("MATCHS",6,true)); |
424 | //Iterate over each match |
425 | foreach ($matchs as $match) { |
426 | $status = fwrite ($bf,start_tag("MATCH",7,true)); |
427 | //Print match contents |
428 | fwrite ($bf,full_tag("ID",8,false,$match->id)); |
429 | fwrite ($bf,full_tag("CODE",8,false,$match->code)); |
430 | fwrite ($bf,full_tag("QUESTIONTEXT",8,false,$match->questiontext)); |
431 | fwrite ($bf,full_tag("ANSWERTEXT",8,false,$match->answertext)); |
432 | $status = fwrite ($bf,end_tag("MATCH",7,true)); |
433 | } |
434 | $status = fwrite ($bf,end_tag("MATCHS",6,true)); |
435 | } |
436 | return $status; |
437 | } |
516cf3eb |
438 | |
315559d3 |
439 | /// RESTORE FUNCTIONS ///////////////// |
440 | |
441 | /* |
442 | * Restores the data in the question |
443 | * |
444 | * This is used in question/restorelib.php |
445 | */ |
446 | function restore($old_question_id,$new_question_id,$info,$restore) { |
447 | |
448 | $status = true; |
449 | |
450 | //Get the matchs array |
451 | $matchs = $info['#']['MATCHS']['0']['#']['MATCH']; |
452 | |
453 | //We have to build the subquestions field (a list of match_sub id) |
454 | $subquestions_field = ""; |
455 | $in_first = true; |
456 | |
457 | //Iterate over matchs |
458 | for($i = 0; $i < sizeof($matchs); $i++) { |
459 | $mat_info = $matchs[$i]; |
460 | |
461 | //We'll need this later!! |
462 | $oldid = backup_todb($mat_info['#']['ID']['0']['#']); |
463 | |
464 | //Now, build the question_match_SUB record structure |
a58ffe3f |
465 | $match_sub = new stdClass; |
315559d3 |
466 | $match_sub->question = $new_question_id; |
1f4d6e9a |
467 | $match_sub->code = isset($mat_info['#']['CODE']['0']['#'])?backup_todb($mat_info['#']['CODE']['0']['#']):''; |
315559d3 |
468 | if (!$match_sub->code) { |
469 | $match_sub->code = $oldid; |
470 | } |
471 | $match_sub->questiontext = backup_todb($mat_info['#']['QUESTIONTEXT']['0']['#']); |
472 | $match_sub->answertext = backup_todb($mat_info['#']['ANSWERTEXT']['0']['#']); |
473 | |
474 | //The structure is equal to the db, so insert the question_match_sub |
475 | $newid = insert_record ("question_match_sub",$match_sub); |
476 | |
477 | //Do some output |
478 | if (($i+1) % 50 == 0) { |
479 | if (!defined('RESTORE_SILENTLY')) { |
480 | echo "."; |
481 | if (($i+1) % 1000 == 0) { |
482 | echo "<br />"; |
483 | } |
484 | } |
485 | backup_flush(300); |
486 | } |
487 | |
488 | if ($newid) { |
489 | //We have the newid, update backup_ids |
490 | backup_putid($restore->backup_unique_code,"question_match_sub",$oldid, |
491 | $newid); |
492 | //We have a new match_sub, append it to subquestions_field |
493 | if ($in_first) { |
494 | $subquestions_field .= $newid; |
495 | $in_first = false; |
496 | } else { |
497 | $subquestions_field .= ",".$newid; |
498 | } |
499 | } else { |
500 | $status = false; |
501 | } |
502 | } |
503 | |
504 | //We have created every match_sub, now create the match |
87ee4968 |
505 | $match = new stdClass; |
315559d3 |
506 | $match->question = $new_question_id; |
507 | $match->subquestions = $subquestions_field; |
508 | |
509 | //The structure is equal to the db, so insert the question_match_sub |
510 | $newid = insert_record ("question_match",$match); |
511 | |
512 | if (!$newid) { |
513 | $status = false; |
514 | } |
515 | |
516 | return $status; |
517 | } |
518 | |
519 | function restore_map($old_question_id,$new_question_id,$info,$restore) { |
520 | |
521 | $status = true; |
522 | |
523 | //Get the matchs array |
524 | $matchs = $info['#']['MATCHS']['0']['#']['MATCH']; |
525 | |
526 | //We have to build the subquestions field (a list of match_sub id) |
527 | $subquestions_field = ""; |
528 | $in_first = true; |
529 | |
530 | //Iterate over matchs |
531 | for($i = 0; $i < sizeof($matchs); $i++) { |
532 | $mat_info = $matchs[$i]; |
533 | |
534 | //We'll need this later!! |
535 | $oldid = backup_todb($mat_info['#']['ID']['0']['#']); |
536 | |
537 | //Now, build the question_match_SUB record structure |
538 | $match_sub->question = $new_question_id; |
539 | $match_sub->questiontext = backup_todb($mat_info['#']['QUESTIONTEXT']['0']['#']); |
540 | $match_sub->answertext = backup_todb($mat_info['#']['ANSWERTEXT']['0']['#']); |
541 | |
542 | //If we are in this method is because the question exists in DB, so its |
543 | //match_sub must exist too. |
544 | //Now, we are going to look for that match_sub in DB and to create the |
545 | //mappings in backup_ids to use them later where restoring states (user level). |
546 | |
547 | //Get the match_sub from DB (by question, questiontext and answertext) |
548 | $db_match_sub = get_record ("question_match_sub","question",$new_question_id, |
549 | "questiontext",$match_sub->questiontext, |
550 | "answertext",$match_sub->answertext); |
551 | //Do some output |
552 | if (($i+1) % 50 == 0) { |
553 | if (!defined('RESTORE_SILENTLY')) { |
554 | echo "."; |
555 | if (($i+1) % 1000 == 0) { |
556 | echo "<br />"; |
557 | } |
558 | } |
559 | backup_flush(300); |
560 | } |
561 | |
562 | //We have the database match_sub, so update backup_ids |
563 | if ($db_match_sub) { |
564 | //We have the newid, update backup_ids |
565 | backup_putid($restore->backup_unique_code,"question_match_sub",$oldid, |
566 | $db_match_sub->id); |
567 | } else { |
568 | $status = false; |
569 | } |
570 | } |
571 | |
572 | return $status; |
573 | } |
574 | |
575 | function restore_recode_answer($state, $restore) { |
576 | |
577 | //The answer is a comma separated list of hypen separated math_subs (for question and answer) |
578 | $answer_field = ""; |
579 | $in_first = true; |
580 | $tok = strtok($state->answer,","); |
581 | while ($tok) { |
582 | //Extract the match_sub for the question and the answer |
583 | $exploded = explode("-",$tok); |
584 | $match_question_id = $exploded[0]; |
585 | $match_answer_code = $exploded[1]; |
586 | //Get the match_sub from backup_ids (for the question) |
587 | if (!$match_que = backup_getid($restore->backup_unique_code,"question_match_sub",$match_question_id)) { |
588 | echo 'Could not recode question_match_sub '.$match_question_id.'<br />'; |
589 | } |
590 | if ($in_first) { |
591 | $answer_field .= $match_que->new_id."-".$match_answer_code; |
592 | $in_first = false; |
593 | } else { |
594 | $answer_field .= ",".$match_que->new_id."-".$match_answer_code; |
595 | } |
596 | //check for next |
597 | $tok = strtok(","); |
598 | } |
599 | return $answer_field; |
600 | } |
601 | |
516cf3eb |
602 | } |
603 | //// END OF CLASS //// |
604 | |
605 | ////////////////////////////////////////////////////////////////////////// |
606 | //// INITIATION - Without this line the question type is not in use... /// |
607 | ////////////////////////////////////////////////////////////////////////// |
a2156789 |
608 | question_register_questiontype(new question_match_qtype()); |
516cf3eb |
609 | ?> |