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