Slightly more helpful message if no courses can be shown.
[moodle-linuxchix.git] / question / restorelib.php
blobe4ca6f7d7025ffc5f82617b6050773bb0c103878
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 if (array_key_exists('GENERALFEEDBACK', $que_info['#'])) {
194 $question->generalfeedback = backup_todb($que_info['#']['GENERALFEEDBACK']['0']['#']);
195 } else {
196 $question->generalfeedback = '';
198 $question->defaultgrade = backup_todb($que_info['#']['DEFAULTGRADE']['0']['#']);
199 $question->penalty = backup_todb($que_info['#']['PENALTY']['0']['#']);
200 $question->qtype = backup_todb($que_info['#']['QTYPE']['0']['#']);
201 $question->length = backup_todb($que_info['#']['LENGTH']['0']['#']);
202 $question->stamp = backup_todb($que_info['#']['STAMP']['0']['#']);
203 $question->version = backup_todb($que_info['#']['VERSION']['0']['#']);
204 $question->hidden = backup_todb($que_info['#']['HIDDEN']['0']['#']);
206 if ($restore->backup_version < 2006032200) {
207 // The qtype was an integer that now needs to be converted to the name
208 $qtypenames = array(1=>'shortanswer',2=>'truefalse',3=>'multichoice',4=>'random',5=>'match',
209 6=>'randomsamatch',7=>'description',8=>'numerical',9=>'multianswer',10=>'calculated',
210 11=>'rqp',12=>'essay');
211 $question->qtype = $qtypenames[$question->qtype];
214 //Check if the question exists
215 //by category, stamp, and version
216 $question_exists = get_record ("question","category",$question->category,
217 "stamp",$question->stamp,"version",$question->version);
219 //If the question exists, only record its id
220 if ($question_exists) {
221 $newid = $question_exists->id;
222 $creatingnewquestion = false;
223 //Else, create a new question
224 } else {
225 //The structure is equal to the db, so insert the question
226 $newid = insert_record ("question",$question);
227 $creatingnewquestion = true;
230 //Save newid to backup tables
231 if ($newid) {
232 //We have the newid, update backup_ids
233 backup_putid($restore->backup_unique_code,"question",$oldid,
234 $newid);
237 $restored_questions[$i] = new stdClass;
238 $restored_questions[$i]->newid = $newid;
239 $restored_questions[$i]->oldid = $oldid;
240 $restored_questions[$i]->qtype = $question->qtype;
241 $restored_questions[$i]->parent = $question->parent;
242 $restored_questions[$i]->is_new = $creatingnewquestion;
245 // Loop again, now all the question id mappings exist, so everything can
246 // be restored.
247 for($i = 0; $i < sizeof($questions); $i++) {
248 $que_info = $questions[$i];
250 $newid = $restored_questions[$i]->newid;
251 $oldid = $restored_questions[$i]->oldid;
253 $question = new object;
254 $question->qtype = $restored_questions[$i]->qtype;
255 $question->parent = $restored_questions[$i]->parent;
258 //If it's a new question in the DB, restore it
259 if ($restored_questions[$i]->is_new) {
261 ////We have to recode the parent field
262 if ($question->parent) {
263 if ($parent = backup_getid($restore->backup_unique_code,"question",$question->parent)) {
264 $question->parent = $parent->new_id;
265 } elseif ($question->parent = $oldid) {
266 $question->parent = $newid;
267 } else {
268 echo 'Could not recode parent '.$question->parent.' for question '.$oldid.'<br />';
272 //Now, restore every question_answers in this question
273 $status = question_restore_answers($oldid,$newid,$que_info,$restore);
274 // Restore questiontype specific data
275 if (array_key_exists($question->qtype, $QTYPES)) {
276 $status = $QTYPES[$question->qtype]->restore($oldid,$newid,$que_info,$restore);
277 } else {
278 echo 'Unknown question type '.$question->qtype.' for question '.$oldid.'<br />';
279 $status = false;
281 } else {
282 //We are NOT creating the question, but we need to know every question_answers
283 //map between the XML file and the database to be able to restore the states
284 //in each attempt.
285 $status = question_restore_map_answers($oldid,$newid,$que_info,$restore);
286 // Do the questiontype specific mapping
287 if (array_key_exists($question->qtype, $QTYPES)) {
288 $status = $QTYPES[$question->qtype]->restore_map($oldid,$newid,$que_info,$restore);
289 } else {
290 echo 'Unknown question type '.$question->qtype.' for question '.$oldid.'<br />';
291 $status = false;
295 //Do some output
296 if (($i+1) % 2 == 0) {
297 if (!defined('RESTORE_SILENTLY')) {
298 echo ".";
299 if (($i+1) % 40 == 0) {
300 echo "<br />";
303 backup_flush(300);
306 return $status;
309 function question_restore_answers ($old_question_id,$new_question_id,$info,$restore) {
311 global $CFG;
313 $status = true;
314 $qtype = backup_todb($info['#']['QTYPE']['0']['#']);
316 //Get the answers array
317 if (isset($info['#']['ANSWERS']['0']['#']['ANSWER'])) {
318 $answers = $info['#']['ANSWERS']['0']['#']['ANSWER'];
320 //Iterate over answers
321 for($i = 0; $i < sizeof($answers); $i++) {
322 $ans_info = $answers[$i];
323 //traverse_xmlize($ans_info); //Debug
324 //print_object ($GLOBALS['traverse_array']); //Debug
325 //$GLOBALS['traverse_array']=""; //Debug
327 //We'll need this later!!
328 $oldid = backup_todb($ans_info['#']['ID']['0']['#']);
330 //Now, build the question_answers record structure
331 $answer = new stdClass;
332 $answer->question = $new_question_id;
333 $answer->answer = backup_todb($ans_info['#']['ANSWER_TEXT']['0']['#']);
334 $answer->fraction = backup_todb($ans_info['#']['FRACTION']['0']['#']);
335 $answer->feedback = backup_todb($ans_info['#']['FEEDBACK']['0']['#']);
337 // Update 'match everything' answers for numerical questions coming from old backup files.
338 if ($qtype == 'numerical' && $answer->answer == '') {
339 $answer->answer = '*';
342 //The structure is equal to the db, so insert the question_answers
343 $newid = insert_record ("question_answers",$answer);
345 //Do some output
346 if (($i+1) % 50 == 0) {
347 if (!defined('RESTORE_SILENTLY')) {
348 echo ".";
349 if (($i+1) % 1000 == 0) {
350 echo "<br />";
353 backup_flush(300);
356 if ($newid) {
357 //We have the newid, update backup_ids
358 backup_putid($restore->backup_unique_code,"question_answers",$oldid,
359 $newid);
360 } else {
361 $status = false;
366 return $status;
369 function question_restore_map_answers ($old_question_id,$new_question_id,$info,$restore) {
371 global $CFG;
373 $status = true;
375 if (!isset($info['#']['ANSWERS'])) { // No answers in this question (eg random)
376 return $status;
379 //Get the answers array
380 $answers = $info['#']['ANSWERS']['0']['#']['ANSWER'];
382 //Iterate over answers
383 for($i = 0; $i < sizeof($answers); $i++) {
384 $ans_info = $answers[$i];
385 //traverse_xmlize($ans_info); //Debug
386 //print_object ($GLOBALS['traverse_array']); //Debug
387 //$GLOBALS['traverse_array']=""; //Debug
389 //We'll need this later!!
390 $oldid = backup_todb($ans_info['#']['ID']['0']['#']);
392 //Now, build the question_answers record structure
393 $answer->question = $new_question_id;
394 $answer->answer = backup_todb($ans_info['#']['ANSWER_TEXT']['0']['#']);
395 $answer->fraction = backup_todb($ans_info['#']['FRACTION']['0']['#']);
396 $answer->feedback = backup_todb($ans_info['#']['FEEDBACK']['0']['#']);
398 //If we are in this method is because the question exists in DB, so its
399 //answers must exist too.
400 //Now, we are going to look for that answer in DB and to create the
401 //mappings in backup_ids to use them later where restoring states (user level).
403 //Get the answer from DB (by question and answer)
404 $db_answer = get_record ("question_answers","question",$new_question_id,
405 "answer",$answer->answer);
407 //Do some output
408 if (($i+1) % 50 == 0) {
409 if (!defined('RESTORE_SILENTLY')) {
410 echo ".";
411 if (($i+1) % 1000 == 0) {
412 echo "<br />";
415 backup_flush(300);
418 if ($db_answer) {
419 //We have the database answer, update backup_ids
420 backup_putid($restore->backup_unique_code,"question_answers",$oldid,
421 $db_answer->id);
422 } else {
423 $status = false;
427 return $status;
430 function question_restore_numerical_units ($old_question_id,$new_question_id,$info,$restore) {
432 global $CFG;
434 $status = true;
436 //Get the numerical array
437 if (!empty($info['#']['NUMERICAL_UNITS'])) {
438 $numerical_units = $info['#']['NUMERICAL_UNITS']['0']['#']['NUMERICAL_UNIT'];
439 } else {
440 $numerical_units = array();
443 //Iterate over numerical_units
444 for($i = 0; $i < sizeof($numerical_units); $i++) {
445 $nu_info = $numerical_units[$i];
446 //traverse_xmlize($nu_info); //Debug
447 //print_object ($GLOBALS['traverse_array']); //Debug
448 //$GLOBALS['traverse_array']=""; //Debug
450 //Now, build the question_numerical_UNITS record structure
451 $numerical_unit = new stdClass;
452 $numerical_unit->question = $new_question_id;
453 $numerical_unit->multiplier = backup_todb($nu_info['#']['MULTIPLIER']['0']['#']);
454 $numerical_unit->unit = backup_todb($nu_info['#']['UNIT']['0']['#']);
456 //The structure is equal to the db, so insert the question_numerical_units
457 $newid = insert_record ("question_numerical_units",$numerical_unit);
459 if (!$newid) {
460 $status = false;
464 return $status;
467 function question_restore_dataset_definitions ($old_question_id,$new_question_id,$info,$restore) {
469 global $CFG;
471 $status = true;
473 //Get the dataset_definitions array
474 $dataset_definitions = $info['#']['DATASET_DEFINITIONS']['0']['#']['DATASET_DEFINITION'];
476 //Iterate over dataset_definitions
477 for($i = 0; $i < sizeof($dataset_definitions); $i++) {
478 $dd_info = $dataset_definitions[$i];
479 //traverse_xmlize($dd_info); //Debug
480 //print_object ($GLOBALS['traverse_array']); //Debug
481 //$GLOBALS['traverse_array']=""; //Debug
483 //Now, build the question_dataset_DEFINITION record structure
484 $dataset_definition = new stdClass;
485 $dataset_definition->category = backup_todb($dd_info['#']['CATEGORY']['0']['#']);
486 $dataset_definition->name = backup_todb($dd_info['#']['NAME']['0']['#']);
487 $dataset_definition->type = backup_todb($dd_info['#']['TYPE']['0']['#']);
488 $dataset_definition->options = backup_todb($dd_info['#']['OPTIONS']['0']['#']);
489 $dataset_definition->itemcount = backup_todb($dd_info['#']['ITEMCOUNT']['0']['#']);
491 //We have to recode the category field (only if the category != 0)
492 if ($dataset_definition->category != 0) {
493 $category = backup_getid($restore->backup_unique_code,"question_categories",$dataset_definition->category);
494 if ($category) {
495 $dataset_definition->category = $category->new_id;
496 } else {
497 echo 'Could not recode category id '.$dataset_definition->category.' for dataset definition'.$dataset_definition->name.'<br />';
501 //Now, we hace to decide when to create the new records or reuse an existing one
502 $create_definition = false;
504 //If the dataset_definition->category = 0, it's a individual question dataset_definition, so we'll create it
505 if ($dataset_definition->category == 0) {
506 $create_definition = true;
507 } else {
508 //The category isn't 0, so it's a category question dataset_definition, we have to see if it exists
509 //Look for a definition with the same category, name and type
510 if ($definitionrec = get_record_sql("SELECT d.*
511 FROM {$CFG->prefix}question_dataset_definitions d
512 WHERE d.category = '$dataset_definition->category' AND
513 d.name = '$dataset_definition->name' AND
514 d.type = '$dataset_definition->type'")) {
515 //Such dataset_definition exist. Now we must check if it has enough itemcount
516 if ($definitionrec->itemcount < $dataset_definition->itemcount) {
517 //We haven't enough itemcount, so we have to create the definition as an individual question one.
518 $dataset_definition->category = 0;
519 $create_definition = true;
520 } else {
521 //We have enough itemcount, so we'll reuse the existing definition
522 $create_definition = false;
523 $newid = $definitionrec->id;
525 } else {
526 //Such dataset_definition doesn't exist. We'll create it.
527 $create_definition = true;
531 //If we've to create the definition, do it
532 if ($create_definition) {
533 //The structure is equal to the db, so insert the question_dataset_definitions
534 $newid = insert_record ("question_dataset_definitions",$dataset_definition);
535 if ($newid) {
536 //Restore question_dataset_items
537 $status = question_restore_dataset_items($newid,$dd_info,$restore);
541 //Now, we must have a definition (created o reused). Its id is in newid. Create the question_datasets record
542 //to join the question and the dataset_definition
543 if ($newid) {
544 $question_dataset = new stdClass;
545 $question_dataset->question = $new_question_id;
546 $question_dataset->datasetdefinition = $newid;
547 $newid = insert_record ("question_datasets",$question_dataset);
550 if (!$newid) {
551 $status = false;
555 return $status;
558 function question_restore_dataset_items ($definitionid,$info,$restore) {
560 global $CFG;
562 $status = true;
564 //Get the items array
565 $dataset_items = $info['#']['DATASET_ITEMS']['0']['#']['DATASET_ITEM'];
567 //Iterate over dataset_items
568 for($i = 0; $i < sizeof($dataset_items); $i++) {
569 $di_info = $dataset_items[$i];
570 //traverse_xmlize($di_info); //Debug
571 //print_object ($GLOBALS['traverse_array']); //Debug
572 //$GLOBALS['traverse_array']=""; //Debug
574 //Now, build the question_dataset_ITEMS record structure
575 $dataset_item = new stdClass;
576 $dataset_item->definition = $definitionid;
577 $dataset_item->itemnumber = backup_todb($di_info['#']['NUMBER']['0']['#']);
578 $dataset_item->value = backup_todb($di_info['#']['VALUE']['0']['#']);
580 //The structure is equal to the db, so insert the question_dataset_items
581 $newid = insert_record ("question_dataset_items",$dataset_item);
583 if (!$newid) {
584 $status = false;
588 return $status;
592 //This function restores the question_states
593 function question_states_restore_mods($attempt_id,$info,$restore) {
595 global $CFG, $QTYPES;
597 $status = true;
599 //Get the question_states array
600 $states = $info['#']['STATES']['0']['#']['STATE'];
601 //Iterate over states
602 for($i = 0; $i < sizeof($states); $i++) {
603 $res_info = $states[$i];
604 //traverse_xmlize($res_info); //Debug
605 //print_object ($GLOBALS['traverse_array']); //Debug
606 //$GLOBALS['traverse_array']=""; //Debug
608 //We'll need this later!!
609 $oldid = backup_todb($res_info['#']['ID']['0']['#']);
611 //Now, build the STATES record structure
612 $state = new stdClass;
613 $state->attempt = $attempt_id;
614 $state->question = backup_todb($res_info['#']['QUESTION']['0']['#']);
615 $state->originalquestion = backup_todb($res_info['#']['ORIGINALQUESTION']['0']['#']);
616 $state->seq_number = backup_todb($res_info['#']['SEQ_NUMBER']['0']['#']);
617 $state->answer = backup_todb($res_info['#']['ANSWER']['0']['#']);
618 $state->timestamp = backup_todb($res_info['#']['TIMESTAMP']['0']['#']);
619 $state->event = backup_todb($res_info['#']['EVENT']['0']['#']);
620 $state->grade = backup_todb($res_info['#']['GRADE']['0']['#']);
621 $state->raw_grade = backup_todb($res_info['#']['RAW_GRADE']['0']['#']);
622 $state->penalty = backup_todb($res_info['#']['PENALTY']['0']['#']);
623 $state->oldid = $oldid; // So it is available to restore_recode_answer.
625 //We have to recode the question field
626 $question = backup_getid($restore->backup_unique_code,"question",$state->question);
627 if ($question) {
628 $state->question = $question->new_id;
629 } else {
630 echo 'Could not recode question id '.$state->question.' for state '.$oldid.'<br />';
633 //We have to recode the originalquestion field if it is nonzero
634 if ($state->originalquestion) {
635 $question = backup_getid($restore->backup_unique_code,"question",$state->originalquestion);
636 if ($question) {
637 $state->originalquestion = $question->new_id;
638 } else {
639 echo 'Could not recode originalquestion id '.$state->question.' for state '.$oldid.'<br />';
643 //We have to recode the answer field
644 //It depends of the question type !!
645 //We get the question first
646 if (!$question = get_record("question","id",$state->question)) {
647 error("Can't find the record for question $state->question for which I am trying to restore a state");
649 //Depending on the qtype, we make different recodes
650 if ($state->answer) {
651 $state->answer = $QTYPES[$question->qtype]->restore_recode_answer($state, $restore);
654 //The structure is equal to the db, so insert the question_states
655 $newid = insert_record ("question_states",$state);
657 //Do some output
658 if (($i+1) % 10 == 0) {
659 if (!defined('RESTORE_SILENTLY')) {
660 echo ".";
661 if (($i+1) % 200 == 0) {
662 echo "<br />";
665 backup_flush(300);
668 if ($newid) {
669 //We have the newid, update backup_ids
670 backup_putid($restore->backup_unique_code,"question_states",$oldid,
671 $newid);
672 //Now process question type specific state information
673 $qtype = get_field('question', 'qtype', 'id', $state->question);
674 $status = $QTYPES[$qtype]->restore_state($newid,$res_info,$restore);
675 } else {
676 $status = false;
680 //Get the question_sessions array
681 $sessions = $info['#']['NEWEST_STATES']['0']['#']['NEWEST_STATE'];
682 //Iterate over question_sessions
683 for($i = 0; $i < sizeof($sessions); $i++) {
684 $res_info = $sessions[$i];
685 //traverse_xmlize($res_info); //Debug
686 //print_object ($GLOBALS['traverse_array']); //Debug
687 //$GLOBALS['traverse_array']=""; //Debug
689 //Now, build the NEWEST_STATES record structure
690 $session = new stdClass;
691 $session->attemptid = $attempt_id;
692 $session->questionid = backup_todb($res_info['#']['QUESTIONID']['0']['#']);
693 $session->newest = backup_todb($res_info['#']['NEWEST']['0']['#']);
694 $session->newgraded = backup_todb($res_info['#']['NEWGRADED']['0']['#']);
695 $session->sumpenalty = backup_todb($res_info['#']['SUMPENALTY']['0']['#']);
697 //We have to recode the question field
698 $question = backup_getid($restore->backup_unique_code,"question",$session->questionid);
699 if ($question) {
700 $session->questionid = $question->new_id;
701 } else {
702 echo 'Could not recode question id '.$session->questionid.'<br />';
705 //We have to recode the newest field
706 $state = backup_getid($restore->backup_unique_code,"question_states",$session->newest);
707 if ($state) {
708 $session->newest = $state->new_id;
709 } else {
710 echo 'Could not recode newest state id '.$session->newest.'<br />';
713 //If the session has been graded we have to recode the newgraded field
714 if ($session->newgraded) {
715 $state = backup_getid($restore->backup_unique_code,"question_states",$session->newgraded);
716 if ($state) {
717 $session->newgraded = $state->new_id;
718 } else {
719 echo 'Could not recode newest graded state id '.$session->newgraded.'<br />';
723 //The structure is equal to the db, so insert the question_sessions
724 $newid = insert_record ("question_sessions",$session);
728 return $status;