Automatic installer.php lang files by installer_builder (20070224)
[moodle.git] / question / restorelib.php
blobe0f8d65912dfc511b5174278fec71638a4e0bb58
1 <?php //$Id$
2 //This php script contains all the stuff to restore questions
4 // Todo:
5 // the restoration of the parent and sortorder fields in the category table needs
6 // a lot more thought. We should probably use a library function to add the category
7 // rather than just writing it to the database
9 // whereever it says "/// We have to recode the .... field" we should put in a check
10 // to see if the recoding was successful and throw an appropriate error otherwise
12 //This is the "graphical" structure of the question database:
13 //To see, put your terminal to 160cc
15 // The following holds student-independent information about the questions
17 // question_categories
18 // (CL,pk->id)
19 // |
20 // |
21 // |.......................................
22 // | .
23 // | .
24 // | -------question_datasets------ .
25 // | | (CL,pk->id,fk->question, | .
26 // | | fk->dataset_definition) | .
27 // | | | .
28 // | | | .
29 // | | | .
30 // | | question_dataset_definitions
31 // | | (CL,pk->id,fk->category)
32 // question |
33 // (CL,pk->id,fk->category,files) |
34 // | question_dataset_items
35 // | (CL,pk->id,fk->definition)
36 // | question_rqp_type
37 // | (SL,pk->id)
38 // | |
39 // -------------------------------------------------------------------------------------------------------------- |
40 // | | | | | | | question_rqp
41 // | | | | | | |--(CL,pk->id,fk->question)
42 // | | | | question_calculated | |
43 // question_truefalse | question_multichoice | (CL,pl->id,fk->question) | |
44 // (CL,pk->id,fk->question) | (CL,pk->id,fk->question) | . | | question_randomsamatch
45 // . | . | . | |--(CL,pk->id,fk->question)
46 // . question_shortanswer . question_numerical . question_multianswer. |
47 // . (CL,pk->id,fk->question) . (CL,pk->id,fk->question) . (CL,pk->id,fk->question) |
48 // . . . . . . | question_match
49 // . . . . . . |--(CL,pk->id,fk->question)
50 // . . . . . . | .
51 // . . . . . . | .
52 // . . . . . . | .
53 // . . . . . . | question_match_sub
54 // ........................................................................................ |--(CL,pk->id,fk->question)
55 // . |
56 // . |
57 // . | question_numerical_units
58 // question_answers |--(CL,pk->id,fk->question)
59 // (CL,pk->id,fk->question)----------------------------------------------------------
62 // The following holds the information about student interaction with the questions
64 // question_sessions
65 // (UL,pk->id,fk->attempt,question)
66 // .
67 // .
68 // question_states
69 // (UL,pk->id,fk->attempt,question)
70 // |
71 // question_rqp_states
72 // (UL,pk->id,fk->stateid)
74 // Meaning: pk->primary key field of the table
75 // fk->foreign key to link with parent
76 // nt->nested field (recursive data)
77 // SL->site level info
78 // CL->course level info
79 // UL->user level info
80 // files->table may have files
82 //-----------------------------------------------------------
84 include_once($CFG->libdir.'/questionlib.php');
86 function restore_question_categories($category,$restore) {
88 global $CFG;
90 $status = true;
92 //Hook to call Moodle < 1.5 Quiz Restore
93 if ($restore->backup_version < 2005043000) {
94 include_once($CFG->dirroot.'/mod/quiz/restorelibpre15.php');
95 return quiz_restore_pre15_question_categories($category,$restore);
98 //Get record from backup_ids
99 $data = backup_getid($restore->backup_unique_code,"question_categories",$category->id);
101 if ($data) {
102 //Now get completed xmlized object
103 $info = $data->info;
104 //traverse_xmlize($info); //Debug
105 //print_object ($GLOBALS['traverse_array']); //Debug
106 //$GLOBALS['traverse_array']=""; //Debug
108 //Now, build the question_categories record structure
109 $question_cat = new stdClass;
110 $question_cat->course = $restore->course_id;
111 $question_cat->name = backup_todb($info['QUESTION_CATEGORY']['#']['NAME']['0']['#']);
112 $question_cat->info = backup_todb($info['QUESTION_CATEGORY']['#']['INFO']['0']['#']);
113 $question_cat->publish = backup_todb($info['QUESTION_CATEGORY']['#']['PUBLISH']['0']['#']);
114 $question_cat->stamp = backup_todb($info['QUESTION_CATEGORY']['#']['STAMP']['0']['#']);
115 $question_cat->parent = backup_todb($info['QUESTION_CATEGORY']['#']['PARENT']['0']['#']);
116 $question_cat->sortorder = backup_todb($info['QUESTION_CATEGORY']['#']['SORTORDER']['0']['#']);
118 if ($catfound = restore_get_best_question_category($question_cat, $restore->course_id)) {
119 $newid = $catfound;
120 } else {
121 if (!$question_cat->stamp) {
122 $question_cat->stamp = make_unique_id_code();
124 $newid = insert_record ("question_categories",$question_cat);
127 //Do some output
128 if ($newid) {
129 if (!defined('RESTORE_SILENTLY')) {
130 echo "<li>".get_string('category', 'quiz')." \"".$question_cat->name."\"<br />";
132 } else {
133 //We must never arrive here !!
134 if (!defined('RESTORE_SILENTLY')) {
135 echo "<li>".get_string('category', 'quiz')." \"".$question_cat->name."\" Error!<br />";
137 $status = false;
139 backup_flush(300);
141 //Here category has been created or selected, so save results in backup_ids and start with questions
142 if ($newid and $status) {
143 //We have the newid, update backup_ids
144 backup_putid($restore->backup_unique_code,"question_categories",
145 $category->id, $newid);
146 //Now restore question
147 $status = restore_questions ($category->id, $newid,$info,$restore);
148 } else {
149 $status = false;
151 if (!defined('RESTORE_SILENTLY')) {
152 echo '</li>';
154 } else {
155 echo 'Could not get backup info for question category'. $category->id;
158 return $status;
161 function restore_questions ($old_category_id,$new_category_id,$info,$restore) {
163 global $CFG, $QTYPES;
165 $status = true;
166 $restored_questions = array();
168 //Get the questions array
169 if (!empty($info['QUESTION_CATEGORY']['#']['QUESTIONS'])) {
170 $questions = $info['QUESTION_CATEGORY']['#']['QUESTIONS']['0']['#']['QUESTION'];
171 } else {
172 $questions = array();
175 //Iterate over questions
176 for($i = 0; $i < sizeof($questions); $i++) {
177 $que_info = $questions[$i];
178 //traverse_xmlize($que_info); //Debug
179 //print_object ($GLOBALS['traverse_array']); //Debug
180 //$GLOBALS['traverse_array']=""; //Debug
182 //We'll need this later!!
183 $oldid = backup_todb($que_info['#']['ID']['0']['#']);
185 //Now, build the question record structure
186 $question = new object;
187 $question->category = $new_category_id;
188 $question->parent = backup_todb($que_info['#']['PARENT']['0']['#']);
189 $question->name = backup_todb($que_info['#']['NAME']['0']['#']);
190 $question->questiontext = backup_todb($que_info['#']['QUESTIONTEXT']['0']['#']);
191 $question->questiontextformat = backup_todb($que_info['#']['QUESTIONTEXTFORMAT']['0']['#']);
192 $question->image = backup_todb($que_info['#']['IMAGE']['0']['#']);
193 $question->defaultgrade = backup_todb($que_info['#']['DEFAULTGRADE']['0']['#']);
194 $question->penalty = backup_todb($que_info['#']['PENALTY']['0']['#']);
195 $question->qtype = backup_todb($que_info['#']['QTYPE']['0']['#']);
196 $question->length = backup_todb($que_info['#']['LENGTH']['0']['#']);
197 $question->stamp = backup_todb($que_info['#']['STAMP']['0']['#']);
198 $question->version = backup_todb($que_info['#']['VERSION']['0']['#']);
199 $question->hidden = backup_todb($que_info['#']['HIDDEN']['0']['#']);
201 if ($restore->backup_version < 2006032200) {
202 // The qtype was an integer that now needs to be converted to the name
203 $qtypenames = array(1=>'shortanswer',2=>'truefalse',3=>'multichoice',4=>'random',5=>'match',
204 6=>'randomsamatch',7=>'description',8=>'numerical',9=>'multianswer',10=>'calculated',
205 11=>'rqp',12=>'essay');
206 $question->qtype = $qtypenames[$question->qtype];
209 //Check if the question exists
210 //by category, stamp, and version
211 $question_exists = get_record ("question","category",$question->category,
212 "stamp",$question->stamp,"version",$question->version);
214 //If the question exists, only record its id
215 if ($question_exists) {
216 $newid = $question_exists->id;
217 $creatingnewquestion = false;
218 //Else, create a new question
219 } else {
220 //The structure is equal to the db, so insert the question
221 $newid = insert_record ("question",$question);
222 $creatingnewquestion = true;
225 //Save newid to backup tables
226 if ($newid) {
227 //We have the newid, update backup_ids
228 backup_putid($restore->backup_unique_code,"question",$oldid,
229 $newid);
232 $restored_questions[$i] = new stdClass;
233 $restored_questions[$i]->newid = $newid;
234 $restored_questions[$i]->oldid = $oldid;
235 $restored_questions[$i]->qtype = $question->qtype;
236 $restored_questions[$i]->parent = $question->parent;
237 $restored_questions[$i]->is_new = $creatingnewquestion;
240 // Loop again, now all the question id mappings exist, so everything can
241 // be restored.
242 for($i = 0; $i < sizeof($questions); $i++) {
243 $que_info = $questions[$i];
245 $newid = $restored_questions[$i]->newid;
246 $oldid = $restored_questions[$i]->oldid;
248 $question = new object;
249 $question->qtype = $restored_questions[$i]->qtype;
250 $question->parent = $restored_questions[$i]->parent;
253 //If it's a new question in the DB, restore it
254 if ($restored_questions[$i]->is_new) {
256 ////We have to recode the parent field
257 if ($question->parent) {
258 if ($parent = backup_getid($restore->backup_unique_code,"question",$question->parent)) {
259 $question->parent = $parent->new_id;
260 } elseif ($question->parent = $oldid) {
261 $question->parent = $newid;
262 } else {
263 echo 'Could not recode parent '.$question->parent.' for question '.$oldid.'<br />';
267 //Now, restore every question_answers in this question
268 $status = question_restore_answers($oldid,$newid,$que_info,$restore);
269 // Restore questiontype specific data
270 if (array_key_exists($question->qtype, $QTYPES)) {
271 $status = $QTYPES[$question->qtype]->restore($oldid,$newid,$que_info,$restore);
272 } else {
273 echo 'Unknown question type '.$question->qtype.' for question '.$oldid.'<br />';
274 $status = false;
276 } else {
277 //We are NOT creating the question, but we need to know every question_answers
278 //map between the XML file and the database to be able to restore the states
279 //in each attempt.
280 $status = question_restore_map_answers($oldid,$newid,$que_info,$restore);
281 // Do the questiontype specific mapping
282 if (array_key_exists($question->qtype, $QTYPES)) {
283 $status = $QTYPES[$question->qtype]->restore_map($oldid,$newid,$que_info,$restore);
284 } else {
285 echo 'Unknown question type '.$question->qtype.' for question '.$oldid.'<br />';
286 $status = false;
290 //Do some output
291 if (($i+1) % 2 == 0) {
292 if (!defined('RESTORE_SILENTLY')) {
293 echo ".";
294 if (($i+1) % 40 == 0) {
295 echo "<br />";
298 backup_flush(300);
301 return $status;
304 function question_restore_answers ($old_question_id,$new_question_id,$info,$restore) {
306 global $CFG;
308 $status = true;
310 //Get the answers array
311 if (isset($info['#']['ANSWERS']['0']['#']['ANSWER'])) {
312 $answers = $info['#']['ANSWERS']['0']['#']['ANSWER'];
314 //Iterate over answers
315 for($i = 0; $i < sizeof($answers); $i++) {
316 $ans_info = $answers[$i];
317 //traverse_xmlize($ans_info); //Debug
318 //print_object ($GLOBALS['traverse_array']); //Debug
319 //$GLOBALS['traverse_array']=""; //Debug
321 //We'll need this later!!
322 $oldid = backup_todb($ans_info['#']['ID']['0']['#']);
324 //Now, build the question_answers record structure
325 $answer = new stdClass;
326 $answer->question = $new_question_id;
327 $answer->answer = backup_todb($ans_info['#']['ANSWER_TEXT']['0']['#']);
328 $answer->fraction = backup_todb($ans_info['#']['FRACTION']['0']['#']);
329 $answer->feedback = backup_todb($ans_info['#']['FEEDBACK']['0']['#']);
331 //The structure is equal to the db, so insert the question_answers
332 $newid = insert_record ("question_answers",$answer);
334 //Do some output
335 if (($i+1) % 50 == 0) {
336 if (!defined('RESTORE_SILENTLY')) {
337 echo ".";
338 if (($i+1) % 1000 == 0) {
339 echo "<br />";
342 backup_flush(300);
345 if ($newid) {
346 //We have the newid, update backup_ids
347 backup_putid($restore->backup_unique_code,"question_answers",$oldid,
348 $newid);
349 } else {
350 $status = false;
355 return $status;
358 function question_restore_map_answers ($old_question_id,$new_question_id,$info,$restore) {
360 global $CFG;
362 $status = true;
364 if (!isset($info['#']['ANSWERS'])) { // No answers in this question (eg random)
365 return $status;
368 //Get the answers array
369 $answers = $info['#']['ANSWERS']['0']['#']['ANSWER'];
371 //Iterate over answers
372 for($i = 0; $i < sizeof($answers); $i++) {
373 $ans_info = $answers[$i];
374 //traverse_xmlize($ans_info); //Debug
375 //print_object ($GLOBALS['traverse_array']); //Debug
376 //$GLOBALS['traverse_array']=""; //Debug
378 //We'll need this later!!
379 $oldid = backup_todb($ans_info['#']['ID']['0']['#']);
381 //Now, build the question_answers record structure
382 $answer->question = $new_question_id;
383 $answer->answer = backup_todb($ans_info['#']['ANSWER_TEXT']['0']['#']);
384 $answer->fraction = backup_todb($ans_info['#']['FRACTION']['0']['#']);
385 $answer->feedback = backup_todb($ans_info['#']['FEEDBACK']['0']['#']);
387 //If we are in this method is because the question exists in DB, so its
388 //answers must exist too.
389 //Now, we are going to look for that answer in DB and to create the
390 //mappings in backup_ids to use them later where restoring states (user level).
392 //Get the answer from DB (by question and answer)
393 $db_answer = get_record ("question_answers","question",$new_question_id,
394 "answer",$answer->answer);
396 //Do some output
397 if (($i+1) % 50 == 0) {
398 if (!defined('RESTORE_SILENTLY')) {
399 echo ".";
400 if (($i+1) % 1000 == 0) {
401 echo "<br />";
404 backup_flush(300);
407 if ($db_answer) {
408 //We have the database answer, update backup_ids
409 backup_putid($restore->backup_unique_code,"question_answers",$oldid,
410 $db_answer->id);
411 } else {
412 $status = false;
416 return $status;
419 function question_restore_numerical_units ($old_question_id,$new_question_id,$info,$restore) {
421 global $CFG;
423 $status = true;
425 //Get the numerical array
426 $numerical_units = $info['#']['NUMERICAL_UNITS']['0']['#']['NUMERICAL_UNIT'];
428 //Iterate over numerical_units
429 for($i = 0; $i < sizeof($numerical_units); $i++) {
430 $nu_info = $numerical_units[$i];
431 //traverse_xmlize($nu_info); //Debug
432 //print_object ($GLOBALS['traverse_array']); //Debug
433 //$GLOBALS['traverse_array']=""; //Debug
435 //Now, build the question_numerical_UNITS record structure
436 $numerical_unit = new stdClass;
437 $numerical_unit->question = $new_question_id;
438 $numerical_unit->multiplier = backup_todb($nu_info['#']['MULTIPLIER']['0']['#']);
439 $numerical_unit->unit = backup_todb($nu_info['#']['UNIT']['0']['#']);
441 //The structure is equal to the db, so insert the question_numerical_units
442 $newid = insert_record ("question_numerical_units",$numerical_unit);
444 if (!$newid) {
445 $status = false;
449 return $status;
452 function question_restore_dataset_definitions ($old_question_id,$new_question_id,$info,$restore) {
454 global $CFG;
456 $status = true;
458 //Get the dataset_definitions array
459 $dataset_definitions = $info['#']['DATASET_DEFINITIONS']['0']['#']['DATASET_DEFINITION'];
461 //Iterate over dataset_definitions
462 for($i = 0; $i < sizeof($dataset_definitions); $i++) {
463 $dd_info = $dataset_definitions[$i];
464 //traverse_xmlize($dd_info); //Debug
465 //print_object ($GLOBALS['traverse_array']); //Debug
466 //$GLOBALS['traverse_array']=""; //Debug
468 //Now, build the question_dataset_DEFINITION record structure
469 $dataset_definition = new stdClass;
470 $dataset_definition->category = backup_todb($dd_info['#']['CATEGORY']['0']['#']);
471 $dataset_definition->name = backup_todb($dd_info['#']['NAME']['0']['#']);
472 $dataset_definition->type = backup_todb($dd_info['#']['TYPE']['0']['#']);
473 $dataset_definition->options = backup_todb($dd_info['#']['OPTIONS']['0']['#']);
474 $dataset_definition->itemcount = backup_todb($dd_info['#']['ITEMCOUNT']['0']['#']);
476 //We have to recode the category field (only if the category != 0)
477 if ($dataset_definition->category != 0) {
478 $category = backup_getid($restore->backup_unique_code,"question_categories",$dataset_definition->category);
479 if ($category) {
480 $dataset_definition->category = $category->new_id;
481 } else {
482 echo 'Could not recode category id '.$dataset_definition->category.' for dataset definition'.$dataset_definition->name.'<br />';
486 //Now, we hace to decide when to create the new records or reuse an existing one
487 $create_definition = false;
489 //If the dataset_definition->category = 0, it's a individual question dataset_definition, so we'll create it
490 if ($dataset_definition->category == 0) {
491 $create_definition = true;
492 } else {
493 //The category isn't 0, so it's a category question dataset_definition, we have to see if it exists
494 //Look for a definition with the same category, name and type
495 if ($definitionrec = get_record_sql("SELECT d.*
496 FROM {$CFG->prefix}question_dataset_definitions d
497 WHERE d.category = '$dataset_definition->category' AND
498 d.name = '$dataset_definition->name' AND
499 d.type = '$dataset_definition->type'")) {
500 //Such dataset_definition exist. Now we must check if it has enough itemcount
501 if ($definitionrec->itemcount < $dataset_definition->itemcount) {
502 //We haven't enough itemcount, so we have to create the definition as an individual question one.
503 $dataset_definition->category = 0;
504 $create_definition = true;
505 } else {
506 //We have enough itemcount, so we'll reuse the existing definition
507 $create_definition = false;
508 $newid = $definitionrec->id;
510 } else {
511 //Such dataset_definition doesn't exist. We'll create it.
512 $create_definition = true;
516 //If we've to create the definition, do it
517 if ($create_definition) {
518 //The structure is equal to the db, so insert the question_dataset_definitions
519 $newid = insert_record ("question_dataset_definitions",$dataset_definition);
520 if ($newid) {
521 //Restore question_dataset_items
522 $status = question_restore_dataset_items($newid,$dd_info,$restore);
526 //Now, we must have a definition (created o reused). Its id is in newid. Create the question_datasets record
527 //to join the question and the dataset_definition
528 if ($newid) {
529 $question_dataset = new stdClass;
530 $question_dataset->question = $new_question_id;
531 $question_dataset->datasetdefinition = $newid;
532 $newid = insert_record ("question_datasets",$question_dataset);
535 if (!$newid) {
536 $status = false;
540 return $status;
543 function question_restore_dataset_items ($definitionid,$info,$restore) {
545 global $CFG;
547 $status = true;
549 //Get the items array
550 $dataset_items = $info['#']['DATASET_ITEMS']['0']['#']['DATASET_ITEM'];
552 //Iterate over dataset_items
553 for($i = 0; $i < sizeof($dataset_items); $i++) {
554 $di_info = $dataset_items[$i];
555 //traverse_xmlize($di_info); //Debug
556 //print_object ($GLOBALS['traverse_array']); //Debug
557 //$GLOBALS['traverse_array']=""; //Debug
559 //Now, build the question_dataset_ITEMS record structure
560 $dataset_item = new stdClass;
561 $dataset_item->definition = $definitionid;
562 $dataset_item->number = backup_todb($di_info['#']['NUMBER']['0']['#']);
563 $dataset_item->value = backup_todb($di_info['#']['VALUE']['0']['#']);
565 //The structure is equal to the db, so insert the question_dataset_items
566 $newid = insert_record ("question_dataset_items",$dataset_item);
568 if (!$newid) {
569 $status = false;
573 return $status;
577 //This function restores the question_states
578 function question_states_restore_mods($attempt_id,$info,$restore) {
580 global $CFG, $QTYPES;
582 $status = true;
584 //Get the question_states array
585 $states = $info['#']['STATES']['0']['#']['STATE'];
586 //Iterate over states
587 for($i = 0; $i < sizeof($states); $i++) {
588 $res_info = $states[$i];
589 //traverse_xmlize($res_info); //Debug
590 //print_object ($GLOBALS['traverse_array']); //Debug
591 //$GLOBALS['traverse_array']=""; //Debug
593 //We'll need this later!!
594 $oldid = backup_todb($res_info['#']['ID']['0']['#']);
596 //Now, build the STATES record structure
597 $state = new stdClass;
598 $state->attempt = $attempt_id;
599 $state->question = backup_todb($res_info['#']['QUESTION']['0']['#']);
600 $state->originalquestion = backup_todb($res_info['#']['ORIGINALQUESTION']['0']['#']);
601 $state->seq_number = backup_todb($res_info['#']['SEQ_NUMBER']['0']['#']);
602 $state->answer = backup_todb($res_info['#']['ANSWER']['0']['#']);
603 $state->timestamp = backup_todb($res_info['#']['TIMESTAMP']['0']['#']);
604 $state->event = backup_todb($res_info['#']['EVENT']['0']['#']);
605 $state->grade = backup_todb($res_info['#']['GRADE']['0']['#']);
606 $state->raw_grade = backup_todb($res_info['#']['RAW_GRADE']['0']['#']);
607 $state->penalty = backup_todb($res_info['#']['PENALTY']['0']['#']);
609 //We have to recode the question field
610 $question = backup_getid($restore->backup_unique_code,"question",$state->question);
611 if ($question) {
612 $state->question = $question->new_id;
613 } else {
614 echo 'Could not recode question id '.$state->question.' for state '.$oldid.'<br />';
617 //We have to recode the originalquestion field if it is nonzero
618 if ($state->originalquestion) {
619 $question = backup_getid($restore->backup_unique_code,"question",$state->originalquestion);
620 if ($question) {
621 $state->originalquestion = $question->new_id;
622 } else {
623 echo 'Could not recode originalquestion id '.$state->question.' for state '.$oldid.'<br />';
627 //We have to recode the answer field
628 //It depends of the question type !!
629 //We get the question first
630 if (!$question = get_record("question","id",$state->question)) {
631 error("Can't find the record for question $state->question for which I am trying to restore a state");
633 //Depending on the qtype, we make different recodes
634 if ($state->answer) {
635 $state->answer = $QTYPES[$question->qtype]->restore_recode_answer($state, $restore);
638 //The structure is equal to the db, so insert the question_states
639 $newid = insert_record ("question_states",$state);
641 //Do some output
642 if (($i+1) % 10 == 0) {
643 if (!defined('RESTORE_SILENTLY')) {
644 echo ".";
645 if (($i+1) % 200 == 0) {
646 echo "<br />";
649 backup_flush(300);
652 if ($newid) {
653 //We have the newid, update backup_ids
654 backup_putid($restore->backup_unique_code,"question_states",$oldid,
655 $newid);
656 //Now process question type specific state information
657 $qtype = get_field('question', 'qtype', 'id', $state->question);
658 $status = $QTYPES[$qtype]->restore_state($newid,$res_info,$restore);
659 } else {
660 $status = false;
664 //Get the question_sessions array
665 $sessions = $info['#']['NEWEST_STATES']['0']['#']['NEWEST_STATE'];
666 //Iterate over question_sessions
667 for($i = 0; $i < sizeof($sessions); $i++) {
668 $res_info = $sessions[$i];
669 //traverse_xmlize($res_info); //Debug
670 //print_object ($GLOBALS['traverse_array']); //Debug
671 //$GLOBALS['traverse_array']=""; //Debug
673 //Now, build the NEWEST_STATES record structure
674 $session = new stdClass;
675 $session->attemptid = $attempt_id;
676 $session->questionid = backup_todb($res_info['#']['QUESTIONID']['0']['#']);
677 $session->newest = backup_todb($res_info['#']['NEWEST']['0']['#']);
678 $session->newgraded = backup_todb($res_info['#']['NEWGRADED']['0']['#']);
679 $session->sumpenalty = backup_todb($res_info['#']['SUMPENALTY']['0']['#']);
681 //We have to recode the question field
682 $question = backup_getid($restore->backup_unique_code,"question",$session->questionid);
683 if ($question) {
684 $session->questionid = $question->new_id;
685 } else {
686 echo 'Could not recode question id '.$session->questionid.'<br />';
689 //We have to recode the newest field
690 $state = backup_getid($restore->backup_unique_code,"question_states",$session->newest);
691 if ($state) {
692 $session->newest = $state->new_id;
693 } else {
694 echo 'Could not recode newest state id '.$session->newest.'<br />';
697 //If the session has been graded we have to recode the newgraded field
698 if ($session->newgraded) {
699 $state = backup_getid($restore->backup_unique_code,"question_states",$session->newgraded);
700 if ($state) {
701 $session->newgraded = $state->new_id;
702 } else {
703 echo 'Could not recode newest graded state id '.$session->newgraded.'<br />';
707 //The structure is equal to the db, so insert the question_sessions
708 $newid = insert_record ("question_sessions",$session);
712 return $status;