]> git.mjollnir.org Git - moodle.git/commitdiff
Moving the backup libraries for each module into their new homes.
authormoodler <moodler>
Wed, 9 Jul 2003 04:40:35 +0000 (04:40 +0000)
committermoodler <moodler>
Wed, 9 Jul 2003 04:40:35 +0000 (04:40 +0000)
There's some beer and pies in the fridge, guys, settle in.

12 files changed:
mod/assignment/backuplib.php [new file with mode: 0644]
mod/assignment/restorelib.php [new file with mode: 0644]
mod/choice/backuplib.php [new file with mode: 0644]
mod/choice/restorelib.php [new file with mode: 0644]
mod/journal/backuplib.php [new file with mode: 0644]
mod/journal/restorelib.php [new file with mode: 0644]
mod/quiz/backuplib.php [new file with mode: 0644]
mod/quiz/restorelib.php [new file with mode: 0644]
mod/resource/backuplib.php [new file with mode: 0644]
mod/resource/restorelib.php [new file with mode: 0644]
mod/survey/backuplib.php [new file with mode: 0644]
mod/survey/restorelib.php [new file with mode: 0644]

diff --git a/mod/assignment/backuplib.php b/mod/assignment/backuplib.php
new file mode 100644 (file)
index 0000000..eced064
--- /dev/null
@@ -0,0 +1,176 @@
+<?PHP //$Id$
+    //This php script contains all the stuff to backup/restore
+    //assignment mods
+
+    //This is the "graphical" structure of the assignment mod:
+    //
+    //                     assignment
+    //                    (CL,pk->id)             
+    //                        |
+    //                        |
+    //                        |
+    //                 assignment_submisions 
+    //           (UL,pk->id, fk->assignment,files)
+    //
+    // Meaning: pk->primary key field of the table
+    //          fk->foreign key to link with parent
+    //          nt->nested field (recursive data)
+    //          CL->course level info
+    //          UL->user level info
+    //          files->table may have files)
+    //
+    //-----------------------------------------------------------
+
+    //This function executes all the backup procedure about this mod
+    function assignment_backup_mods($bf,$preferences) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Iterate over assignment table
+        $assignments = get_records ("assignment","course",$preferences->backup_course,"id");
+        if ($assignments) {
+            foreach ($assignments as $assignment) {
+                //Start mod
+                fwrite ($bf,start_tag("MOD",3,true));
+                //Print assignment data
+                fwrite ($bf,full_tag("ID",4,false,$assignment->id));
+                fwrite ($bf,full_tag("MODTYPE",4,false,"assignment"));
+                fwrite ($bf,full_tag("NAME",4,false,$assignment->name));
+                fwrite ($bf,full_tag("DESCRIPTION",4,false,$assignment->description));
+                fwrite ($bf,full_tag("FORMAT",4,false,$assignment->format));
+                fwrite ($bf,full_tag("RESUBMIT",4,false,$assignment->resubmit));
+                fwrite ($bf,full_tag("TYPE",4,false,$assignment->type));
+                fwrite ($bf,full_tag("MAXBYTES",4,false,$assignment->maxbytes));
+                fwrite ($bf,full_tag("TIMEDUE",4,false,$assignment->timedue));
+                fwrite ($bf,full_tag("GRADE",4,false,$assignment->grade));
+                fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$assignment->timemodified));
+                //if we've selected to backup users info, then execute backup_assignment_submisions
+                if ($preferences->mods["assignment"]->userinfo) {
+                    $status = backup_assignment_submissions($bf,$preferences,$assignment->id);
+                }
+                //End mod
+                $status =fwrite ($bf,end_tag("MOD",3,true));
+            }
+        }
+        //if we've selected to backup users info, then backup files too
+        if ($status) {
+            if ($preferences->mods["assignment"]->userinfo) {
+                $status = backup_assignment_files($bf,$preferences);
+            }
+        }
+        return $status;  
+    }
+
+    //Backup assignment_submissions contents (executed from assignment_backup_mods)
+    function backup_assignment_submissions ($bf,$preferences,$assignment) {
+
+        global $CFG;
+
+        $status = true;
+
+        $assignment_submissions = get_records("assignment_submissions","assignment",$assignment,"id");
+        //If there is submissions
+        if ($assignment_submissions) {
+            //Write start tag
+            $status =fwrite ($bf,start_tag("SUBMISSIONS",4,true));
+            //Iterate over each submission
+            foreach ($assignment_submissions as $ass_sub) {
+                //Start submission
+                $status =fwrite ($bf,start_tag("SUBMISSION",5,true));
+                //Print submission contents
+                fwrite ($bf,full_tag("ID",6,false,$ass_sub->id));       
+                fwrite ($bf,full_tag("USERID",6,false,$ass_sub->userid));       
+                fwrite ($bf,full_tag("TIMECREATED",6,false,$ass_sub->timecreated));       
+                fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$ass_sub->timemodified));       
+                fwrite ($bf,full_tag("NUMFILES",6,false,$ass_sub->numfiles));       
+                fwrite ($bf,full_tag("GRADE",6,false,$ass_sub->grade));       
+                fwrite ($bf,full_tag("COMMENT",6,false,$ass_sub->comment));       
+                fwrite ($bf,full_tag("TEACHER",6,false,$ass_sub->teacher));       
+                fwrite ($bf,full_tag("TIMEMARKED",6,false,$ass_sub->timemarked));       
+                fwrite ($bf,full_tag("MAILED",6,false,$ass_sub->mailed));       
+                //End submission
+                $status =fwrite ($bf,end_tag("SUBMISSION",5,true));
+            }
+            //Write end tag
+            $status =fwrite ($bf,end_tag("SUBMISSIONS",4,true));
+        }
+        return $status;
+    }
+
+    //Backup assignment files because we've selected to backup user info
+    //and files are user info's level
+    function backup_assignment_files($bf,$preferences) {
+
+        global $CFG;
+       
+        $status = true;
+
+        //First we check to moddata exists and create it as necessary
+        //in temp/backup/$backup_code  dir
+        $status = check_and_create_moddata_dir($preferences->backup_unique_code);
+        //Now copy the assignment dir
+        if ($status) {
+            //Only if it exists !! Thanks to Daniel Miksik.
+            if (is_dir($CFG->dataroot."/".$preferences->backup_course."/".$CFG->moddata."/assignment")) {
+                $status = backup_copy_file($CFG->dataroot."/".$preferences->backup_course."/".$CFG->moddata."/assignment",
+                                           $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/moddata/assignment");
+            }
+        }
+
+        return $status;
+
+    } 
+
+    //Return an array of info (name,value)
+    function assignment_check_backup_mods($course,$user_data=false,$backup_unique_code) {
+        //First the course data
+        $info[0][0] = get_string("modulenameplural","assignment");
+        if ($ids = assignment_ids ($course)) {
+            $info[0][1] = count($ids);
+        } else {
+            $info[0][1] = 0;
+        }
+
+        //Now, if requested, the user_data
+        if ($user_data) {
+            $info[1][0] = get_string("submissions","assignment");
+            if ($ids = assignment_submission_ids_by_course ($course)) { 
+                $info[1][1] = count($ids);
+            } else {
+                $info[1][1] = 0;
+            }
+        }
+        return $info;
+    }
+
+
+
+
+
+
+    // INTERNAL FUNCTIONS. BASED IN THE MOD STRUCTURE
+
+    //Returns an array of assignments id 
+    function assignment_ids ($course) {
+
+        global $CFG;
+
+        return get_records_sql ("SELECT a.id, a.course
+                                 FROM {$CFG->prefix}assignment a
+                                 WHERE a.course = '$course'");
+    }
+    
+    //Returns an array of assignment_submissions id
+    function assignment_submission_ids_by_course ($course) {
+
+        global $CFG;
+
+        return get_records_sql ("SELECT s.id , s.assignment
+                                 FROM {$CFG->prefix}assignment_submissions s,
+                                      {$CFG->prefix}assignment a
+                                 WHERE a.course = '$course' AND
+                                       s.assignment = a.id");
+    }
+?>
diff --git a/mod/assignment/restorelib.php b/mod/assignment/restorelib.php
new file mode 100644 (file)
index 0000000..25a3d4b
--- /dev/null
@@ -0,0 +1,205 @@
+<?PHP //$Id$
+    //This php script contains all the stuff to backup/restore
+    //assignment mods
+
+    //This is the "graphical" structure of the assignment mod:
+    //
+    //                     assignment
+    //                    (CL,pk->id)             
+    //                        |
+    //                        |
+    //                        |
+    //                 assignment_submisions 
+    //           (UL,pk->id, fk->assignment,files)
+    //
+    // Meaning: pk->primary key field of the table
+    //          fk->foreign key to link with parent
+    //          nt->nested field (recursive data)
+    //          CL->course level info
+    //          UL->user level info
+    //          files->table may have files)
+    //
+    //-----------------------------------------------------------
+
+    //This function executes all the restore procedure about this mod
+    function assignment_restore_mods($mod,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get record from backup_ids
+        $data = backup_getid($restore->backup_unique_code,$mod->modtype,$mod->id);
+
+        if ($data) {
+            //Now get completed xmlized object   
+            $info = $data->info;
+            //traverse_xmlize($info);                                                                     //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //Now, build the ASSIGNMENT record structure
+            $assignment->course = $restore->course_id;
+            $assignment->name = backup_todb($info['MOD']['#']['NAME']['0']['#']);
+            $assignment->description = backup_todb($info['MOD']['#']['DESCRIPTION']['0']['#']);
+            $assignment->format = backup_todb($info['MOD']['#']['FORMAT']['0']['#']);
+            $assignment->resubmit = backup_todb($info['MOD']['#']['RESUBMIT']['0']['#']);
+            $assignment->type = backup_todb($info['MOD']['#']['TYPE']['0']['#']);
+            $assignment->maxbytes = backup_todb($info['MOD']['#']['MAXBYTES']['0']['#']);
+            $assignment->timedue = backup_todb($info['MOD']['#']['TIMEDUE']['0']['#']);
+            $assignment->grade = backup_todb($info['MOD']['#']['GRADE']['0']['#']);
+            $assignment->timemodified = backup_todb($info['MOD']['#']['TIMEMODIFIED']['0']['#']);
+
+            //The structure is equal to the db, so insert the assignment
+            $newid = insert_record ("assignment",$assignment);
+
+            //Do some output     
+            echo "<ul><li>Assignment \"".$assignment->name."\"<br>";
+            backup_flush(300);
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,$mod->modtype,
+                             $mod->id, $newid);
+                //Now check if want to restore user data and do it.
+                if ($restore->mods[assignment]->userinfo) {
+                    //Restore assignmet_submissions
+                    $status = assignment_submissions_restore_mods ($mod->id, $newid,$info,$restore);
+                }
+            } else {
+                $status = false;
+            }
+
+            //Finalize ul        
+            echo "</ul>";
+        
+        } else {
+            $status = false;
+        }
+
+        return $status;
+    }
+
+    //This function restores the assignment_submissions
+    function assignment_submissions_restore_mods($old_assignment_id, $new_assignment_id,$info,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get the submissions array 
+        $submissions = $info['MOD']['#']['SUBMISSIONS']['0']['#']['SUBMISSION'];
+
+        //Iterate over submissions
+        for($i = 0; $i < sizeof($submissions); $i++) {
+            $sub_info = $submissions[$i];
+            //traverse_xmlize($sub_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //We'll need this later!!
+            $oldid = backup_todb($sub_info['#']['ID']['0']['#']);
+            $olduserid = backup_todb($sub_info['#']['USERID']['0']['#']);
+
+            //Now, build the ASSIGNMENT_SUBMISSIONS record structure
+            $submission->assignment = $new_assignment_id;
+            $submission->userid = backup_todb($sub_info['#']['USERID']['0']['#']);
+            $submission->timecreated = backup_todb($sub_info['#']['TIMECREATED']['0']['#']);
+            $submission->timemodified = backup_todb($sub_info['#']['TIMEMODIFIED']['0']['#']);
+            $submission->numfiles = backup_todb($sub_info['#']['NUMFILES']['0']['#']);
+            $submission->grade = backup_todb($sub_info['#']['GRADE']['0']['#']);
+            $submission->comment = backup_todb($sub_info['#']['COMMENT']['0']['#']);
+            $submission->teacher = backup_todb($sub_info['#']['TEACHER']['0']['#']);
+            $submission->timemarked = backup_todb($sub_info['#']['TIMEMARKED']['0']['#']);
+            $submission->mailed = backup_todb($sub_info['#']['MAILED']['0']['#']);
+
+            //We have to recode the userid field
+            $user = backup_getid($restore->backup_unique_code,"user",$submission->userid);
+            if ($user) {
+                $submission->userid = $user->new_id;
+            }
+
+            //We have to recode the teacher field
+            $user = backup_getid($restore->backup_unique_code,"user",$submission->teacher);
+            if ($user) {
+                $submission->teacher = $user->new_id;
+            } 
+
+            //The structure is equal to the db, so insert the assignment_submission
+            $newid = insert_record ("assignment_submissions",$submission);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                echo ".";
+                if (($i+1) % 1000 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"assignment_submission",$oldid,
+                             $newid);
+
+                //Now copy moddata associated files
+                $status = assignment_restore_files ($old_assignment_id, $new_assignment_id, 
+                                                    $olduserid, $submission->userid, $restore);
+
+            } else {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+    //This function copies the assignment related info from backup temp dir to course moddata folder,
+    //creating it if needed and recoding everything (assignment id and user id) 
+    function assignment_restore_files ($oldassid, $newassid, $olduserid, $newuserid, $restore) {
+
+        global $CFG;
+
+        $status = true;
+        $todo = false;
+        $moddata_path = "";
+        $assignment_path = "";
+        $temp_path = "";
+
+        //First, locate course's moddata directory
+        $moddata_path = $CFG->dataroot."/".$restore->course_id."/".$CFG->moddata;
+   
+        //Check it exists and create it
+        $status = check_dir_exists($moddata_path,true);
+
+        //Now, locate assignment directory
+        if ($status) {
+            $assignment_path = $moddata_path."/assignment";
+            //Check it exists and create it
+            $status = check_dir_exists($assignment_path,true);
+        }
+
+        //Now locate the temp dir we are gong to restore
+        if ($status) {
+            $temp_path = $CFG->dataroot."/temp/backup/".$restore->backup_unique_code.
+                         "/moddata/assignment/".$oldassid."/".$olduserid;
+            //Check it exists
+            if (is_dir($temp_path)) {
+                $todo = true;
+            }
+        }
+
+        //If todo, we create the neccesary dirs in course moddata/assignment
+        if ($status and $todo) {
+            //First this assignment id
+            $this_assignment_path = $assignment_path."/".$newassid;
+            $status = check_dir_exists($this_assignment_path,true);
+            //Now this user id
+            $user_assignment_path = $this_assignment_path."/".$newuserid;
+            //And now, copy temp_path to user_assignment_path
+            $status = backup_copy_file($temp_path, $user_assignment_path); 
+        }
+       
+        return $status;
+    }
+?>
diff --git a/mod/choice/backuplib.php b/mod/choice/backuplib.php
new file mode 100644 (file)
index 0000000..b9abb98
--- /dev/null
@@ -0,0 +1,141 @@
+<?PHP //$Id$
+    //This php script contains all the stuff to backup/restore
+    //choice mods
+
+    //This is the "graphical" structure of the choice mod:
+    //
+    //                      choice                                      
+    //                    (CL,pk->id)
+    //                        |
+    //                        |
+    //                        |
+    //                   choice_answers 
+    //               (UL,pk->id, fk->choice)     
+    //
+    // Meaning: pk->primary key field of the table
+    //          fk->foreign key to link with parent
+    //          nt->nested field (recursive data)
+    //          CL->course level info
+    //          UL->user level info
+    //          files->table may have files)
+    //
+    //-----------------------------------------------------------
+
+    function choice_backup_mods($bf,$preferences) {
+        
+        global $CFG;
+
+        $status = true;
+
+        //Iterate over choice table
+        $choices = get_records ("choice","course",$preferences->backup_course,"id");
+        if ($choices) {
+            foreach ($choices as $choice) {
+                //Start mod
+                fwrite ($bf,start_tag("MOD",3,true));
+                //Print choice data
+                fwrite ($bf,full_tag("ID",4,false,$choice->id));
+                fwrite ($bf,full_tag("MODTYPE",4,false,"choice"));
+                fwrite ($bf,full_tag("NAME",4,false,$choice->name));
+                fwrite ($bf,full_tag("TEXT",4,false,$choice->text));
+                fwrite ($bf,full_tag("FORMAT",4,false,$choice->format));
+                fwrite ($bf,full_tag("ANSWER1",4,false,$choice->answer1));
+                fwrite ($bf,full_tag("ANSWER2",4,false,$choice->answer2));
+                fwrite ($bf,full_tag("ANSWER3",4,false,$choice->answer3));
+                fwrite ($bf,full_tag("ANSWER4",4,false,$choice->answer4));
+                fwrite ($bf,full_tag("ANSWER5",4,false,$choice->answer5));
+                fwrite ($bf,full_tag("ANSWER6",4,false,$choice->answer6));
+                fwrite ($bf,full_tag("PUBLISH",4,false,$choice->publish));
+                fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$choice->timemodified));
+                //if we've selected to backup users info, then execute backup_choice_answers
+                if ($preferences->mods["choice"]->userinfo) {
+                    $status = backup_choice_answers($bf,$preferences,$choice->id);
+                }
+                //End mod
+                $status =fwrite ($bf,end_tag("MOD",3,true));
+            }
+        }
+        return $status;
+    }
+
+    //Backup choice_answers contents (executed from choice_backup_mods)
+    function backup_choice_answers ($bf,$preferences,$choice) {
+
+        global $CFG;
+
+        $status = true;
+
+        $choice_answers = get_records("choice_answers","choice",$choice,"id");
+        //If there is submissions
+        if ($choice_answers) {
+            //Write start tag
+            $status =fwrite ($bf,start_tag("ANSWERS",4,true));
+            //Iterate over each answer
+            foreach ($choice_answers as $cho_ans) {
+                //Start answer
+                $status =fwrite ($bf,start_tag("ANSWER",5,true));
+                //Print submission contents
+                fwrite ($bf,full_tag("ID",6,false,$cho_ans->id));
+                fwrite ($bf,full_tag("USERID",6,false,$cho_ans->userid));
+                fwrite ($bf,full_tag("CHOICE_ANSWER",6,false,$cho_ans->answer));
+                fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$cho_ans->timemodified));
+                //End answer
+                $status =fwrite ($bf,end_tag("ANSWER",5,true));
+            }
+            //Write end tag
+            $status =fwrite ($bf,end_tag("ANSWERS",4,true));
+        }
+        return $status;
+    }
+   
+   ////Return an array of info (name,value)
+   function choice_check_backup_mods($course,$user_data=false,$backup_unique_code) {
+        //First the course data
+        $info[0][0] = get_string("modulenameplural","choice");
+        if ($ids = choice_ids ($course)) {
+            $info[0][1] = count($ids);
+        } else {
+            $info[0][1] = 0;
+        }
+
+        //Now, if requested, the user_data
+        if ($user_data) {
+            $info[1][0] = get_string("responses","choice");
+            if ($ids = choice_answer_ids_by_course ($course)) {
+                $info[1][1] = count($ids);
+            } else {
+                $info[1][1] = 0;
+            }
+        }
+        return $info;
+    }
+
+
+
+
+
+
+    // INTERNAL FUNCTIONS. BASED IN THE MOD STRUCTURE
+
+    //Returns an array of choices id
+    function choice_ids ($course) {
+
+        global $CFG;
+
+        return get_records_sql ("SELECT a.id, a.course
+                                 FROM {$CFG->prefix}choice a
+                                 WHERE a.course = '$course'");
+    }
+   
+    //Returns an array of choice_answers id
+    function choice_answer_ids_by_course ($course) {
+
+        global $CFG;
+
+        return get_records_sql ("SELECT s.id , s.choice
+                                 FROM {$CFG->prefix}choice_answers s,
+                                      {$CFG->prefix}choice a
+                                 WHERE a.course = '$course' AND
+                                       s.choice = a.id");
+    }
+?>
diff --git a/mod/choice/restorelib.php b/mod/choice/restorelib.php
new file mode 100644 (file)
index 0000000..bbdff4f
--- /dev/null
@@ -0,0 +1,142 @@
+<?PHP //$Id$
+    //This php script contains all the stuff to backup/restore
+    //choice mods
+
+    //This is the "graphical" structure of the choice mod:
+    //
+    //                      choice                                      
+    //                    (CL,pk->id)
+    //                        |
+    //                        |
+    //                        |
+    //                   choice_answers 
+    //               (UL,pk->id, fk->choice)     
+    //
+    // Meaning: pk->primary key field of the table
+    //          fk->foreign key to link with parent
+    //          nt->nested field (recursive data)
+    //          CL->course level info
+    //          UL->user level info
+    //          files->table may have files)
+    //
+    //-----------------------------------------------------------
+
+    //This function executes all the restore procedure about this mod
+    function choice_restore_mods($mod,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get record from backup_ids
+        $data = backup_getid($restore->backup_unique_code,$mod->modtype,$mod->id);
+
+        if ($data) {
+            //Now get completed xmlized object
+            $info = $data->info;
+            //traverse_xmlize($info);                                                                     //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //Now, build the CHOICE record structure
+            $choice->course = $restore->course_id;
+            $choice->name = backup_todb($info['MOD']['#']['NAME']['0']['#']);
+            $choice->text = backup_todb($info['MOD']['#']['TEXT']['0']['#']);
+            $choice->format = backup_todb($info['MOD']['#']['FORMAT']['0']['#']);
+            $choice->answer1 = backup_todb($info['MOD']['#']['ANSWER1']['0']['#']);
+            $choice->answer2 = backup_todb($info['MOD']['#']['ANSWER2']['0']['#']);
+            $choice->answer3 = backup_todb($info['MOD']['#']['ANSWER3']['0']['#']);
+            $choice->answer4 = backup_todb($info['MOD']['#']['ANSWER4']['0']['#']);
+            $choice->answer5 = backup_todb($info['MOD']['#']['ANSWER5']['0']['#']);
+            $choice->answer6 = backup_todb($info['MOD']['#']['ANSWER6']['0']['#']);
+            $choice->publish = backup_todb($info['MOD']['#']['PUBLISH']['0']['#']);
+            $choice->timemodified = backup_todb($info['MOD']['#']['TIMEMODIFIED']['0']['#']);
+
+            //The structure is equal to the db, so insert the choice
+            $newid = insert_record ("choice",$choice);
+
+            //Do some output     
+            echo "<ul><li>Choice \"".$choice->name."\"<br>";
+            backup_flush(300);
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,$mod->modtype,
+                             $mod->id, $newid);
+                //Now check if want to restore user data and do it.
+                if ($restore->mods[choice]->userinfo) {
+                    //Restore choice_answers
+                    $status = choice_answers_restore_mods ($newid,$info,$restore);
+                }
+            } else {
+                $status = false;
+            }
+
+            //Finalize ul        
+            echo "</ul>";
+
+        } else {
+            $status = false;
+        }
+
+        return $status;
+    }
+
+    //This function restores the choice_answers
+    function choice_answers_restore_mods($choice_id,$info,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get the answers array
+        $answers = $info['MOD']['#']['ANSWERS']['0']['#']['ANSWER'];
+
+        //Iterate over answers
+        for($i = 0; $i < sizeof($answers); $i++) {
+            $sub_info = $answers[$i];
+            //traverse_xmlize($sub_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //We'll need this later!!
+            $oldid = backup_todb($sub_info['#']['ID']['0']['#']);
+            $olduserid = backup_todb($sub_info['#']['USERID']['0']['#']);
+
+            //Now, build the CHOICE_ANSWERS record structure
+            $answer->choice = $choice_id;
+            $answer->userid = backup_todb($sub_info['#']['USERID']['0']['#']);
+            $answer->answer = backup_todb($sub_info['#']['CHOICE_ANSWER']['0']['#']);
+            $answer->timemodified = backup_todb($sub_info['#']['TIMEMODIFIED']['0']['#']);
+
+            //We have to recode the userid field
+            $user = backup_getid($restore->backup_unique_code,"user",$answer->userid);
+            if ($user) {
+                $answer->userid = $user->new_id;
+            }
+
+            //The structure is equal to the db, so insert the choice_answers
+            $newid = insert_record ("choice_answers",$answer);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                echo ".";
+                if (($i+1) % 1000 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"choice_answers",$oldid,
+                             $newid);
+            } else {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+?>
diff --git a/mod/journal/backuplib.php b/mod/journal/backuplib.php
new file mode 100644 (file)
index 0000000..321608f
--- /dev/null
@@ -0,0 +1,142 @@
+<?PHP //$Id$
+    //This php script contains all the stuff to backup/restore
+    //journal mods
+
+    //This is the "graphical" structure of the journal mod:
+    //
+    //                      journal                                      
+    //                    (CL,pk->id)
+    //                        |
+    //                        |
+    //                        |
+    //                   journal_entries 
+    //               (UL,pk->id, fk->journal)     
+    //
+    // Meaning: pk->primary key field of the table
+    //          fk->foreign key to link with parent
+    //          nt->nested field (recursive data)
+    //          CL->course level info
+    //          UL->user level info
+    //          files->table may have files)
+    //
+    //-----------------------------------------------------------
+
+    function journal_backup_mods($bf,$preferences) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Iterate over journal table
+        $journals = get_records ("journal","course",$preferences->backup_course,"id");
+        if ($journals) {
+            foreach ($journals as $journal) {
+                //Start mod
+                fwrite ($bf,start_tag("MOD",3,true));
+                //Print journal data
+                fwrite ($bf,full_tag("ID",4,false,$journal->id));
+                fwrite ($bf,full_tag("MODTYPE",4,false,"journal"));
+                fwrite ($bf,full_tag("NAME",4,false,$journal->name));
+                fwrite ($bf,full_tag("INTRO",4,false,$journal->intro));
+                fwrite ($bf,full_tag("DAYS",4,false,$journal->days));
+                fwrite ($bf,full_tag("ASSESSED",4,false,$journal->assessed));
+                fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$journal->timemodified));
+
+                //if we've selected to backup users info, then execute backup_journal_entries
+                if ($preferences->mods["journal"]->userinfo) {
+                    $status = backup_journal_entries($bf,$preferences,$journal->id);
+                }
+                //End mod
+                $status =fwrite ($bf,end_tag("MOD",3,true));
+            }
+        }
+        return $status;
+    }
+
+    //Backup journal_entries contents (executed from journal_backup_mods)
+    function backup_journal_entries ($bf,$preferences,$journal) {
+
+        global $CFG;
+
+        $status = true;
+
+        $journal_entries = get_records("journal_entries","journal",$journal,"id");
+        //If there is entries
+        if ($journal_entries) {
+            //Write start tag
+            $status =fwrite ($bf,start_tag("ENTRIES",4,true));
+            //Iterate over each entry
+            foreach ($journal_entries as $jou_ent) {
+                //Start entry
+                $status =fwrite ($bf,start_tag("ENTRY",5,true));
+                //Print journal_entries contents
+                fwrite ($bf,full_tag("ID",6,false,$jou_ent->id));
+                fwrite ($bf,full_tag("USERID",6,false,$jou_ent->userid));
+                fwrite ($bf,full_tag("MODIFIED",6,false,$jou_ent->modified));
+                fwrite ($bf,full_tag("TEXT",6,false,$jou_ent->text));
+                fwrite ($bf,full_tag("FORMAT",6,false,$jou_ent->format));
+                fwrite ($bf,full_tag("RATING",6,false,$jou_ent->rating));
+                fwrite ($bf,full_tag("COMMENT",6,false,$jou_ent->comment));
+                fwrite ($bf,full_tag("TEACHER",6,false,$jou_ent->teacher));
+                fwrite ($bf,full_tag("TIMEMARKED",6,false,$jou_ent->timemarked));
+                fwrite ($bf,full_tag("MAILED",6,false,$jou_ent->mailed));
+                //End entry
+                $status =fwrite ($bf,end_tag("ENTRY",5,true));
+            }
+            //Write end tag
+            $status =fwrite ($bf,end_tag("ENTRIES",4,true));
+        }
+        return $status;
+    }
+   ////Return an array of info (name,value)
+   function journal_check_backup_mods($course,$user_data=false,$backup_unique_code) {
+        //First the course data
+        $info[0][0] = get_string("modulenameplural","journal");
+        if ($ids = journal_ids ($course)) {
+            $info[0][1] = count($ids);
+        } else {
+            $info[0][1] = 0;
+        }
+
+        //Now, if requested, the user_data
+        if ($user_data) {
+            $info[1][0] = get_string("entries","journal");
+            if ($ids = journal_entry_ids_by_course ($course)) {
+                $info[1][1] = count($ids);
+            } else {
+                $info[1][1] = 0;
+            }
+        }
+        return $info;
+    }
+
+
+
+
+
+
+    // INTERNAL FUNCTIONS. BASED IN THE MOD STRUCTURE
+
+    //Returns an array of journals id
+    function journal_ids ($course) {
+
+        global $CFG;
+
+        return get_records_sql ("SELECT a.id, a.course
+                                 FROM {$CFG->prefix}journal a
+                                 WHERE a.course = '$course'");
+    }
+   
+    //Returns an array of journal entries id
+    function journal_entry_ids_by_course ($course) {
+
+        global $CFG;
+
+        return get_records_sql ("SELECT s.id , s.journal
+                                 FROM {$CFG->prefix}journal_entries s,
+                                      {$CFG->prefix}journal a
+                                 WHERE a.course = '$course' AND
+                                       s.journal = a.id");
+    }
+?>
diff --git a/mod/journal/restorelib.php b/mod/journal/restorelib.php
new file mode 100644 (file)
index 0000000..0f654c6
--- /dev/null
@@ -0,0 +1,149 @@
+<?PHP //$Id$
+    //This php script contains all the stuff to backup/restore
+    //journal mods
+
+    //This is the "graphical" structure of the journal mod:
+    //
+    //                      journal                                      
+    //                    (CL,pk->id)
+    //                        |
+    //                        |
+    //                        |
+    //                   journal_entries 
+    //               (UL,pk->id, fk->journal)     
+    //
+    // Meaning: pk->primary key field of the table
+    //          fk->foreign key to link with parent
+    //          nt->nested field (recursive data)
+    //          CL->course level info
+    //          UL->user level info
+    //          files->table may have files)
+    //
+    //-----------------------------------------------------------
+
+    //This function executes all the restore procedure about this mod
+    function journal_restore_mods($mod,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get record from backup_ids
+        $data = backup_getid($restore->backup_unique_code,$mod->modtype,$mod->id);
+
+        if ($data) {
+            //Now get completed xmlized object
+            $info = $data->info;
+            //traverse_xmlize($info);                                                                     //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //Now, build the JOURNAL record structure
+            $journal->course = $restore->course_id;
+            $journal->name = backup_todb($info['MOD']['#']['NAME']['0']['#']);
+            $journal->intro = backup_todb($info['MOD']['#']['INTRO']['0']['#']);
+            $journal->days = backup_todb($info['MOD']['#']['DAYS']['0']['#']);
+            $journal->assessed = backup_todb($info['MOD']['#']['ASSESSED']['0']['#']);
+            $journal->timemodified = backup_todb($info['MOD']['#']['TIMEMODIFIED']['0']['#']);
+
+            //The structure is equal to the db, so insert the journal
+            $newid = insert_record ("journal",$journal);
+
+            //Do some output
+            echo "<ul><li>Journal \"".$journal->name."\"<br>";
+            backup_flush(300);
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,$mod->modtype,
+                             $mod->id, $newid);
+                //Now check if want to restore user data and do it.
+                if ($restore->mods[journal]->userinfo) {
+                    //Restore journal_entries
+                    $status = journal_entries_restore_mods ($mod->id, $newid,$info,$restore);
+                }
+            } else {
+                $status = false;
+            }
+
+            //Finalize ul
+            echo "</ul>";
+
+        } else {
+            $status = false;
+        }
+
+        return $status;
+    }
+
+
+    //This function restores the journal_entries
+    function journal_entries_restore_mods($old_journal_id, $new_journal_id,$info,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get the entries array
+        $entries = $info['MOD']['#']['ENTRIES']['0']['#']['ENTRY'];
+
+        //Iterate over entries
+        for($i = 0; $i < sizeof($entries); $i++) {
+            $entry_info = $entries[$i];
+            //traverse_xmlize($entry_info);                                                               //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //We'll need this later!!
+            $oldid = backup_todb($sub_info['#']['ID']['0']['#']);
+            $olduserid = backup_todb($sub_info['#']['USERID']['0']['#']);
+
+            //Now, build the JOURNAL_ENTRIES record structure
+            $entry->journal = $new_journal_id;
+            $entry->userid = backup_todb($entry_info['#']['USERID']['0']['#']);
+            $entry->modified = backup_todb($entry_info['#']['MODIFIED']['0']['#']);
+            $entry->text = backup_todb($entry_info['#']['TEXT']['0']['#']);
+            $entry->format = backup_todb($entry_info['#']['FORMAT']['0']['#']);
+            $entry->rating = backup_todb($entry_info['#']['RATING']['0']['#']);
+            $entry->comment = backup_todb($entry_info['#']['COMMENT']['0']['#']);
+            $entry->teacher = backup_todb($entry_info['#']['TEACHER']['0']['#']);
+            $entry->timemarked = backup_todb($entry_info['#']['TIMEMARKED']['0']['#']);
+            $entry->mailed = backup_todb($entry_info['#']['MAILED']['0']['#']);
+
+            //We have to recode the userid field
+            $user = backup_getid($restore->backup_unique_code,"user",$entry->userid);
+            if ($user) {
+                $entry->userid = $user->new_id;
+            }
+
+            //We have to recode the teacher field
+            $user = backup_getid($restore->backup_unique_code,"user",$entry->teacher);
+            if ($user) {
+                $entry->teacher = $user->new_id;
+            }
+
+            //The structure is equal to the db, so insert the journal_entry
+            $newid = insert_record ("journal_entries",$entry);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                echo ".";
+                if (($i+1) % 1000 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"journal_entry",$oldid,
+                             $newid);
+            } else {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+?>
diff --git a/mod/quiz/backuplib.php b/mod/quiz/backuplib.php
new file mode 100644 (file)
index 0000000..2c70452
--- /dev/null
@@ -0,0 +1,601 @@
+<?PHP //$Id$
+    //This php script contains all the stuff to backup/restore
+    //quiz mods
+
+   //To see, put your terminal to 132cc
+
+    //This is the "graphical" structure of the quiz mod:
+    //
+    //                           quiz                                                      quiz_categories
+    //                        (CL,pk->id)                                                   (CL,pk->id)
+    //                            |                                                              |
+    //             -----------------------------------------------                               |
+    //             |                        |                    |                               |
+    //             |                        |                    |                               |
+    //             |                        |                    |                               |
+    //        quiz_attempts          quiz_grades         quiz_question_grades                    |
+    //   (UL,pk->id, fk->quiz)   (UL,pk->id,fk->quiz)    (CL,pk->id,fk->quiz)                    |
+    //             |                                              |                              |
+    //             |                                              |                              |
+    //             |                                              |                              |
+    //       quiz_responses                                       |                        quiz_questions     
+    //  (UL,pk->id, fk->attempt)----------------------------------------------------(CL,pk->id,fk->category,files)
+    //                                                                                           |
+    //                                                                                           |
+    //                                                                                           |
+    //             ------------------------------------------------------------------------------------------------------
+    //             |                         |                        |                |    
+    //             |                         |                        |                |
+    //             |                         |                        |                |           quiz_randomsamatch
+    //       quiz_truefalse           quiz_shortanswer         quiz_multichoice        |---------(CL,pl->id,fk->question)
+    //  (CL,pl->id,fk->question)  (CL,pl->id,fk->question)  (CL,pl->id,fk->question)   |
+    //             .                         .                        .                |
+    //             .                         .                        .                |
+    //             .                         .                        .                |               quiz_match
+    //             ....................................................                |---------(CL,pl->id,fk->question)
+    //                                       .                                         |                    .
+    //                                       .                                         |                    .
+    //                                       .                                         |                    .
+    //                                    quiz_answers                                 |              quiz_match_sub
+    //                             (CL,pk->id,fk->question)----------------------------|---------(CL,pl->id,fk->question) 
+    // 
+    // Meaning: pk->primary key field of the table
+    //          fk->foreign key to link with parent
+    //          nt->nested field (recursive data)
+    //          CL->course level info
+    //          UL->user level info
+    //          files->table may have files
+    //
+    //-----------------------------------------------------------
+
+    //THIS MOD BACKUP NEEDS TO USE THE mdl_backup_ids TABLE
+
+    //This module is special, because we make the backup in two steps:
+    // 1.-We backup every category and their questions (complete structure). It includes this tables:
+    //     - quiz_categories
+    //     - quiz_questions
+    //     - quiz_truefalse
+    //     - quiz_shortanswer
+    //     - quiz_multichoice
+    //     - quiz_randomsamatch
+    //     - quiz_match
+    //     - quiz_match_sub
+    //     - quiz_answers
+    //    All this backup info have its own section in moodle.xml (QUESTION_CATEGORIES) and it's generated
+    //    before every module backup standard invocation. And only if to backup quizzes has been selected !!
+    //    It's invoked with quiz_backup_question_categories. (course independent).
+
+    // 2.-Standard module backup (Invoked via quiz_backup_mods). It includes this tables:
+    //     - quiz
+    //     - quiz_question_grades
+    //     - quiz_attempts
+    //     - quiz_grades
+    //     - quiz_responses
+    //    This step is the standard mod backup. (course dependent).
+
+    //STEP 1. Backup categories/questions and associated structures
+    //    (course independent)
+    function quiz_backup_question_categories($bf,$preferences) {
+
+        global $CFG;
+
+        $status = true;
+
+        //First, we get the used categories from backup_ids
+        $categories = quiz_category_ids_by_backup ($preferences->backup_unique_code);
+      
+        //If we've categories
+        if ($categories) {
+             //Write start tag
+             $status = fwrite($bf,start_tag("QUESTION_CATEGORIES",2,true));
+             //Iterate over each category
+            foreach ($categories as $cat) {
+                //Start category
+                $status =fwrite ($bf,start_tag("QUESTION_CATEGORY",3,true));
+                //Get category data from quiz_categories
+                $category = get_record ("quiz_categories","id",$cat->old_id);
+                //Print category contents
+                fwrite($bf,full_tag("ID",4,false,$category->id));
+                fwrite($bf,full_tag("NAME",4,false,$category->name));
+                fwrite($bf,full_tag("INFO",4,false,$category->info));
+                fwrite($bf,full_tag("PUBLISH",4,false,$category->publish));
+                //Now, backup their questions
+                $status = quiz_backup_question($bf,$preferences,$category->id);
+                //End category
+                $status =fwrite ($bf,end_tag("QUESTION_CATEGORY",3,true));
+            }
+            //Write end tag    
+            $status =fwrite ($bf,end_tag("QUESTION_CATEGORIES",2,true));
+        }
+
+        return $status;
+    }
+    
+    //This function backups all the questions in selected category and their
+    //asociated data 
+    function quiz_backup_question($bf,$preferences,$category) {
+
+        global $CFG;
+
+        $status = true;
+
+        $questions = get_records("quiz_questions","category",$category,"id");
+        //If there is questions
+        if ($questions) {
+            //Write start tag
+            $status =fwrite ($bf,start_tag("QUESTIONS",4,true));
+            $counter = 0;
+            //Iterate over each question
+            foreach ($questions as $question) {
+                //Start question
+                $status =fwrite ($bf,start_tag("QUESTION",5,true));
+                //Print question contents
+                fwrite ($bf,full_tag("ID",6,false,$question->id));
+                fwrite ($bf,full_tag("NAME",6,false,$question->name));
+                fwrite ($bf,full_tag("QUESTIONTEXT",6,false,$question->questiontext));
+                fwrite ($bf,full_tag("IMAGE",6,false,$question->image));
+                fwrite ($bf,full_tag("DEFAULTGRADE",6,false,$question->defaultgrade));
+                fwrite ($bf,full_tag("QTYPE",6,false,$question->qtype));
+                //Now, depending of the qtype, call one function or other
+                if ($question->qtype == "1") {
+                    $status = quiz_backup_shortanswer($bf,$preferences,$question->id);
+                } else if ($question->qtype == "2") {
+                    $status = quiz_backup_truefalse($bf,$preferences,$question->id);
+                } else if ($question->qtype == "3") {
+                    $status = quiz_backup_multichoice($bf,$preferences,$question->id);
+                } else if ($question->qtype == "4") {
+                    //Random question. Nothing to write.
+                } else if ($question->qtype == "5") {
+                    $status = quiz_backup_match($bf,$preferences,$question->id);
+                } else if ($question->qtype == "6") {
+                    $status = quiz_backup_randomsamatch($bf,$preferences,$question->id);
+                } else if ($question->qtype == "7") {
+                    //Description question. Nothing to write.
+                }
+                //End question
+                $status =fwrite ($bf,end_tag("QUESTION",5,true));
+                //Do some output
+                $counter++;
+                if ($counter % 10 == 0) {
+                    echo ".";            
+                    if ($counter % 200 == 0) {
+                        echo "<br>";
+                    }
+                    backup_flush(300);
+                }
+            }
+            //Write end tag
+            $status =fwrite ($bf,end_tag("QUESTIONS",4,true));
+        }
+        return $status;
+    }
+
+    //This function backups the data in a truefalse question (qtype=2) and its
+    //asociated data
+    function quiz_backup_truefalse($bf,$preferences,$question) {
+
+        global $CFG;
+
+        $status = true;
+
+        $truefalses = get_records("quiz_truefalse","question",$question,"id");
+        //If there are truefalses
+        if ($truefalses) {
+            //Iterate over each truefalse
+            foreach ($truefalses as $truefalse) {
+                $status =fwrite ($bf,start_tag("TRUEFALSE",6,true));
+                //Print truefalse contents
+                fwrite ($bf,full_tag("TRUEANSWER",7,false,$truefalse->trueanswer));
+                fwrite ($bf,full_tag("FALSEANSWER",7,false,$truefalse->falseanswer));
+                $status =fwrite ($bf,end_tag("TRUEFALSE",6,true));
+            }
+            //Now print quiz_answers
+            $status = quiz_backup_answers($bf,$preferences,$question);
+        }
+        return $status;
+    }
+
+    //This function backups the data in a shortanswer question (qtype=1) and its
+    //asociated data
+    function quiz_backup_shortanswer($bf,$preferences,$question) {
+
+        global $CFG;
+
+        $status = true;
+
+        $shortanswers = get_records("quiz_shortanswer","question",$question,"id");
+        //If there are shortanswers
+        if ($shortanswers) {
+            //Iterate over each shortanswer
+            foreach ($shortanswers as $shortanswer) {
+                $status =fwrite ($bf,start_tag("SHORTANSWER",6,true));
+                //Print shortanswer contents
+                fwrite ($bf,full_tag("ANSWERS",7,false,$shortanswer->answers));
+                fwrite ($bf,full_tag("USECASE",7,false,$shortanswer->usecase));
+                $status =fwrite ($bf,end_tag("SHORTANSWER",6,true));
+            }
+            //Now print quiz_answers
+            $status = quiz_backup_answers($bf,$preferences,$question);
+        }
+        return $status;
+    } 
+
+    //This function backups the data in a multichoice question (qtype=3) and its
+    //asociated data
+    function quiz_backup_multichoice($bf,$preferences,$question) {
+
+        global $CFG;
+
+        $status = true;
+
+        $multichoices = get_records("quiz_multichoice","question",$question,"id");
+        //If there are multichoices
+        if ($multichoices) {
+            //Iterate over each multichoice
+            foreach ($multichoices as $multichoice) {
+                $status =fwrite ($bf,start_tag("MULTICHOICE",6,true));
+                //Print multichoice contents
+                fwrite ($bf,full_tag("LAYOUT",7,false,$multichoice->layout));
+                fwrite ($bf,full_tag("ANSWERS",7,false,$multichoice->answers));
+                fwrite ($bf,full_tag("SINGLE",7,false,$multichoice->single));
+                $status =fwrite ($bf,end_tag("MULTICHOICE",6,true));
+            }
+            //Now print quiz_answers
+            $status = quiz_backup_answers($bf,$preferences,$question);
+        }
+        return $status;
+    }
+
+    //This function backups the data in a randomsamatch question (qtype=6) and its
+    //asociated data
+    function quiz_backup_randomsamatch($bf,$preferences,$question) {
+
+        global $CFG;
+
+        $status = true;
+
+        $randomsamatchs = get_records("quiz_randomsamatch","question",$question,"id");
+        //If there are randomsamatchs
+        if ($randomsamatchs) {
+            //Iterate over each randomsamatch
+            foreach ($randomsamatchs as $randomsamatch) {
+                $status =fwrite ($bf,start_tag("RANDOMSAMATCH",6,true));
+                //Print randomsamatch contents
+                fwrite ($bf,full_tag("CHOOSE",7,false,$randomsamatch->choose));
+                $status =fwrite ($bf,end_tag("RANDOMSAMATCH",6,true));
+            }
+        }
+        return $status;
+    }
+
+    //This function backups the data in a match question (qtype=5) and its
+    //asociated data
+    function quiz_backup_match($bf,$preferences,$question) {
+
+        global $CFG;
+
+        $status = true;
+
+        $matchs = get_records("quiz_match_sub","question",$question,"id");
+        //If there are matchs
+        if ($matchs) {
+            $status =fwrite ($bf,start_tag("MATCHS",6,true));
+            //Iterate over each match
+            foreach ($matchs as $match) {
+                $status =fwrite ($bf,start_tag("MATCH",7,true));
+                //Print match contents
+                fwrite ($bf,full_tag("ID",8,false,$match->id));
+                fwrite ($bf,full_tag("QUESTIONTEXT",8,false,$match->questiontext));
+                fwrite ($bf,full_tag("ANSWERTEXT",8,false,$match->answertext));
+                $status =fwrite ($bf,end_tag("MATCH",7,true));
+            }
+            $status =fwrite ($bf,end_tag("MATCHS",6,true));
+        }
+        return $status;
+    }
+
+    //This function backups the answers data in some question types
+    //(truefalse, shortanswer,multichoice)
+    function quiz_backup_answers($bf,$preferences,$question) {
+
+        global $CFG;
+
+        $status = true;
+
+        $answers = get_records("quiz_answers","question",$question,"id");
+        //If there are answers
+        if ($answers) {
+            $status =fwrite ($bf,start_tag("ANSWERS",6,true));
+            //Iterate over each answer
+            foreach ($answers as $answer) {
+                $status =fwrite ($bf,start_tag("ANSWER",7,true));
+                //Print answer contents
+                fwrite ($bf,full_tag("ID",8,false,$answer->id));
+                fwrite ($bf,full_tag("ANSWER_TEXT",8,false,$answer->answer));
+                fwrite ($bf,full_tag("FRACTION",8,false,$answer->fraction));
+                fwrite ($bf,full_tag("FEEDBACK",8,false,$answer->feedback));
+                $status =fwrite ($bf,end_tag("ANSWER",7,true));
+            }
+            $status =fwrite ($bf,end_tag("ANSWERS",6,true));
+        }
+        return $status;
+    }
+
+
+
+
+
+    //STEP 2. Backup quizzes and associated structures
+    //    (course dependent)
+    function quiz_backup_mods($bf,$preferences) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Iterate over quiz table
+        $quizzes = get_records ("quiz","course",$preferences->backup_course,"id");
+        if ($quizzes) {
+            foreach ($quizzes as $quiz) {
+                //Start mod
+                fwrite ($bf,start_tag("MOD",3,true));
+                //Print quiz data
+                fwrite ($bf,full_tag("ID",4,false,$quiz->id));
+                fwrite ($bf,full_tag("MODTYPE",4,false,"quiz"));
+                fwrite ($bf,full_tag("NAME",4,false,$quiz->name));
+                fwrite ($bf,full_tag("INTRO",4,false,$quiz->intro));
+                fwrite ($bf,full_tag("TIMEOPEN",4,false,$quiz->timeopen));
+                fwrite ($bf,full_tag("TIMECLOSE",4,false,$quiz->timeclose));
+                fwrite ($bf,full_tag("ATTEMPTS_NUMBER",4,false,$quiz->attempts));
+                fwrite ($bf,full_tag("FEEDBACK",4,false,$quiz->feedback));
+                fwrite ($bf,full_tag("CORRECTANSWERS",4,false,$quiz->correctanswers));
+                fwrite ($bf,full_tag("GRADEMETHOD",4,false,$quiz->grademethod));
+                fwrite ($bf,full_tag("REVIEW",4,false,$quiz->review));
+                fwrite ($bf,full_tag("SHUFFLEQUESTIONS",4,false,$quiz->shufflequestions));
+                fwrite ($bf,full_tag("SHUFFLEANSWERS",4,false,$quiz->shuffleanswers));
+                fwrite ($bf,full_tag("QUESTIONS",4,false,$quiz->questions));
+                fwrite ($bf,full_tag("SUMGRADES",4,false,$quiz->sumgrades));
+                fwrite ($bf,full_tag("GRADE",4,false,$quiz->grade));
+                fwrite ($bf,full_tag("TIMECREATED",4,false,$quiz->timecreated));
+                fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$quiz->timemodified));
+                //Now we print to xml question_grades (Course Level)
+                $status = backup_quiz_question_grades($bf,$preferences,$quiz->id);
+                //if we've selected to backup users info, then execute:
+                //    - backup_quiz_grades
+                //    - backup_quiz_attempts
+                if ($preferences->mods["quiz"]->userinfo and $status) {
+                    $status = backup_quiz_grades($bf,$preferences,$quiz->id);
+                    if ($status) {
+                        $status = backup_quiz_attempts($bf,$preferences,$quiz->id);
+                    }
+                }
+                //End mod
+                $status =fwrite ($bf,end_tag("MOD",3,true));
+            }
+        }
+        return $status;
+    }
+
+    //Backup quiz_question_grades contents (executed from quiz_backup_mods)
+    function backup_quiz_question_grades ($bf,$preferences,$quiz) {
+
+        global $CFG;
+
+        $status = true;
+
+        $quiz_question_grades = get_records("quiz_question_grades","quiz",$quiz,"id");
+        //If there are question_grades
+        if ($quiz_question_grades) {
+            //Write start tag
+            $status =fwrite ($bf,start_tag("QUESTION_GRADES",4,true));
+            //Iterate over each question_grade
+            foreach ($quiz_question_grades as $que_gra) {
+                //Start question grade
+                $status =fwrite ($bf,start_tag("QUESTION_GRADE",5,true));
+                //Print question_grade contents
+                fwrite ($bf,full_tag("ID",6,false,$que_gra->id));
+                fwrite ($bf,full_tag("QUESTION",6,false,$que_gra->question));
+                fwrite ($bf,full_tag("GRADE",6,false,$que_gra->grade));
+                //End question grade
+                $status =fwrite ($bf,end_tag("QUESTION_GRADE",5,true));
+            }
+            //Write end tag
+            $status =fwrite ($bf,end_tag("QUESTION_GRADES",4,true));
+        }
+        return $status;
+    }
+
+    //Backup quiz_grades contents (executed from quiz_backup_mods)
+    function backup_quiz_grades ($bf,$preferences,$quiz) {
+
+        global $CFG;
+
+        $status = true;
+
+        $quiz_grades = get_records("quiz_grades","quiz",$quiz,"id");
+        //If there are grades
+        if ($quiz_grades) {
+            //Write start tag
+            $status =fwrite ($bf,start_tag("GRADES",4,true));
+            //Iterate over each grade
+            foreach ($quiz_grades as $gra) {
+                //Start grade
+                $status =fwrite ($bf,start_tag("GRADE",5,true));
+                //Print grade contents
+                fwrite ($bf,full_tag("ID",6,false,$gra->id));
+                fwrite ($bf,full_tag("USERID",6,false,$gra->userid));
+                fwrite ($bf,full_tag("GRADEVAL",6,false,$gra->grade));
+                fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$gra->timemodified));
+                //End question grade
+                $status =fwrite ($bf,end_tag("GRADE",5,true));
+            }
+            //Write end tag
+            $status =fwrite ($bf,end_tag("GRADES",4,true));
+        }
+        return $status;
+    }
+
+    //Backup quiz_attempts contents (executed from quiz_backup_mods)
+    function backup_quiz_attempts ($bf,$preferences,$quiz) {
+
+        global $CFG;
+
+        $status = true;
+
+        $quiz_attempts = get_records("quiz_attempts","quiz",$quiz,"id");
+        //If there are attempts
+        if ($quiz_attempts) {
+            //Write start tag
+            $status =fwrite ($bf,start_tag("ATTEMPTS",4,true));
+            //Iterate over each attempt
+            foreach ($quiz_attempts as $attempt) {
+                //Start attempt
+                $status =fwrite ($bf,start_tag("ATTEMPT",5,true));
+                //Print attempt contents
+                fwrite ($bf,full_tag("ID",6,false,$attempt->id));
+                fwrite ($bf,full_tag("USERID",6,false,$attempt->userid));
+                fwrite ($bf,full_tag("ATTEMPTNUM",6,false,$attempt->attempt));
+                fwrite ($bf,full_tag("SUMGRADES",6,false,$attempt->sumgrades));
+                fwrite ($bf,full_tag("TIMESTART",6,false,$attempt->timestart));
+                fwrite ($bf,full_tag("TIMEFINISH",6,false,$attempt->timefinish));
+                fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$attempt->timemodified));
+                //Now write to xml the responses (in this attempt)
+                $status = backup_quiz_responses ($bf,$preferences,$attempt->id);
+                //End attempt
+                $status =fwrite ($bf,end_tag("ATTEMPT",5,true));
+            }
+            //Write end tag
+            $status =fwrite ($bf,end_tag("ATTEMPTS",4,true));
+        }
+        return $status;
+    }
+
+    //Backup quiz_responses contents (executed from backup_quiz_attempts)
+    function backup_quiz_responses ($bf,$preferences,$attempt) {
+
+        global $CFG;
+
+        $status = true;
+
+        $quiz_responses = get_records("quiz_responses","attempt",$attempt,"id");
+        //If there are responses
+        if ($quiz_responses) {
+            //Write start tag
+            $status =fwrite ($bf,start_tag("RESPONSES",6,true));
+            //Iterate over each response
+            foreach ($quiz_responses as $response) {
+                //Start response
+                $status =fwrite ($bf,start_tag("RESPONSE",7,true));
+                //Print response contents
+                fwrite ($bf,full_tag("ID",8,false,$response->id));
+                fwrite ($bf,full_tag("QUESTION",8,false,$response->question));
+                fwrite ($bf,full_tag("ANSWER",8,false,$response->answer));
+                fwrite ($bf,full_tag("GRADE",8,false,$response->grade));
+                //End response
+                $status =fwrite ($bf,end_tag("RESPONSE",7,true));
+            }
+            //Write end tag
+            $status =fwrite ($bf,end_tag("RESPONSES",6,true));
+        }
+        return $status;
+    }
+
+
+
+
+
+
+   ////Return an array of info (name,value)
+   function quiz_check_backup_mods($course,$user_data=false,$backup_unique_code) {
+        //Deletes data from mdl_backup_ids (categories section)
+        delete_category_ids ($backup_unique_code);
+        //Create date into mdl_backup_ids (categories section)
+        insert_category_ids ($course,$backup_unique_code);
+        //First the course data
+        $info[0][0] = get_string("modulenameplural","quiz");
+        if ($ids = quiz_ids ($course)) {
+            $info[0][1] = count($ids);
+        } else {
+            $info[0][1] = 0;
+        }
+        //Categories
+        $info[1][0] = get_string("categories","quiz");
+        if ($ids = quiz_category_ids_by_backup ($backup_unique_code)) {
+            $info[1][1] = count($ids);
+        } else {
+            $info[1][1] = 0;
+        }
+        //Questions
+        $info[2][0] = get_string("questions","quiz");
+        if ($ids = quiz_question_ids_by_backup ($backup_unique_code)) {
+            $info[2][1] = count($ids);
+        } else {
+            $info[2][1] = 0;
+        }
+
+        //Now, if requested, the user_data
+        if ($user_data) {
+            //Grades 
+            $info[3][0] = get_string("grades","quiz"); 
+            if ($ids = quiz_grade_ids_by_course ($course)) { 
+                $info[3][1] = count($ids);
+            } else {
+                $info[3][1] = 0;
+            }
+        }
+
+        return $info;
+    }
+
+
+
+
+
+
+    // INTERNAL FUNCTIONS. BASED IN THE MOD STRUCTURE
+
+    //Returns an array of quiz id
+    function quiz_ids ($course) {
+
+        global $CFG;
+
+        return get_records_sql ("SELECT a.id, a.course
+                                 FROM {$CFG->prefix}quiz a
+                                 WHERE a.course = '$course'");
+    }
+
+    //Returns an array of categories id
+    function quiz_category_ids_by_backup ($backup_unique_code) {
+
+        global $CFG;
+
+        return get_records_sql ("SELECT a.old_id, a.backup_code
+                                 FROM {$CFG->prefix}backup_ids a
+                                 WHERE a.backup_code = '$backup_unique_code' AND
+                                       a.table_name = 'quiz_categories'");
+    }
+
+    function quiz_question_ids_by_backup ($backup_unique_code) {
+
+        global $CFG;
+
+        return get_records_sql ("SELECT q.id, q.category
+                                 FROM {$CFG->prefix}backup_ids a,
+                                      {$CFG->prefix}quiz_questions q
+                                 WHERE a.backup_code = '$backup_unique_code' AND
+                                       q.category = a.old_id AND 
+                                       a.table_name = 'quiz_categories'");
+    }
+
+    function quiz_grade_ids_by_course ($course) {
+
+        global $CFG;
+
+        return get_records_sql ("SELECT g.id, g.quiz 
+                                 FROM {$CFG->prefix}quiz a,
+                                      {$CFG->prefix}quiz_grades g
+                                 WHERE a.course = '$course' and
+                                       g.quiz = a.id");
+    }
+
+?>
diff --git a/mod/quiz/restorelib.php b/mod/quiz/restorelib.php
new file mode 100644 (file)
index 0000000..f1fd51b
--- /dev/null
@@ -0,0 +1,979 @@
+<?PHP //$Id$
+    //This php script contains all the stuff to backup/restore
+    //quiz mods
+
+   //To see, put your terminal to 132cc
+
+    //This is the "graphical" structure of the quiz mod:
+    //
+    //                           quiz                                                      quiz_categories
+    //                        (CL,pk->id)                                                   (CL,pk->id)
+    //                            |                                                              |
+    //             -----------------------------------------------                               |
+    //             |                        |                    |                               |
+    //             |                        |                    |                               |
+    //             |                        |                    |                               |
+    //        quiz_attempts          quiz_grades         quiz_question_grades                    |
+    //   (UL,pk->id, fk->quiz)   (UL,pk->id,fk->quiz)    (CL,pk->id,fk->quiz)                    |
+    //             |                                              |                              |
+    //             |                                              |                              |
+    //             |                                              |                              |
+    //       quiz_responses                                       |                        quiz_questions     
+    //  (UL,pk->id, fk->attempt)----------------------------------------------------(CL,pk->id,fk->category,files)
+    //                                                                                           |
+    //                                                                                           |
+    //                                                                                           |
+    //             ------------------------------------------------------------------------------------------------------
+    //             |                         |                        |                |    
+    //             |                         |                        |                |
+    //             |                         |                        |                |           quiz_randomsamatch
+    //       quiz_truefalse           quiz_shortanswer         quiz_multichoice        |---------(CL,pl->id,fk->question)
+    //  (CL,pl->id,fk->question)  (CL,pl->id,fk->question)  (CL,pl->id,fk->question)   |
+    //             .                         .                        .                |
+    //             .                         .                        .                |
+    //             .                         .                        .                |               quiz_match
+    //             ....................................................                |---------(CL,pl->id,fk->question)
+    //                                       .                                         |                    .
+    //                                       .                                         |                    .
+    //                                       .                                         |                    .
+    //                                    quiz_answers                                 |              quiz_match_sub
+    //                             (CL,pk->id,fk->question)----------------------------|---------(CL,pl->id,fk->question) 
+    // 
+    // Meaning: pk->primary key field of the table
+    //          fk->foreign key to link with parent
+    //          nt->nested field (recursive data)
+    //          CL->course level info
+    //          UL->user level info
+    //          files->table may have files
+    //
+    //-----------------------------------------------------------
+
+    //This module is special, because we make the restore in two steps:
+    // 1.-We restore every category and their questions (complete structure). It includes this tables:
+    //     - quiz_categories
+    //     - quiz_questions
+    //     - quiz_truefalse
+    //     - quiz_shortanswer
+    //     - quiz_multichoice
+    //     - quiz_randomsamatch
+    //     - quiz_match
+    //     - quiz_match_sub
+    //     - quiz_answers
+    //    All this backup info have its own section in moodle.xml (QUESTION_CATEGORIES) and it's generated
+    //    before every module backup standard invocation. And only if to restore quizzes has been selected !!
+    //    It's invoked with quiz_restore_question_categories. (course independent).
+
+    // 2.-Standard module restore (Invoked via quiz_restore_mods). It includes this tables:
+    //     - quiz
+    //     - quiz_question_grades
+    //     - quiz_attempts
+    //     - quiz_grades
+    //     - quiz_responses
+    //    This step is the standard mod backup. (course dependent).
+
+    //STEP 1. Restore categories/questions and associated structures
+    //    (course independent)
+    function quiz_restore_question_categories($category,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get record from backup_ids
+        $data = backup_getid($restore->backup_unique_code,"quiz_categories",$category->id);
+   
+        if ($data) {
+            //Now get completed xmlized object
+            $info = $data->info;
+            //traverse_xmlize($info);                                                                     //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //Now, build the QUIZ_CATEGORIES record structure
+            $quiz_cat->course = $restore->course_id;
+            $quiz_cat->name = backup_todb($info['QUESTION_CATEGORY']['#']['NAME']['0']['#']);
+            $quiz_cat->info = backup_todb($info['QUESTION_CATEGORY']['#']['INFO']['0']['#']);
+            $quiz_cat->publish = backup_todb($info['QUESTION_CATEGORY']['#']['PUBLISH']['0']['#']);
+
+            //Now search it that category exists !!
+            $cat = get_record("quiz_categories","name",$quiz_cat->name);
+            //Create it if doesn't exists
+            if (!$cat) {
+                //The structure is equal to the db, so insert the quiz_categories
+                $newid = insert_record ("quiz_categories",$quiz_cat);
+            } else {
+                //Exists, so get its id
+                $newid = $cat->id;
+            }
+
+            //Do some output
+            echo "<ul><li>Category \"".$quiz_cat->name."\"<br>";
+            backup_flush(300);
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"quiz_categories",
+                             $category->id, $newid);
+                //Now restore quiz_questions
+                $status = quiz_restore_questions ($category->id, $newid,$info,$restore);
+            } else {
+                $status = false;
+            }
+            
+
+            //Finalize ul
+            echo "</ul>";
+        }
+
+        return $status;
+    }
+
+    function quiz_restore_questions ($old_category_id,$new_category_id,$info,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get the questions array
+        $questions = $info['QUESTION_CATEGORY']['#']['QUESTIONS']['0']['#']['QUESTION'];
+
+        //Iterate over questions
+        for($i = 0; $i < sizeof($questions); $i++) {
+            $que_info = $questions[$i];
+            //traverse_xmlize($que_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //We'll need this later!!
+            $oldid = backup_todb($que_info['#']['ID']['0']['#']);
+
+            //Now, build the QUIZ_QUESTIONS record structure
+            $question->category = $new_category_id;
+            $question->name = backup_todb($que_info['#']['NAME']['0']['#']);
+            $question->questiontext = backup_todb($que_info['#']['QUESTIONTEXT']['0']['#']);
+            $question->image = backup_todb($que_info['#']['IMAGE']['0']['#']);
+            $question->defaultgrade = backup_todb($que_info['#']['DEFAULTGRADE']['0']['#']);
+            $question->qtype = backup_todb($que_info['#']['QTYPE']['0']['#']);
+
+            //The structure is equal to the db, so insert the quiz_questions
+            $newid = insert_record ("quiz_questions",$question);
+
+            //Do some output
+            if (($i+1) % 2 == 0) {
+                echo ".";
+                if (($i+1) % 40 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"quiz_questions",$oldid,
+                             $newid);
+                //Now, restore every quiz_answers in this question
+                $status = quiz_restore_answers($oldid,$newid,$que_info,$restore);
+                //Now, depending of the type of questions, invoke different functions
+                if ($question->qtype == "1") {
+                    $status = quiz_restore_shortanswer($oldid,$newid,$que_info,$restore);
+                } else if ($question->qtype == "2") {
+                    $status = quiz_restore_truefalse($oldid,$newid,$que_info,$restore);
+                } else if ($question->qtype == "3") {
+                    $status = quiz_restore_multichoice($oldid,$newid,$que_info,$restore);
+                } else if ($question->qtype == "4") {
+                    //Random question. Nothing to do.
+                } else if ($question->qtype == "5") {
+                    $status = quiz_restore_match($oldid,$newid,$que_info,$restore);
+                } else if ($question->qtype == "6") {
+                    $status = quiz_restore_randomsamatch($oldid,$newid,$que_info,$restore);
+                } else if ($question->qtype == "7") {
+                    //Description question. Nothing to do.
+                }
+            } else {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+    function quiz_restore_answers ($old_question_id,$new_question_id,$info,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get the answers array
+        $answers = $info['#']['ANSWERS']['0']['#']['ANSWER'];
+
+        //Iterate over answers
+        for($i = 0; $i < sizeof($answers); $i++) {
+            $ans_info = $answers[$i];
+            //traverse_xmlize($ans_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //We'll need this later!!
+            $oldid = backup_todb($ans_info['#']['ID']['0']['#']);
+
+            //Now, build the QUIZ_ANSWERS record structure
+            $answer->question = $new_question_id;
+            $answer->answer = backup_todb($ans_info['#']['ANSWER_TEXT']['0']['#']);
+            $answer->fraction = backup_todb($ans_info['#']['FRACTION']['0']['#']);
+            $answer->feedback = backup_todb($ans_info['#']['FEEDBACK']['0']['#']);
+
+            //The structure is equal to the db, so insert the quiz_answers
+            $newid = insert_record ("quiz_answers",$answer);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                echo ".";
+                if (($i+1) % 1000 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"quiz_answers",$oldid,
+                             $newid);
+            } else {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+   
+    function quiz_restore_shortanswer ($old_question_id,$new_question_id,$info,$restore) {
+
+        global $CFG;          
+
+        $status = true;
+
+        //Get the shortanswers array 
+        $shortanswers = $info['#']['SHORTANSWER'];
+
+        //Iterate over shortanswers
+        for($i = 0; $i < sizeof($shortanswers); $i++) { 
+            $sho_info = $shortanswers[$i];
+            //traverse_xmlize($sho_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+            //Now, build the QUIZ_SHORTANSWER record structure
+            $shortanswer->question = $new_question_id;
+            $shortanswer->answers = backup_todb($sho_info['#']['ANSWERS']['0']['#']);
+            $shortanswer->usecase = backup_todb($sho_info['#']['USECASE']['0']['#']);
+
+            //We have to recode the answers field (a list of answers id)
+            //Extracts answer id from sequence
+            $answers_field = "";
+            $in_first = true;
+            $tok = strtok($shortanswer->answers,",");
+            while ($tok) {
+                //Get the answer from backup_ids
+                $answer = backup_getid($restore->backup_unique_code,"quiz_answers",$tok);
+                if ($answer) {
+                    if ($in_first) {
+                        $answers_field .= $answer->new_id;
+                        $in_first = false;
+                    } else {
+                        $answers_field .= ",".$answer->new_id;
+                    }
+                }
+                //check for next
+                $tok = strtok(",");
+            }
+            //We have the answers field recoded to its new ids
+            $shortanswer->answers = $answers_field;
+
+            //The structure is equal to the db, so insert the quiz_shortanswer
+            $newid = insert_record ("quiz_shortanswer",$shortanswer);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                echo ".";
+                if (($i+1) % 1000 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if (!$newid) {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+    function quiz_restore_truefalse ($old_question_id,$new_question_id,$info,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get the truefalse array
+        $truefalses = $info['#']['TRUEFALSE'];
+
+        //Iterate over truefalse
+        for($i = 0; $i < sizeof($truefalses); $i++) {
+            $tru_info = $truefalses[$i];
+            //traverse_xmlize($tru_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //Now, build the QUIZ_TRUEFALSE record structure
+            $truefalse->question = $new_question_id;
+            $truefalse->trueanswer = backup_todb($tru_info['#']['TRUEANSWER']['0']['#']);
+            $truefalse->falseanswer = backup_todb($tru_info['#']['FALSEANSWER']['0']['#']);
+
+            ////We have to recode the trueanswer field
+            $answer = backup_getid($restore->backup_unique_code,"quiz_answers",$truefalse->trueanswer);
+            if ($answer) {
+                $truefalse->trueanswer = $answer->new_id;
+            }
+
+            ////We have to recode the falseanswer field
+            $answer = backup_getid($restore->backup_unique_code,"quiz_answers",$truefalse->falseanswer);
+            if ($answer) {
+                $truefalse->falseanswer = $answer->new_id;
+            }
+
+            //The structure is equal to the db, so insert the quiz_truefalse
+            $newid = insert_record ("quiz_truefalse",$truefalse);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                echo ".";
+                if (($i+1) % 1000 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if (!$newid) {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+    function quiz_restore_multichoice ($old_question_id,$new_question_id,$info,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get the multichoices array
+        $multichoices = $info['#']['MULTICHOICE'];
+
+        //Iterate over multichoices
+        for($i = 0; $i < sizeof($multichoices); $i++) {
+            $mul_info = $multichoices[$i];
+            //traverse_xmlize($mul_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //Now, build the QUIZ_MULTICHOICE record structure
+            $multichoice->question = $new_question_id;
+            $multichoice->layout = backup_todb($mul_info['#']['LAYOUT']['0']['#']);
+            $multichoice->answers = backup_todb($mul_info['#']['ANSWERS']['0']['#']);
+            $multichoice->single = backup_todb($mul_info['#']['SINGLE']['0']['#']);
+
+            //We have to recode the answers field (a list of answers id)
+            //Extracts answer id from sequence
+            $answers_field = "";
+            $in_first = true;
+            $tok = strtok($multichoice->answers,",");
+            while ($tok) {
+                //Get the answer from backup_ids
+                $answer = backup_getid($restore->backup_unique_code,"quiz_answers",$tok);
+                if ($answer) {
+                    if ($in_first) {
+                        $answers_field .= $answer->new_id;
+                        $in_first = false;
+                    } else {
+                        $answers_field .= ",".$answer->new_id;
+                    }
+                }
+                //check for next
+                $tok = strtok(",");
+            }
+            //We have the answers field recoded to its new ids
+            $multichoice->answers = $answers_field;
+
+            //The structure is equal to the db, so insert the quiz_shortanswer
+            $newid = insert_record ("quiz_multichoice",$multichoice);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                echo ".";
+                if (($i+1) % 1000 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if (!$newid) {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+    function quiz_restore_match ($old_question_id,$new_question_id,$info,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get the matchs array
+        $matchs = $info['#']['MATCHS']['0']['#']['MATCH'];
+
+        //We have to build the subquestions field (a list of match_sub id)
+        $subquestions_field = "";
+        $in_first = true;
+
+        //Iterate over matchs
+        for($i = 0; $i < sizeof($matchs); $i++) {
+            $mat_info = $matchs[$i];
+            //traverse_xmlize($mat_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //We'll need this later!!
+            $oldid = backup_todb($mat_info['#']['ID']['0']['#']);
+
+            //Now, build the QUIZ_MATCH_SUB record structure
+            $match_sub->question = $new_question_id;
+            $match_sub->questiontext = backup_todb($mat_info['#']['QUESTIONTEXT']['0']['#']);
+            $match_sub->answertext = backup_todb($mat_info['#']['ANSWERTEXT']['0']['#']);
+
+            //The structure is equal to the db, so insert the quiz_match_sub
+            $newid = insert_record ("quiz_match_sub",$match_sub);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                echo ".";
+                if (($i+1) % 1000 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"quiz_match_sub",$oldid,
+                             $newid);
+                //We have a new match_sub, append it to subquestions_field
+                if ($in_first) {
+                    $subquestions_field .= $newid;
+                    $in_first = false;
+                } else {
+                    $subquestions_field .= ",".$newid;
+                }
+            } else {
+                $status = false;
+            }
+        }
+
+        //We have created every match_sub, now create the match
+        $match->question = $new_question_id;
+        $match->subquestions = $subquestions_field;
+
+        //The structure is equal to the db, so insert the quiz_match_sub  
+        $newid = insert_record ("quiz_match",$match);
+
+        if (!$newid) {
+            $status = false;
+        }
+
+        return $status;
+    }
+
+    function quiz_restore_randomsamatch ($old_question_id,$new_question_id,$info,$restore) {
+
+        global $CFG;
+
+        $status = true;      
+
+        //Get the randomsamatchs array
+        $randomsamatchs = $info['#']['RANDOMSAMATCH'];
+
+        //Iterate over randomsamatchs
+        for($i = 0; $i < sizeof($randomsamatchs); $i++) {
+            $ran_info = $randomsamatchs[$i];
+            //traverse_xmlize($ran_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //Now, build the QUIZ_RANDOMSAMATCH record structure
+            $randomsamatch->question = $new_question_id;
+            $randomsamatch->choose = backup_todb($ran_info['#']['CHOOSE']['0']['#']);
+
+            //The structure is equal to the db, so insert the quiz_randomsamatch
+            $newid = insert_record ("quiz_randomsamatch",$randomsamatch);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                echo ".";
+                if (($i+1) % 1000 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if (!$newid) {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+
+
+
+    //STEP 2. Restore quizzes and associated structures
+    //    (course dependent)
+    function quiz_restore_mods($mod,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get record from backup_ids
+        $data = backup_getid($restore->backup_unique_code,$mod->modtype,$mod->id);
+
+        if ($data) {
+            //Now get completed xmlized object
+            $info = $data->info;
+            //traverse_xmlize($info);                                                                     //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //Now, build the QUIZ record structure
+            $quiz->course = $restore->course_id;
+            $quiz->name = backup_todb($info['MOD']['#']['NAME']['0']['#']);
+            $quiz->intro = backup_todb($info['MOD']['#']['INTRO']['0']['#']);
+            $quiz->timeopen = backup_todb($info['MOD']['#']['TIMEOPEN']['0']['#']);
+            $quiz->timeclose = backup_todb($info['MOD']['#']['TIMECLOSE']['0']['#']);
+            $quiz->attempts = backup_todb($info['MOD']['#']['ATTEMPTS_NUMBER']['0']['#']);
+            $quiz->feedback = backup_todb($info['MOD']['#']['FEEDBACK']['0']['#']);
+            $quiz->correctanswers = backup_todb($info['MOD']['#']['CORRECTANSWERS']['0']['#']);
+            $quiz->grademethod = backup_todb($info['MOD']['#']['GRADEMETHOD']['0']['#']);
+            $quiz->review = backup_todb($info['MOD']['#']['REVIEW']['0']['#']);
+            $quiz->shufflequestions = backup_todb($info['MOD']['#']['SHUFFLEQUESTIONS']['0']['#']);
+            $quiz->shuffleanswers = backup_todb($info['MOD']['#']['SHUFFLEANSWERS']['0']['#']);
+            $quiz->questions = backup_todb($info['MOD']['#']['QUESTIONS']['0']['#']);
+            $quiz->sumgrades = backup_todb($info['MOD']['#']['SUMGRADES']['0']['#']);
+            $quiz->grade = backup_todb($info['MOD']['#']['GRADE']['0']['#']);
+            $quiz->timecreated = backup_todb($info['MOD']['#']['TIMECREATED']['0']['#']);
+            $quiz->timemodified = backup_todb($info['MOD']['#']['TIMEMODIFIED']['0']['#']);
+
+            //We have to recode the questions field (a list of questions id)          
+            //Extracts question id from sequence
+            $questions_field = "";
+            $in_first = true;
+            $tok = strtok($quiz->questions,",");
+            while ($tok) {
+                //Get the question from backup_ids
+                $question = backup_getid($restore->backup_unique_code,"quiz_questions",$tok);  
+                if ($question) {
+                    if ($in_first) {
+                        $questions_field .= $question->new_id;
+                        $in_first = false;
+                    } else {
+                        $questions_field .= ",".$question->new_id;
+                    }
+                }
+                //check for next
+                $tok = strtok(",");
+            }
+            //We have the questions field recoded to its new ids
+            $quiz->questions = $questions_field;
+
+            //The structure is equal to the db, so insert the quiz
+            $newid = insert_record ("quiz",$quiz);
+
+            //Do some output
+            echo "<ul><li>Quiz \"".$quiz->name."\"<br>";
+            backup_flush(300);
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,$mod->modtype,
+                             $mod->id, $newid);
+                //We have to restore the question_grades now (course level table)
+                $status = quiz_question_grades_restore_mods($newid,$info,$restore);
+                //Now check if want to restore user data and do it.
+                if ($restore->mods[quiz]->userinfo) {
+                    //Restore quiz_attempts
+                    $status = quiz_attempts_restore_mods ($newid,$info,$restore);
+                    if ($status) {
+                        //Restore quiz_grades   
+                        $status = quiz_grades_restore_mods ($newid,$info,$restore);
+                    }  
+                }
+            } else {
+                $status = false;
+            }
+
+            //Finalize ul
+            echo "</ul>";
+
+        } else {
+            $status = false;
+        }
+
+        return $status;
+    }
+
+    //This function restores the quiz_question_grades 
+    function quiz_question_grades_restore_mods($quiz_id,$info,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get the quiz_question_grades array
+        $grades = $info['MOD']['#']['QUESTION_GRADES']['0']['#']['QUESTION_GRADE'];
+
+        //Iterate over question_grades
+        for($i = 0; $i < sizeof($grades); $i++) {
+            $gra_info = $grades[$i];
+            //traverse_xmlize($gra_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //We'll need this later!!
+            $oldid = backup_todb($gra_info['#']['ID']['0']['#']);
+
+            //Now, build the QUESTION_GRADES record structure
+            $grade->quiz = $quiz_id;
+            $grade->question = backup_todb($gra_info['#']['QUESTION']['0']['#']);
+            $grade->grade = backup_todb($gra_info['#']['GRADE']['0']['#']);
+
+            //We have to recode the question field
+            $question = backup_getid($restore->backup_unique_code,"quiz_questions",$grade->question);
+            if ($question) {
+                $grade->question = $question->new_id;
+            }
+
+            //The structure is equal to the db, so insert the quiz_question_grades
+            $newid = insert_record ("quiz_question_grades",$grade);
+
+            //Do some output
+            if (($i+1) % 10 == 0) {
+                echo ".";
+                if (($i+1) % 200 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"quiz_question_grades",$oldid,
+                             $newid);
+            } else {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+    //This function restores the quiz_attempts
+    function quiz_attempts_restore_mods($quiz_id,$info,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get the quiz_attempts array
+        $attempts = $info['MOD']['#']['ATTEMPTS']['0']['#']['ATTEMPT'];
+
+        //Iterate over attempts
+        for($i = 0; $i < sizeof($attempts); $i++) {
+            $att_info = $attempts[$i];
+            //traverse_xmlize($att_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //We'll need this later!!
+            $oldid = backup_todb($att_info['#']['ID']['0']['#']);
+            $olduserid = backup_todb($att_info['#']['USERID']['0']['#']);
+
+            //Now, build the ATTEMPTS record structure
+            $attempt->quiz = $quiz_id;
+            $attempt->userid = backup_todb($att_info['#']['USERID']['0']['#']);
+            $attempt->attempt = backup_todb($att_info['#']['ATTEMPTNUM']['0']['#']);
+            $attempt->sumgrades = backup_todb($att_info['#']['SUMGRADES']['0']['#']);
+            $attempt->timestart = backup_todb($att_info['#']['TIMESTART']['0']['#']);
+            $attempt->timefinish = backup_todb($att_info['#']['TIMEFINISH']['0']['#']);
+            $attempt->timemodified = backup_todb($att_info['#']['TIMEMODIFIED']['0']['#']);
+
+            //We have to recode the userid field
+            $user = backup_getid($restore->backup_unique_code,"user",$attempt->userid);
+            if ($user) {
+                $attempt->userid = $user->new_id;
+            }
+
+            //The structure is equal to the db, so insert the quiz_attempts
+            $newid = insert_record ("quiz_attempts",$attempt);
+
+            //Do some output
+            if (($i+1) % 10 == 0) {
+                echo ".";
+                if (($i+1) % 200 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"quiz_attempts",$oldid,
+                             $newid);
+                //Now process quiz_responses
+                $status = quiz_responses_restore_mods($newid,$att_info,$restore);
+            } else {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+    //This function restores the quiz_responses       
+    function quiz_responses_restore_mods($attempt_id,$info,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get the quiz_responses array
+        $responses = $info['#']['RESPONSES']['0']['#']['RESPONSE'];
+        //Iterate over responses
+        for($i = 0; $i < sizeof($responses); $i++) {
+            $res_info = $responses[$i];
+            //traverse_xmlize($res_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //We'll need this later!!
+            $oldid = backup_todb($res_info['#']['ID']['0']['#']);
+
+            //Now, build the RESPONSES record structure
+            $response->attempt = $attempt_id;
+            $response->question = backup_todb($res_info['#']['QUESTION']['0']['#']);
+            $response->answer = backup_todb($res_info['#']['ANSWER']['0']['#']);
+            $response->grade = backup_todb($res_info['#']['GRADE']['0']['#']);
+
+            //We have to recode the question field
+            $question = backup_getid($restore->backup_unique_code,"quiz_questions",$response->question);
+            if ($question) {
+                $response->question = $question->new_id;
+            }
+
+            //We have to recode the answer field
+            //It depends of the question type !!
+            //We get the question first
+            $question = get_record("quiz_questions","id",$response->question);
+            //It exists
+            if ($question) {
+                //Depending of the qtype, we make different recodes
+                switch ($question->qtype) {
+                    case 1:    //SHORTANSWER QTYPE
+                        //Nothing to do. The response is a text.
+                        break;
+                    case 2:    //TRUEFALSE QTYPE
+                        //The answer is one answer id. We must recode it
+                        $answer = backup_getid($restore->backup_unique_code,"quiz_answers",$response->answer);
+                        if ($answer) {
+                            $response->answer = $answer->new_id;
+                        }
+                        break;
+                    case 3:    //MULTICHOICE QTYPE
+                        //The answer is a comma separated list of answers. We must recode them
+                        $answer_field = "";
+                        $in_first = true;
+                        $tok = strtok($response->answer,",");
+                        while ($tok) {    
+                            //Get the answer from backup_ids
+                            $answer = backup_getid($restore->backup_unique_code,"quiz_answers",$tok);
+                            if ($answer) {
+                                if ($in_first) {    
+                                    $answer_field .= $answer->new_id;          
+                                    $in_first = false;
+                                } else {  
+                                    $answer_field .= ",".$answer->new_id;
+                                }
+                            }       
+                            //check for next
+                            $tok = strtok(",");
+                        }
+                        $response->answer = $answer_field;
+                        break;
+                    case 4:    //RANDOM QTYPE
+                        //The answer links to another question id, we must recode it
+                        $answer_link = backup_getid($restore->backup_unique_code,"quiz_questions",$response->answer);
+                        if ($answer_link) {  
+                            $response->answer = $answer_link->new_id;
+                        }
+                        break;
+                    case 5:    //MATCH QTYPE
+                        //The answer is a comma separated list of hypen separated math_subs (for question and answer)
+                        $answer_field = "";    
+                        $in_first = true;
+                        $tok = strtok($response->answer,",");
+                        while ($tok) {
+                            //Extract the match_sub for the question and the answer
+                            $exploded = explode("-",$tok);      
+                            $match_question_id = $exploded[0];
+                            $match_answer_id = $exploded[1];
+                            //Get the match_sub from backup_ids
+                            $match_que = backup_getid($restore->backup_unique_code,"quiz_match_sub",$match_question_id);
+                            //Get the answer from backup_ids
+                            $match_ans = backup_getid($restore->backup_unique_code,"quiz_match_sub",$match_answer_id);
+                            if ($match_que and $match_ans) {
+                                if ($in_first) {
+                                    $answer_field .= $match_que->new_id."-".$match_ans->new_id;
+                                    $in_first = false;
+                                } else {
+                                    $answer_field .= ",".$match_que->new_id."-".$match_ans->new_id;
+                                }
+                            }
+                            //check for next
+                            $tok = strtok(",");
+                        }
+                        $response->answer = $answer_field;
+                        break;
+                    case 6:    //RANDOMSAMATCH QTYPE
+                        //The answer is a comma separated list of hypen separated question_id and answer_id. We must recode them
+                        $answer_field = "";
+                        $in_first = true;
+                        $tok = strtok($response->answer,",");
+                        while ($tok) {
+                            //Extract the question_id and the answer_id
+                            $exploded = explode("-",$tok);
+                            $question_id = $exploded[0];
+                            $answer_id = $exploded[1];
+                            //Get the question from backup_ids
+                            $que = backup_getid($restore->backup_unique_code,"quiz_questions",$question_id);
+                            //Get the answer from backup_ids
+                            $ans = backup_getid($restore->backup_unique_code,"quiz_answers",$answer_id);
+                            if ($que and $ans) {
+                                if ($in_first) {
+                                    $answer_field .= $que->new_id."-".$ans->new_id;
+                                    $in_first = false;
+                                } else { 
+                                    $answer_field .= ",".$que->new_id."-".$ans->new_id;
+                                }
+                            }
+                            //check for next
+                            $tok = strtok(",");
+                        }
+                        $response->answer = $answer_field;
+                        break;
+                    case 7:    //DESCRIPTION QTYPE
+                        //Nothing to do (there is no awser to this qtype)
+                        //But this case must exist !!
+                        break;
+                    default:   //UNMATCHED QTYPE.
+                        //This is an error (unimplemented qtype)
+                        $status = false;
+                        break;
+                }
+            } else {
+                $status = false;
+            }
+
+            //The structure is equal to the db, so insert the quiz_attempts
+            $newid = insert_record ("quiz_responses",$response);
+
+            //Do some output
+            if (($i+1) % 10 == 0) {
+                echo ".";
+                if (($i+1) % 200 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"quiz_responses",$oldid,
+                             $newid);
+            } else {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+    //This function restores the quiz_grades
+    function quiz_grades_restore_mods($quiz_id,$info,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get the quiz_grades array
+        $grades = $info['MOD']['#']['GRADES']['0']['#']['GRADE'];
+
+        //Iterate over grades
+        for($i = 0; $i < sizeof($grades); $i++) {
+            $gra_info = $grades[$i];
+            //traverse_xmlize($gra_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //We'll need this later!!
+            $oldid = backup_todb($gra_info['#']['ID']['0']['#']);
+            $olduserid = backup_todb($gra_info['#']['USERID']['0']['#']);
+
+            //Now, build the GRADES record structure
+            $grade->quiz = $quiz_id;
+            $grade->userid = backup_todb($gra_info['#']['USERID']['0']['#']);
+            $grade->grade = backup_todb($gra_info['#']['GRADEVAL']['0']['#']);
+            $grade->timemodified = backup_todb($gra_info['#']['TIMEMODIFIED']['0']['#']);
+
+            //We have to recode the userid field
+            $user = backup_getid($restore->backup_unique_code,"user",$grade->userid);
+            if ($user) {
+                $grade->userid = $user->new_id;
+            }
+
+            //The structure is equal to the db, so insert the quiz_grades
+            $newid = insert_record ("quiz_grades",$grade);
+
+            //Do some output
+            if (($i+1) % 10 == 0) {
+                echo ".";
+                if (($i+1) % 200 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"quiz_grades",$oldid,
+                             $newid);
+            } else {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+?>
diff --git a/mod/resource/backuplib.php b/mod/resource/backuplib.php
new file mode 100644 (file)
index 0000000..61e63b5
--- /dev/null
@@ -0,0 +1,77 @@
+<?PHP //$Id$
+    //This php script contains all the stuff to backup/restore
+    //resource mods
+
+    //This is the "graphical" structure of the resource mod:
+    //
+    //                     resource                                      
+    //                 (CL,pk->id,files)
+    //
+    // Meaning: pk->primary key field of the table
+    //          fk->foreign key to link with parent
+    //          nt->nested field (recursive data)
+    //          CL->course level info
+    //          UL->user level info
+    //          files->table may have files)
+    //
+    //-----------------------------------------------------------
+
+    //This function executes all the backup procedure about this mod
+    function resource_backup_mods($bf,$preferences) {
+        global $CFG;
+
+        $status = true; 
+
+        ////Iterate over resource table
+        $resources = get_records ("resource","course",$preferences->backup_course,"id");
+        if ($resources) {
+            foreach ($resources as $resource) {
+                //Start mod
+                fwrite ($bf,start_tag("MOD",3,true));
+                //Print assignment data
+                fwrite ($bf,full_tag("ID",4,false,$resource->id));
+                fwrite ($bf,full_tag("MODTYPE",4,false,"resource"));
+                fwrite ($bf,full_tag("NAME",4,false,$resource->name));
+                fwrite ($bf,full_tag("TYPE",4,false,$resource->type));
+                fwrite ($bf,full_tag("REFERENCE",4,false,$resource->reference));
+                fwrite ($bf,full_tag("SUMMARY",4,false,$resource->summary));
+                fwrite ($bf,full_tag("ALLTEXT",4,false,$resource->alltext));
+                fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$resource->timemodified));
+                //End mod
+                $status = fwrite ($bf,end_tag("MOD",3,true));
+            }
+        }
+        return $status;
+    }
+   
+   ////Return an array of info (name,value)
+   function resource_check_backup_mods($course,$user_data=false,$backup_unique_code) {
+        //First the course data
+        $info[0][0] = get_string("modulenameplural","resource");
+        if ($ids = resource_ids ($course)) {
+            $info[0][1] = count($ids);
+        } else {
+            $info[0][1] = 0;
+        }
+
+        return $info;
+    }
+
+
+
+
+
+
+    // INTERNAL FUNCTIONS. BASED IN THE MOD STRUCTURE
+
+    //Returns an array of resources id
+    function resource_ids ($course) {
+
+        global $CFG;
+
+        return get_records_sql ("SELECT a.id, a.course
+                                 FROM {$CFG->prefix}resource a
+                                 WHERE a.course = '$course'");
+    }
+   
+?>
diff --git a/mod/resource/restorelib.php b/mod/resource/restorelib.php
new file mode 100644 (file)
index 0000000..66334ca
--- /dev/null
@@ -0,0 +1,71 @@
+<?PHP //$Id$
+    //This php script contains all the stuff to backup/restore
+    //resource mods
+
+    //This is the "graphical" structure of the resource mod:
+    //
+    //                     resource                                      
+    //                 (CL,pk->id,files)
+    //
+    // Meaning: pk->primary key field of the table
+    //          fk->foreign key to link with parent
+    //          nt->nested field (recursive data)
+    //          CL->course level info
+    //          UL->user level info
+    //          files->table may have files)
+    //
+    //-----------------------------------------------------------
+
+    //This function executes all the restore procedure about this mod
+    function resource_restore_mods($mod,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get record from backup_ids
+        $data = backup_getid($restore->backup_unique_code,$mod->modtype,$mod->id);
+
+        if ($data) {
+            //Now get completed xmlized object
+            $info = $data->info;
+            //traverse_xmlize($info);                                                                     //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+          
+            //Now, build the RESOURCE record structure
+            $resource->course = $restore->course_id;
+            $resource->name = backup_todb($info['MOD']['#']['NAME']['0']['#']);
+            $resource->type = $info['MOD']['#']['TYPE']['0']['#'];
+            $resource->reference = backup_todb($info['MOD']['#']['REFERENCE']['0']['#']);
+            $resource->summary = backup_todb($info['MOD']['#']['SUMMARY']['0']['#']);
+            $resource->alltext = backup_todb($info['MOD']['#']['ALLTEXT']['0']['#']);
+            $resource->timemodified = $info['MOD']['#']['TIMEMODIFIED']['0']['#'];
+            //The structure is equal to the db, so insert the resource
+            $newid = insert_record ("resource",$resource);
+
+            //Do some output     
+            echo "<ul><li>Resource \"".$resource->name."\"<br>";
+            backup_flush(300);
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,$mod->modtype,
+                             $mod->id, $newid);
+   
+            } else {
+                $status = false;
+            }
+
+            //Finalize ul        
+            echo "</ul>";
+
+        } else {
+            $status = false;
+        }
+
+        return $status;
+    }
+   
+?>
diff --git a/mod/survey/backuplib.php b/mod/survey/backuplib.php
new file mode 100644 (file)
index 0000000..d3a6135
--- /dev/null
@@ -0,0 +1,174 @@
+<?PHP //$Id$
+    //This php script contains all the stuff to backup/restore
+    //survey mods
+
+    //This is the "graphical" structure of the survey mod:
+    //                                                    --------------------
+    //                           survey                   | survey_questions |
+    //                        (CL,pk->id)                 |(CL,pk->id,?????) |
+    //                            |                       --------------------
+    //                            |
+    //             -----------------------------------        
+    //             |                                 |
+    //        survey_analysis                   survey_answers
+    //    (UL,pk->id, fk->survey)           (UL,pk->id, fk->survey)
+    //
+    // Meaning: pk->primary key field of the table
+    //          fk->foreign key to link with parent
+    //          nt->nested field (recursive data)
+    //          CL->course level info
+    //          UL->user level info
+    //          files->table may have files)
+    //
+    //-----------------------------------------------------------
+
+    function survey_backup_mods($bf,$preferences) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Iterate over survey table
+        $surveys = get_records ("survey","course",$preferences->backup_course,"id");
+        if ($surveys) {
+            foreach ($surveys as $survey) {
+                //Start mod
+                fwrite ($bf,start_tag("MOD",3,true));
+                //Print choice data
+                fwrite ($bf,full_tag("ID",4,false,$survey->id));
+                fwrite ($bf,full_tag("MODTYPE",4,false,"survey"));
+                fwrite ($bf,full_tag("TEMPLATE",4,false,$survey->template));
+                fwrite ($bf,full_tag("DAYS",4,false,$survey->days));
+                fwrite ($bf,full_tag("TIMECREATED",4,false,$survey->timecreated));
+                fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$survey->timemodified));
+                fwrite ($bf,full_tag("NAME",4,false,$survey->name));
+                fwrite ($bf,full_tag("INTRO",4,false,$survey->intro));
+                fwrite ($bf,full_tag("QUESTIONS",4,false,$survey->questions));
+
+                //if we've selected to backup users info, then execute backup_survey_answers and
+                //backup_survey_analysis
+                if ($preferences->mods["survey"]->userinfo) {
+                    $status = backup_survey_answers($bf,$preferences,$survey->id);
+                    $status = backup_survey_analysis($bf,$preferences,$survey->id);
+                }
+                //End mod
+                $status =fwrite ($bf,end_tag("MOD",3,true));
+            }
+        }
+        return $status;
+    }
+
+    //Backup survey_answers contents (executed from survey_backup_mods)
+    function backup_survey_answers ($bf,$preferences,$survey) {
+
+        global $CFG;
+
+        $status = true;
+
+        $survey_answers = get_records("survey_answers","survey",$survey,"id");
+        //If there is answers
+        if ($survey_answers) {
+            //Write start tag
+            $status =fwrite ($bf,start_tag("ANSWERS",4,true));
+            //Iterate over each answer
+            foreach ($survey_answers as $sur_ans) {
+                //Start answer
+                $status =fwrite ($bf,start_tag("ANSWER",5,true));
+                //Print survey_answers contents
+                fwrite ($bf,full_tag("ID",6,false,$sur_ans->id));
+                fwrite ($bf,full_tag("USERID",6,false,$sur_ans->userid));
+                fwrite ($bf,full_tag("QUESTION",6,false,$sur_ans->question));
+                fwrite ($bf,full_tag("TIME",6,false,$sur_ans->time));
+                fwrite ($bf,full_tag("ANSWER1",6,false,$sur_ans->answer1));
+                fwrite ($bf,full_tag("ANSWER2",6,false,$sur_ans->answer2));
+                //End answer
+                $status =fwrite ($bf,end_tag("ANSWER",5,true));
+            }
+            //Write end tag
+            $status =fwrite ($bf,end_tag("ANSWERS",4,true));
+        }
+        return $status;
+    }
+
+    //Backup survey_analysis contents (executed from survey_backup_mods)
+    function backup_survey_analysis ($bf,$preferences,$survey) {
+
+        global $CFG;
+
+        $status = true;
+
+        $survey_analysis = get_records("survey_analysis","survey",$survey,"id");
+        //If there is analysis
+        if ($survey_analysis) {
+            //Write start tag
+            $status =fwrite ($bf,start_tag("ANALYSIS",4,true));
+            //Iterate over each analysis
+            foreach ($survey_analysis as $sur_ana) {
+                //Start answer
+                $status =fwrite ($bf,start_tag("ANALYS",5,true));
+                //Print survey_analysis contents
+                fwrite ($bf,full_tag("ID",6,false,$sur_ana->id));
+                fwrite ($bf,full_tag("USERID",6,false,$sur_ana->userid));
+                fwrite ($bf,full_tag("NOTES",6,false,$sur_ana->notes));
+                //End answer
+                $status =fwrite ($bf,end_tag("ANALYS",5,true));
+            }
+            //Write end tag
+            $status =fwrite ($bf,end_tag("ANALYSIS",4,true));
+        }
+        return $status;
+    }
+
+    ////Return an array of info (name,value)
+   function survey_check_backup_mods($course,$user_data=false,$backup_unique_code) {
+       //First the course data
+       $info[0][0] = get_string("modulenameplural","survey");
+       if ($ids = survey_ids ($course)) {
+           $info[0][1] = count($ids);
+       } else {
+           $info[0][1] = 0;
+       }
+
+        //Now, if requested, the user_data
+        if ($user_data) {
+            //Subscriptions
+            $info[1][0] = get_string("answers","survey");
+            if ($ids = survey_answer_ids_by_course ($course)) {
+                $info[1][1] = count($ids);
+            } else {
+                $info[1][1] = 0;
+            }
+        }
+        return $info;
+    }
+
+
+
+
+
+
+    // INTERNAL FUNCTIONS. BASED IN THE MOD STRUCTURE
+
+    //Returns an array of surveys id
+    function survey_ids ($course) {
+
+        global $CFG;
+
+        return get_records_sql ("SELECT a.id, a.course
+                                 FROM {$CFG->prefix}survey a
+                                 WHERE a.course = '$course'");
+    }
+
+    //Returns an array of survey answer id
+    function survey_answer_ids_by_course ($course) {
+
+        global $CFG;
+
+        return get_records_sql ("SELECT s.id , s.survey
+                                 FROM {$CFG->prefix}survey_answers s,
+                                      {$CFG->prefix}survey a
+                                 WHERE a.course = '$course' AND
+                                       s.survey = a.id");
+    }
+
+?>
diff --git a/mod/survey/restorelib.php b/mod/survey/restorelib.php
new file mode 100644 (file)
index 0000000..c17f167
--- /dev/null
@@ -0,0 +1,200 @@
+<?PHP //$Id$
+    //This php script contains all the stuff to backup/restore
+    //survey mods
+
+    //This is the "graphical" structure of the survey mod:
+    //                                                    --------------------
+    //                           survey                   | survey_questions |
+    //                        (CL,pk->id)                 |(CL,pk->id,?????) |
+    //                            |                       --------------------
+    //                            |
+    //             -----------------------------------        
+    //             |                                 |
+    //        survey_analysis                   survey_answers
+    //    (UL,pk->id, fk->survey)           (UL,pk->id, fk->survey)
+    //
+    // Meaning: pk->primary key field of the table
+    //          fk->foreign key to link with parent
+    //          nt->nested field (recursive data)
+    //          CL->course level info
+    //          UL->user level info
+    //          files->table may have files)
+    //
+    //-----------------------------------------------------------
+
+
+    function survey_restore_mods($mod,$restore) {
+
+        global $CFG,$db;
+
+        $status = true;
+
+        //Get record from backup_ids
+        $data = backup_getid($restore->backup_unique_code,$mod->modtype,$mod->id);
+
+        if ($data) {
+            //Now get completed xmlized object   
+            $info = $data->info;
+            //traverse_xmlize($info);                                                                     //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //Now, build the SURVEY record structure
+            $survey->course = $restore->course_id;
+            $survey->template = backup_todb($info['MOD']['#']['TEMPLATE']['0']['#']);
+            $survey->days = backup_todb($info['MOD']['#']['DAYS']['0']['#']);
+            $survey->timecreated = backup_todb($info['MOD']['#']['TIMECREATED']['0']['#']);
+            $survey->timemodified = backup_todb($info['MOD']['#']['TIMEMODIFIED']['0']['#']);
+            $survey->name = backup_todb($info['MOD']['#']['NAME']['0']['#']);
+            $survey->intro = backup_todb($info['MOD']['#']['INTRO']['0']['#']);
+            $survey->questions = backup_todb($info['MOD']['#']['QUESTIONS']['0']['#']);
+
+            //The structure is equal to the db, so insert the survey
+            $newid = insert_record ("survey",$survey);
+
+            //Do some output
+            echo "<ul><li>Survey \"".$survey->name."\"<br>";
+            backup_flush(300);
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,$mod->modtype,
+                             $mod->id, $newid);
+                //Now check if want to restore user data and do it.
+                if ($restore->mods[survey]->userinfo) {
+                    //Restore survey_answers
+                    $status = survey_answers_restore_mods ($newid,$info,$restore);
+                    //Restore survey_analysis
+                    if ($status) {
+                        $status = survey_analysis_restore_mods ($newid,$info,$restore);
+                    }
+                }
+            } else {
+                $status = false;
+            }
+
+            //Finalize ul
+            echo "</ul>";
+
+        } else {
+            $status = false;
+        }
+
+        return $status;
+    }
+
+    //This function restores the survey_answers
+    function survey_answers_restore_mods($survey_id,$info,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get the answers array
+        $answers = $info['MOD']['#']['ANSWERS']['0']['#']['ANSWER'];
+
+        //Iterate over answers
+        for($i = 0; $i < sizeof($answers); $i++) {
+            $sub_info = $answers[$i];
+            //traverse_xmlize($sub_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //We'll need this later!!
+            $oldid = backup_todb($sub_info['#']['ID']['0']['#']);
+            $olduserid = backup_todb($sub_info['#']['USERID']['0']['#']);
+
+            //Now, build the SURVEY_ANSWERS record structure
+            $answer->survey = $survey_id;
+            $answer->userid = backup_todb($sub_info['#']['USERID']['0']['#']);
+            $answer->question = backup_todb($sub_info['#']['QUESTION']['0']['#']);
+            $answer->time = backup_todb($sub_info['#']['TIME']['0']['#']);
+            $answer->answer1 = backup_todb($sub_info['#']['ANSWER1']['0']['#']);
+            $answer->answer2 = backup_todb($sub_info['#']['ANSWER2']['0']['#']);
+
+            //We have to recode the userid field
+            $user = backup_getid($restore->backup_unique_code,"user",$answer->userid);
+            if ($user) {
+                $answer->userid = $user->new_id;
+            }
+
+            //The structure is equal to the db, so insert the survey_answers
+            $newid = insert_record ("survey_answers",$answer);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                echo ".";
+                if (($i+1) % 1000 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"survey_answers",$oldid,
+                             $newid);
+            } else {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+
+    //This function restores the survey_analysis
+    function survey_analysis_restore_mods($survey_id,$info,$restore) {
+
+        global $CFG;
+
+        $status = true;
+
+        //Get the analysis array
+        $analysis = $info['MOD']['#']['ANALYSIS']['0']['#']['ANALYS'];
+
+        //Iterate over analysis
+        for($i = 0; $i < sizeof($analysis); $i++) {
+            $sub_info = $analysis[$i];
+            //traverse_xmlize($sub_info);                                                                 //Debug
+            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+            //$GLOBALS['traverse_array']="";                                                              //Debug
+
+            //We'll need this later!!
+            $oldid = backup_todb($sub_info['#']['ID']['0']['#']);
+            $olduserid = backup_todb($sub_info['#']['USERID']['0']['#']);
+
+            //Now, build the SURVEY_ANALYSIS record structure
+            $analys->survey = $survey_id;
+            $analys->userid = backup_todb($sub_info['#']['USERID']['0']['#']);
+            $analys->notes = backup_todb($sub_info['#']['NOTES']['0']['#']);
+
+            //We have to recode the userid field
+            $user = backup_getid($restore->backup_unique_code,"user",$analys->userid);
+            if ($user) {
+                $analys->userid = $user->new_id;
+            }
+
+            //The structure is equal to the db, so insert the survey_analysis
+            $newid = insert_record ("survey_analysis",$analys);
+
+            //Do some output
+            if (($i+1) % 50 == 0) {
+                echo ".";       
+                if (($i+1) % 1000 == 0) {
+                    echo "<br>";
+                }
+                backup_flush(300);
+            }
+
+            if ($newid) {
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,"survey_analysis",$oldid,
+                             $newid);
+            } else {
+                $status = false;
+            }
+        }
+
+        return $status;
+    }
+?>