2 //Functions used in restore
4 //This function unzips a zip file in the same directory that it is
5 //It automatically uses pclzip or command line unzip
6 function restore_unzip ($file,$moodle_home) {
12 if (empty($CFG->unzip
)) { // Use built-in php-based unzip function
13 include_once($moodle_home."/lib/pclzip/pclzip.lib.php");
14 $archive = new PclZip($file);
15 if (!$list = $archive->extract(dirname($file))) {
18 } else { // Use external unzip program
19 $command = "cd ".dirname($file)."; $CFG->unzip -o ".basename($file);
26 //This function checks if moodle.xml seems to be a valid xml file
27 //(exists, has an xml header and a course main tag
28 function restore_check_moodle_file ($file) {
33 if ($status = is_file($file)) {
34 //Open it and read the first 200 bytes (chars)
35 $handle = fopen ($file, "r");
36 $first_chars = fread($handle,200);
37 $status = fclose ($handle);
38 //Chek if it has the requires strings
40 $status = strpos($first_chars,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
41 if ($status !== false) {
42 $status = strpos($first_chars,"<MOODLE_BACKUP>");
50 //This function read the xml file and store it data from the info zone in an object
51 function restore_read_xml_info ($xml_file) {
53 //We call the main read_xml function, with todo = INFO
54 $info = restore_read_xml ($xml_file,"INFO",false);
59 //This function read the xml file and store it data from the course header zone in an object
60 function restore_read_xml_course_header ($xml_file) {
62 //We call the main read_xml function, with todo = COURSE_HEADER
63 $info = restore_read_xml ($xml_file,"COURSE_HEADER",false);
68 //This function read the xml file and store its data from the sections in a object
69 function restore_read_xml_sections ($xml_file) {
71 //We call the main read_xml function, with todo = SECTIONS
72 $info = restore_read_xml ($xml_file,"SECTIONS",false);
77 //This function read the xml file and store its data from the users in
78 //backup_ids->info db (and user's id in $info)
79 function restore_read_xml_users ($restore,$xml_file) {
81 //We call the main read_xml function, with todo = USERS
82 $info = restore_read_xml ($xml_file,"USERS",$restore);
87 //This function read the xml file and store its data from the questions in
88 //backup_ids->info db (and category's id in $info)
89 function restore_read_xml_questions ($restore,$xml_file) {
91 //We call the main read_xml function, with todo = QUESTIONS
92 $info = restore_read_xml ($xml_file,"QUESTIONS",$restore);
97 //This function read the xml file and store its data from the modules in
99 function restore_read_xml_modules ($restore,$xml_file) {
101 //We call the main read_xml function, with todo = MODULES
102 $info = restore_read_xml ($xml_file,"MODULES",$restore);
107 //This function prints the contents from the info parammeter passed
108 function restore_print_info ($info) {
112 //This is tha align to every ingo table
113 $table->align
= array ("RIGHT","LEFT");
114 //This is the nowrap clause
115 $table->wrap
= array ("","NOWRAP");
117 $table->width
= "70%";
118 //Put interesting info in table
119 //The backup original name
120 $tab[0][0] = "<b>".get_string("backuporiginalname").":</b>";
121 $tab[0][1] = $info->backup_name
;
123 $tab[1][0] = "<b>".get_string("moodleversion").":</b>";
124 $tab[1][1] = $info->backup_moodle_release
." (".$info->backup_moodle_version
.")";
126 $tab[2][0] = "<b>".get_string("backupversion").":</b>";
127 $tab[2][1] = $info->backup_backup_release
." (".$info->backup_backup_version
.")";
129 $tab[3][0] = "<b>".get_string("backupdate").":</b>";
130 $tab[3][1] = userdate($info->backup_date
);
132 print_heading(get_string("backup").":");
134 //Print backup general info
136 //Now backup contents in another table
141 foreach ($mods as $key => $mod) {
142 $tab[$elem][0] = "<b>".get_string("modulenameplural",$key).":</b>";
143 if ($mod->backup
== "false") {
144 $tab[$elem][1] = get_string("notincluded");
146 if ($mod->userinfo
== "true") {
147 $tab[$elem][1] = get_string("included")." ".get_string("withuserdata");
149 $tab[$elem][1] = get_string("included")." ".get_string("withoutuserdata");
155 $tab[$elem][0] = "<b>".get_string("users").":</b>";
156 $tab[$elem][1] = get_string($info->backup_users
);
159 $tab[$elem][0] = "<b>".get_string("logs").":</b>";
160 if ($info->backup_logs
== "true") {
161 $tab[$elem][1] = get_string("yes");
163 $tab[$elem][1] = get_string("no");
167 $tab[$elem][0] = "<b>".get_string("userfiles").":</b>";
168 if ($info->backup_user_files
== "true") {
169 $tab[$elem][1] = get_string("yes");
171 $tab[$elem][1] = get_string("no");
175 $tab[$elem][0] = "<b>".get_string("coursefiles").":</b>";
176 if ($info->backup_course_files
== "true") {
177 $tab[$elem][1] = get_string("yes");
179 $tab[$elem][1] = get_string("no");
184 print_heading(get_string("backupdetails").":");
185 //Print backup general info
194 //This function prints the contents from the course_header parammeter passed
195 function restore_print_course_header ($course_header) {
198 if ($course_header) {
199 //This is tha align to every ingo table
200 $table->align
= array ("RIGHT","LEFT");
202 $table->width
= "70%";
203 //Put interesting course header in table
205 $tab[0][0] = "<b>".get_string("name").":</b>";
206 $tab[0][1] = $course_header->course_fullname
." (".$course_header->course_shortname
.")";
208 $tab[1][0] = "<b>".get_string("summary").":</b>";
209 $tab[1][1] = $course_header->course_summary
;
212 print_heading(get_string("course").":");
213 //Print backup course header info
221 //This function create a new course record.
222 //When finished, course_header contains the id of the new course
223 function restore_create_new_course($restore,&$course_header) {
229 $fullname = $course_header->course_fullname
;
230 $shortname = $course_header->course_shortname
;
231 $currentfullname = "";
232 $currentshortname = "";
234 //Iteratere while the name exists
237 $suffixfull = " ".get_string("copy")." ".$counter;
238 $suffixshort = "-".$counter;
243 $currentfullname = $fullname.$suffixfull;
244 $currentshortname = $shortname.$suffixshort;
245 $course = get_record("course","fullname",addslashes($currentfullname));
249 //New name = currentname
250 $course_header->course_fullname
= $currentfullname;
251 $course_header->course_shortname
= $currentshortname;
253 //Now calculate the category
254 $category = get_record("course_categories","id",$course_header->category
->id
,
255 "name",addslashes($course_header->category
->name
));
256 //If no exists, try by name only
258 $category = get_record("course_categories","name",addslashes($course_header->category
->name
));
260 //If no exists, get category id 1
262 $category = get_record("course_categories","id","1");
264 //If exists, put new category id
266 $course_header->category
->id
= $category->id
;
267 $course_header->category
->name
= $category->name
;
268 //Error, cannot locate category
270 $course_header->category
->id
= 0;
271 $course_header->category
->name
= getstring("unknowcategory");
275 //Create the course_object
277 $course->category
= addslashes($course_header->category
->id
);
278 $course->password
= addslashes($course_header->course_password
);
279 $course->fullname
= addslashes($course_header->course_fullname
);
280 $course->shortname
= addslashes($course_header->course_shortname
);
281 $course->summary
= addslashes($course_header->course_summary
);
282 $course->format
= addslashes($course_header->course_format
);
283 $course->newsitems
= addslashes($course_header->course_newsitems
);
284 $course->teacher
= addslashes($course_header->course_teacher
);
285 $course->teachers
= addslashes($course_header->course_teachers
);
286 $course->student
= addslashes($course_header->course_student
);
287 $course->students
= addslashes($course_header->course_students
);
288 $course->guest
= addslashes($course_header->course_guest
);
289 $course->startdate
= addslashes($course_header->course_startdate
);
290 $course->numsections
= addslashes($course_header->course_numsections
);
291 $course->showrecent
= addslashes($course_header->course_showrecent
);
292 $course->marker
= addslashes($course_header->course_marker
);
293 $course->visible
= addslashes($course_header->course_visible
);
294 $course->timecreated
= addslashes($course_header->course_timecreated
);
295 $course->timemodified
= addslashes($course_header->course_timemodified
);
296 //Now insert the record
297 $newid = insert_record("course",$course);
299 //save old and new course id
300 backup_putid ($restore->backup_unique_code
,"course",$course_header->course_id
,$newid);
301 //Replace old course_id in course_header
302 $course_header->course_id
= $newid;
311 //This function creates all the course_sections and course_modules from xml
312 //when restoring in a new course or simply checks sections and create records
313 //in backup_ids when restoring in a existing course
314 function restore_create_sections($restore,$xml_file) {
320 if (!file_exists($xml_file)) {
325 $info = restore_read_xml_sections($xml_file);
327 //Put the info in the DB, recoding ids and saving the in backup tables
332 //For each, section, save it to db
333 foreach ($info->sections
as $key => $sect) {
335 $section->course
= $restore->course_id
;
336 $section->section
= $sect->number
;
337 $section->summary
= addslashes($sect->summary
);
338 $section->visible
= $sect->visible
;
339 $section->sequence
= "";
340 //Now calculate the section's newid
342 if ($restore->restoreto
== 1) {
343 //Save it to db (only if restoring to new course)
344 $newid = insert_record("course_sections",$section);
346 //Get section id when restoring in existing course
347 $rec = get_record("course_sections","course",$restore->course_id
,
348 "section",$section->section
);
349 //If that section doesn't exist, get section 0 (every mod will be
352 $rec = get_record("course_sections","course",$restore->course_id
,
356 $sequence = $rec->sequence
;
359 //save old and new section id
360 backup_putid ($restore->backup_unique_code
,"course_sections",$key,$newid);
364 //If all is OK, go with associated mods
366 //If we have mods in the section
368 //For each mod inside section
369 foreach ($sect->mods
as $keym => $mod) {
370 //Check if we've to restore this module
371 if ($restore->mods
[$mod->type
]->restore
) {
372 //Get the module id from modules
373 $module = get_record("modules","name",$mod->type
);
375 $course_module->course
= $restore->course_id
;
376 $course_module->module
= $module->id
;
377 $course_module->section
= $newid;
378 $course_module->added
= $mod->added
;
379 $course_module->deleted
= $mod->deleted
;
380 $course_module->score
= $mod->score
;
381 $course_module->visible
= $mod->visible
;
382 $course_module->instance
= null;
383 //NOTE: The instance (new) is calculated and updated in db in the
384 // final step of the restore. We don't know it yet.
385 //print_object($course_module); //Debug
387 $newidmod = insert_record("course_modules",$course_module);
389 //save old and new module id
390 //In the info field, we save the original instance of the module
392 backup_putid ($restore->backup_unique_code
,"course_modules",
393 $keym,$newidmod,$mod->instance
);
397 //Now, calculate the sequence field
400 $sequence .= ",".$newidmod;
402 $sequence = $newidmod;
412 //If all is OK, update sequence field in course_sections
415 $rec->sequence
= $sequence;
416 //Unset other fields before update (we don't want them)
417 //Only need id and sequence !! Previously, existing bug
418 //because update without addslashes in summary
420 unset($rec->section
);
421 unset($rec->summary
);
422 unset($rec->visible
);
423 $status = update_record("course_sections",$rec);
432 //This function creates all the user, user_students, user_teachers
433 //user_course_creators and user_admins from xml
434 function restore_create_users($restore,$xml_file) {
440 if (!file_exists($xml_file)) {
445 //info will contain the old_id of every user
446 //in backup_ids->info will be the real info (serialized)
447 $info = restore_read_xml_users($restore,$xml_file);
450 //Now, get evey user_id from $info and user data from $backup_ids
451 //and create the necessary records (users, user_students, user_teachers
452 //user_course_creators and user_admins
454 //For each, user, take its info from backup_ids
455 foreach ($info->users
as $userid) {
456 $rec = backup_getid($restore->backup_unique_code
,"user",$userid);
458 //Calculate if it is a course user
459 //Has role teacher or student or admin or coursecreator
460 $is_course_user = ($user->roles
[teacher
] or $user->roles
[student
] or
461 $user->roles
[admin
] or $user->roles
[coursecreator
]);
462 //Check if it's admin and coursecreator
463 $is_admin = ($user->roles
[admin
]);
464 $is_coursecreator = ($user->roles
[coursecreator
]);
465 //Check if it's teacher and student
466 $is_teacher = ($user->roles
[teacher
]);
467 $is_student = ($user->roles
[student
]);
468 //To store new ids created
470 //check if it exists (by username) and get its id
472 $user_data = get_record("user","username",$user->username
);
474 $user_exists = false;
476 $newid = $user_data->id
;
478 //Flags to see if we have to create the user and roles
480 $create_roles = true;
482 //If we are restoring course users and it isn't a course user
483 if ($restore->users
== 1 and !$is_course_user) {
484 //If only restoring course_users and user isn't a course_user, inform to $backup_ids
485 $status = backup_putid($restore->backup_unique_code
,"user",$userid,null,'notincourse');
486 $create_user = false;
487 $create_roles = false;
490 if ($user_exists and $create_user) {
491 //If user exists mark its newid in backup_ids (the same than old)
492 $status = backup_putid($restore->backup_unique_code
,"user",$userid,$newid,'exists');
493 $create_user = false;
496 //Here, if create_user, do it
498 //We addslashes to necessary fields
499 $user->username
= addslashes($user->username
);
500 $user->firstname
= addslashes($user->firstname
);
501 $user->lastname
= addslashes($user->lastname
);
502 $user->email
= addslashes($user->email
);
503 $user->institution
= addslashes($user->institution
);
504 $user->department
= addslashes($user->department
);
505 $user->address
= addslashes($user->address
);
506 $user->city
= addslashes($user->city
);
507 $user->url
= addslashes($user->url
);
508 $user->description
= addslashes($user->description
);
509 //We are going to create the user
510 //The structure is exactly as we need
511 $newid = insert_record ("user",$user);
513 $status = backup_putid($restore->backup_unique_code
,"user",$userid,$newid,"new");
516 //Here, if create_roles, do it as necessary
518 //Get the newid and currecnt info from backup_ids
519 $data = backup_getid($restore->backup_unique_code
,"user",$userid);
520 $newid = $data->new_id
;
521 $currinfo = $data->info
.",";
522 //Now, depending of the role, create records in user_studentes and user_teacher
523 //and/or mark it in backup_ids
525 //If the record (user_admins) doesn't exists
526 if (!record_exists("user_admins","userid",$newid)) {
527 //Only put status in backup_ids
528 $currinfo = $currinfo."admin,";
529 $status = backup_putid($restore->backup_unique_code
,"user",$userid,$newid,$currinfo);
532 if ($is_coursecreator) {
533 //If the record (user_coursecreators) doesn't exists
534 if (!record_exists("user_coursecreators","userid",$newid)) {
535 //Only put status in backup_ids
536 $currinfo = $currinfo."coursecreator,";
537 $status = backup_putid($restore->backup_unique_code
,"user",$userid,$newid,$currinfo);
541 //If the record (teacher) doesn't exists
542 if (!record_exists("user_teachers","userid",$newid,"course", $restore->course_id
)) {
543 //Put status in backup_ids
544 $currinfo = $currinfo."teacher,";
545 $status = backup_putid($restore->backup_unique_code
,"user",$userid,$newid,$currinfo);
546 //Set course and user
547 $user->roles
[teacher
]->course
= $restore->course_id
;
548 $user->roles
[teacher
]->userid
= $newid;
549 //Insert data in user_teachers
550 //The structure is exactly as we need
551 $status = insert_record("user_teachers",$user->roles
[teacher
]);
555 //If the record (student) doesn't exists
556 if (!record_exists("user_students","userid",$newid,"course", $restore->course_id
)) {
557 //Put status in backup_ids
558 $currinfo = $currinfo."student,";
559 $status = backup_putid($restore->backup_unique_code
,"user",$userid,$newid,$currinfo);
560 //Set course and user
561 $user->roles
[student
]->course
= $restore->course_id
;
562 $user->roles
[student
]->userid
= $newid;
563 //Insert data in user_students
564 //The structure is exactly as we need
565 $status = insert_record("user_students",$user->roles
[student
]);
568 if (!$is_course_user) {
569 //If the record (user) doesn't exists
570 if (!record_exists("user","id",$newid)) {
571 //Put status in backup_ids
572 $currinfo = $currinfo."user,";
573 $status = backup_putid($restore->backup_unique_code
,"user",$userid,$newid,$currinfo);
585 //This function creates all the categories and questions
586 //from xml (STEP1 of quiz restore)
587 function restore_create_questions($restore,$xml_file) {
593 if (!file_exists($xml_file)) {
598 //info will contain the old_id of every category
599 //in backup_ids->info will be the real info (serialized)
600 $info = restore_read_xml_questions($restore,$xml_file);
602 //Now, if we have anything in info, we have to restore that
603 //categories/questions
605 if ($info !== true) {
606 //Iterate over each category
607 foreach ($info as $category) {
608 $catrestore = "quiz_restore_question_categories";
609 if (function_exists($catrestore)) {
610 //print_object ($category); //Debug
611 $status = $catrestore($category,$restore);
613 //Something was wrong. Function should exist.
624 //This function restores the userfiles from the temp (user_files) directory to the
625 //dataroot/users directory
626 function restore_user_files($restore) {
632 //First, we check to "users" exists and create is as necessary
634 $dest_dir = $CFG->dataroot
."/users";
635 $status = check_dir_exists($dest_dir,true);
637 //Now, we iterate over "user_files" records to check if that user dir must be
638 //copied (and renamed) to the "users" dir.
639 $rootdir = $CFG->dataroot
."/temp/backup/".$restore->backup_unique_code
."/user_files";
640 //Check if directory exists
641 if (is_dir($rootdir)) {
642 $list = list_directories ($rootdir);
646 foreach ($list as $dir) {
647 //Look for dir like username in backup_ids
648 $data = get_record ("backup_ids","backup_code",$restore->backup_unique_code
,
651 //If thar user exists in backup_ids
653 //Only it user has been created now
654 if (strpos($data->info
,"new") !== false) {
655 //Copy the old_dir to its new location (and name) !!
656 //Only if destination doesn't exists
657 if (!file_exists($dest_dir."/".$data->new_id
)) {
658 $status = backup_copy_file($rootdir."/".$dir,
659 $dest_dir."/".$data->new_id
);
663 if ($counter %
2 == 0) {
665 if ($counter %
40 == 0) {
675 //If status is ok and whe have dirs created, returns counter to inform
676 if ($status and $counter) {
683 //This function restores the course files from the temp (course_files) directory to the
684 //dataroot/course_id directory
685 function restore_course_files($restore) {
691 //First, we check to "course_id" exists and create is as necessary
693 $dest_dir = $CFG->dataroot
."/".$restore->course_id
;
694 $status = check_dir_exists($dest_dir,true);
696 //Now, we iterate over "course_files" records to check if that file/dir must be
697 //copied to the "dest_dir" dir.
698 $rootdir = $CFG->dataroot
."/temp/backup/".$restore->backup_unique_code
."/course_files";
699 //Check if directory exists
700 if (is_dir($rootdir)) {
701 $list = list_directories_and_files ($rootdir);
705 foreach ($list as $dir) {
706 //Copy the dir to its new location
707 //Only if destination file/dir doesn exists
708 if (!file_exists($dest_dir."/".$dir)) {
709 $status = backup_copy_file($rootdir."/".$dir,
714 if ($counter %
2 == 0) {
716 if ($counter %
40 == 0) {
724 //If status is ok and whe have dirs created, returns counter to inform
725 if ($status and $counter) {
733 //This function creates all the structures for every module in backup file
734 //Depending what has been selected.
735 function restore_create_modules($restore,$xml_file) {
741 if (!file_exists($xml_file)) {
746 //info will contain the id and modtype of every module
747 //in backup_ids->info will be the real info (serialized)
748 $info = restore_read_xml_modules($restore,$xml_file);
751 //Now, if we have anything in info, we have to restore that mods
752 //from backup_ids (calling every mod restore function)
754 if ($info !== true) {
755 //Iterate over each module
756 foreach ($info as $mod) {
757 $modrestore = $mod->modtype
."_restore_mods";
758 if (function_exists($modrestore)) {
759 //print_object ($mod); //Debug
760 $status = $modrestore($mod,$restore);
762 //Something was wrong. Function should exist.
773 //This function adjusts the instance field into course_modules. It's executed after
774 //modules restore. There, we KNOW the new instance id !!
775 function restore_check_instances($restore) {
781 //We are going to iterate over each course_module saved in backup_ids
782 $course_modules = get_records_sql("SELECT old_id,new_id
783 FROM {$CFG->prefix}backup_ids
784 WHERE backup_code = '$restore->backup_unique_code' AND
785 table_name = 'course_modules'");
786 if ($course_modules) {
787 foreach($course_modules as $cm) {
788 //Get full record, using backup_getids
789 $cm_module = backup_getid($restore->backup_unique_code
,"course_modules",$cm->old_id
);
790 //Now we are going to the REAL course_modules to get its type (field module)
791 $module = get_record("course_modules","id",$cm_module->new_id
);
793 //We know the module type id. Get the name from modules
794 $type = get_record("modules","id",$module->module
);
796 //We know the type name and the old_id. Get its new_id
797 //from backup_ids. It's the instance !!!
798 $instance = backup_getid($restore->backup_unique_code
,$type->name
,$cm_module->info
);
800 //We have the new instance, so update the record in course_modules
801 $module->instance
= $instance->new_id
;
802 //print_object ($module); //Debug
803 $status = update_record("course_modules",$module);
820 //=====================================================================================
822 //== XML Functions (SAX) ==
824 //=====================================================================================
826 //This is the class used to do all the xml parse
829 var $level = 0; //Level we are
830 var $counter = 0; //Counter
831 var $tree = array(); //Array of levels we are
832 var $content = ""; //Content under current level
833 var $todo = ""; //What we hav to do when parsing
834 var $info = ""; //Information collected. Temp storage. Used to return data after parsing.
835 var $temp = ""; //Temp storage.
836 var $preferences = ""; //Preferences about what to load !!
837 var $finished = false; //Flag to say xml_parse to stop
839 //This function is used to get the current contents property value
840 //They are trimed and converted from utf8
841 function getContents() {
842 return trim(utf8_decode($this->content
));
845 //This is the startTag handler we use where we are reading the info zone (todo="INFO")
846 function startElementInfo($parser, $tagName, $attrs) {
849 $this->tree
[$this->level
] = $tagName;
851 //Output something to avoid browser timeouts...
854 //Check if we are into INFO zone
855 //if ($this->tree[2] == "INFO") //Debug
856 // echo $this->level.str_repeat(" ",$this->level*2)."<".$tagName."><br>\n"; //Debug
859 //This is the startTag handler we use where we are reading the course header zone (todo="COURSE_HEADER")
860 function startElementCourseHeader($parser, $tagName, $attrs) {
863 $this->tree
[$this->level
] = $tagName;
865 //Output something to avoid browser timeouts...
868 //Check if we are into COURSE_HEADER zone
869 //if ($this->tree[3] == "HEADER") //Debug
870 // echo $this->level.str_repeat(" ",$this->level*2)."<".$tagName."><br>\n"; //Debug
873 //This is the startTag handler we use where we are reading the sections zone (todo="SECTIONS")
874 function startElementSections($parser, $tagName, $attrs) {
877 $this->tree
[$this->level
] = $tagName;
879 //Output something to avoid browser timeouts...
882 //Check if we are into SECTIONS zone
883 //if ($this->tree[3] == "SECTIONS") //Debug
884 // echo $this->level.str_repeat(" ",$this->level*2)."<".$tagName."><br>\n"; //Debug
887 //This is the startTag handler we use where we are reading the user zone (todo="USERS")
888 function startElementUsers($parser, $tagName, $attrs) {
891 $this->tree
[$this->level
] = $tagName;
893 //Check if we are into USERS zone
894 //if ($this->tree[3] == "USERS") //Debug
895 // echo $this->level.str_repeat(" ",$this->level*2)."<".$tagName."><br>\n"; //Debug
898 //This is the startTag handler we use where we are reading the questions zone (todo="QUESTIONS")
899 function startElementQuestions($parser, $tagName, $attrs) {
902 $this->tree
[$this->level
] = $tagName;
904 //if ($tagName == "QUESTION_CATEGORY" && $this->tree[3] == "QUESTION_CATEGORIES") { //Debug
905 // echo "<P>QUESTION_CATEGORY: ".strftime ("%X",time()),"-"; //Debug
908 //Output something to avoid browser timeouts...
911 //Check if we are into QUESTION_CATEGORIES zone
912 //if ($this->tree[3] == "QUESTION_CATEGORIES") //Debug
913 // echo $this->level.str_repeat(" ",$this->level*2)."<".$tagName."><br>\n"; //Debug
915 //If we are under a QUESTION_CATEGORY tag under a QUESTION_CATEGORIES zone, accumule it
916 if (($this->tree
[4] == "QUESTION_CATEGORY") and ($this->tree
[3] == "QUESTION_CATEGORIES")) {
917 $this->temp
.= "<".$tagName.">";
921 //This is the startTag handler we use where we are reading the modules zone (todo="MODULES")
922 function startElementModules($parser, $tagName, $attrs) {
925 $this->tree
[$this->level
] = $tagName;
927 //if ($tagName == "MOD" && $this->tree[3] == "MODULES") { //Debug
928 // echo "<P>MOD: ".strftime ("%X",time()),"-"; //Debug
931 //Output something to avoid browser timeouts...
934 //Check if we are into MODULES zone
935 //if ($this->tree[3] == "MODULES") //Debug
936 // echo $this->level.str_repeat(" ",$this->level*2)."<".$tagName."><br>\n"; //Debug
938 //If we are under a MOD tag under a MODULES zone, accumule it
939 if (($this->tree
[4] == "MOD") and ($this->tree
[3] == "MODULES")) {
940 $this->temp
.= "<".$tagName.">";
944 //This is the startTag default handler we use when todo is undefined
945 function startElement($parser, $tagName, $attrs) {
947 $this->tree
[$this->level
] = $tagName;
949 //Output something to avoid browser timeouts...
952 echo $this->level
.str_repeat(" ",$this->level
*2)."<".$tagName."><br>\n"; //Debug
955 //This is the endTag handler we use where we are reading the info zone (todo="INFO")
956 function endElementInfo($parser, $tagName) {
957 //Check if we are into INFO zone
958 if ($this->tree
[2] == "INFO") {
959 //if (trim($this->content)) //Debug
960 // echo "C".str_repeat(" ",($this->level+2)*2).$this->getContents()."<br>\n"; //Debug
961 //echo $this->level.str_repeat(" ",$this->level*2)."</".$tagName."><br>\n"; //Debug
962 //Dependig of different combinations, do different things
963 if ($this->level
== 3) {
966 $this->info
->backup_name
= $this->getContents();
968 case "MOODLE_VERSION":
969 $this->info
->backup_moodle_version
= $this->getContents();
971 case "MOODLE_RELEASE":
972 $this->info
->backup_moodle_release
= $this->getContents();
974 case "BACKUP_VERSION":
975 $this->info
->backup_backup_version
= $this->getContents();
977 case "BACKUP_RELEASE":
978 $this->info
->backup_backup_release
= $this->getContents();
981 $this->info
->backup_date
= $this->getContents();
985 if ($this->tree
[3] == "DETAILS") {
986 if ($this->level
== 4) {
989 $this->info
->backup_users
= $this->getContents();
992 $this->info
->backup_logs
= $this->getContents();
995 $this->info
->backup_user_files
= $this->getContents();
998 $this->info
->backup_course_files
= $this->getContents();
1002 if ($this->level
== 5) {
1005 $this->info
->tempName
= $this->getContents();
1008 $this->info
->mods
[$this->info
->tempName
]->backup
= $this->getContents();
1011 $this->info
->mods
[$this->info
->tempName
]->userinfo
= $this->getContents();
1020 $this->tree
[$this->level
] = "";
1022 $this->content
= "";
1024 //Stop parsing if todo = INFO and tagName = INFO (en of the tag, of course)
1025 //Speed up a lot (avoid parse all)
1026 if ($tagName == "INFO") {
1027 $this->finished
= true;
1031 //This is the endTag handler we use where we are reading the course_header zone (todo="COURSE_HEADER")
1032 function endElementCourseHeader($parser, $tagName) {
1033 //Check if we are into COURSE_HEADER zone
1034 if ($this->tree
[3] == "HEADER") {
1035 //if (trim($this->content)) //Debug
1036 // echo "C".str_repeat(" ",($this->level+2)*2).$this->getContents()."<br>\n"; //Debug
1037 //echo $this->level.str_repeat(" ",$this->level*2)."</".$tagName."><br>\n"; //Debug
1038 //Dependig of different combinations, do different things
1039 if ($this->level
== 4) {
1042 $this->info
->course_id
= $this->getContents();
1045 $this->info
->course_password
= $this->getContents();
1048 $this->info
->course_fullname
= $this->getContents();
1051 $this->info
->course_shortname
= $this->getContents();
1054 $this->info
->course_summary
= $this->getContents();
1057 $this->info
->course_format
= $this->getContents();
1060 $this->info
->course_newsitems
= $this->getContents();
1063 $this->info
->course_teacher
= $this->getContents();
1066 $this->info
->course_teachers
= $this->getContents();
1069 $this->info
->course_student
= $this->getContents();
1072 $this->info
->course_students
= $this->getContents();
1075 $this->info
->course_guest
= $this->getContents();
1078 $this->info
->course_stardate
= $this->getContents();
1081 $this->info
->course_numsections
= $this->getContents();
1084 $this->info
->course_showrecent
= $this->getContents();
1087 $this->info
->course_marker
= $this->getContents();
1090 $this->info
->course_visible
= $this->getContents();
1093 $this->info
->course_timecreated
= $this->getContents();
1095 case "TIMEMODIFIED":
1096 $this->info
->course_timemodified
= $this->getContents();
1100 if ($this->tree
[4] == "CATEGORY") {
1101 if ($this->level
== 5) {
1104 $this->info
->category
->id
= $this->getContents();
1107 $this->info
->category
->name
= $this->getContents();
1115 $this->tree
[$this->level
] = "";
1117 $this->content
= "";
1119 //Stop parsing if todo = COURSE_HEADER and tagName = HEADER (en of the tag, of course)
1120 //Speed up a lot (avoid parse all)
1121 if ($tagName == "HEADER") {
1122 $this->finished
= true;
1126 //This is the endTag handler we use where we are reading the sections zone (todo="SECTIONS")
1127 function endElementSections($parser, $tagName) {
1128 //Check if we are into SECTIONS zone
1129 if ($this->tree
[3] == "SECTIONS") {
1130 //if (trim($this->content)) //Debug
1131 // echo "C".str_repeat(" ",($this->level+2)*2).$this->getContents()."<br>\n"; //Debug
1132 //echo $this->level.str_repeat(" ",$this->level*2)."</".$tagName."><br>\n"; //Debug
1133 //Dependig of different combinations, do different things
1134 if ($this->level
== 4) {
1137 //We've finalized a section, get it
1138 $this->info
->sections
[$this->info
->tempsection
->id
]->number
= $this->info
->tempsection
->number
;
1139 $this->info
->sections
[$this->info
->tempsection
->id
]->summary
= $this->info
->tempsection
->summary
;
1140 $this->info
->sections
[$this->info
->tempsection
->id
]->visible
= $this->info
->tempsection
->visible
;
1141 $this->info
->sections
[$this->info
->tempsection
->id
]->mods
= $this->info
->tempsection
->mods
;
1142 unset($this->info
->tempsection
);
1145 if ($this->level
== 5) {
1148 $this->info
->tempsection
->id
= $this->getContents();
1151 $this->info
->tempsection
->number
= $this->getContents();
1154 $this->info
->tempsection
->summary
= $this->getContents();
1157 $this->info
->tempsection
->visible
= $this->getContents();
1161 if ($this->level
== 6) {
1164 //We've finalized a mod, get it
1165 $this->info
->tempsection
->mods
[$this->info
->tempmod
->id
]->type
=
1166 $this->info
->tempmod
->type
;
1167 $this->info
->tempsection
->mods
[$this->info
->tempmod
->id
]->instance
=
1168 $this->info
->tempmod
->instance
;
1169 $this->info
->tempsection
->mods
[$this->info
->tempmod
->id
]->added
=
1170 $this->info
->tempmod
->added
;
1171 $this->info
->tempsection
->mods
[$this->info
->tempmod
->id
]->deleted
=
1172 $this->info
->tempmod
->deleted
;
1173 $this->info
->tempsection
->mods
[$this->info
->tempmod
->id
]->score
=
1174 $this->info
->tempmod
->score
;
1175 $this->info
->tempsection
->mods
[$this->info
->tempmod
->id
]->visible
=
1176 $this->info
->tempmod
->visible
;
1177 unset($this->info
->tempmod
);
1180 if ($this->level
== 7) {
1183 $this->info
->tempmod
->id
= $this->getContents();
1186 $this->info
->tempmod
->type
= $this->getContents();
1189 $this->info
->tempmod
->instance
= $this->getContents();
1192 $this->info
->tempmod
->added
= $this->getContents();
1195 $this->info
->tempmod
->deleted
= $this->getContents();
1198 $this->info
->tempmod
->score
= $this->getContents();
1201 $this->info
->tempmod
->visible
= $this->getContents();
1207 $this->tree
[$this->level
] = "";
1209 $this->content
= "";
1211 //Stop parsing if todo = SECTIONS and tagName = SECTIONS (en of the tag, of course)
1212 //Speed up a lot (avoid parse all)
1213 if ($tagName == "SECTIONS") {
1214 $this->finished
= true;
1218 //This is the endTag handler we use where we are reading the users zone (todo="USERS")
1219 function endElementUsers($parser, $tagName) {
1220 //Check if we are into USERS zone
1221 if ($this->tree
[3] == "USERS") {
1222 //if (trim($this->content)) //Debug
1223 // echo "C".str_repeat(" ",($this->level+2)*2).$this->getContents()."<br>\n"; //Debug
1224 //echo $this->level.str_repeat(" ",$this->level*2)."</".$tagName."><br>\n"; //Debug
1225 //Dependig of different combinations, do different things
1226 if ($this->level
== 4) {
1232 backup_putid($this->preferences
->backup_unique_code
,"user",$this->info
->tempuser
->id
,
1233 null,$this->info
->tempuser
);
1236 if ($this->counter %
10 == 0) {
1238 if ($this->counter %
200 == 0) {
1244 //Delete temp obejct
1245 unset($this->info
->tempuser
);
1249 if ($this->level
== 5) {
1252 $this->info
->users
[$this->getContents()] = $this->getContents();
1253 $this->info
->tempuser
->id
= $this->getContents();
1256 $this->info
->tempuser
->confirmed
= $this->getContents();
1259 $this->info
->tempuser
->deleted
= $this->getContents();
1262 $this->info
->tempuser
->username
= $this->getContents();
1265 $this->info
->tempuser
->password
= $this->getContents();
1268 $this->info
->tempuser
->idnumber
= $this->getContents();
1271 $this->info
->tempuser
->firstname
= $this->getContents();
1274 $this->info
->tempuser
->lastname
= $this->getContents();
1277 $this->info
->tempuser
->email
= $this->getContents();
1280 $this->info
->tempuser
->icq
= $this->getContents();
1283 $this->info
->tempuser
->phone1
= $this->getContents();
1286 $this->info
->tempuser
->phone2
= $this->getContents();
1289 $this->info
->tempuser
->institution
= $this->getContents();
1292 $this->info
->tempuser
->department
= $this->getContents();
1295 $this->info
->tempuser
->address
= $this->getContents();
1298 $this->info
->tempuser
->city
= $this->getContents();
1301 $this->info
->tempuser
->country
= $this->getContents();
1304 $this->info
->tempuser
->lang
= $this->getContents();
1307 $this->info
->tempuser
->timezone
= $this->getContents();
1310 $this->info
->tempuser
->firstaccess
= $this->getContents();
1313 $this->info
->tempuser
->lastaccess
= $this->getContents();
1316 $this->info
->tempuser
->lastlogin
= $this->getContents();
1318 case "CURRENTLOGIN":
1319 $this->info
->tempuser
->currentlogin
= $this->getContents();
1322 $this->info
->tempuser
->lastip
= $this->getContents();
1325 $this->info
->tempuser
->secret
= $this->getContents();
1328 $this->info
->tempuser
->picture
= $this->getContents();
1331 $this->info
->tempuser
->url
= $this->getContents();
1334 $this->info
->tempuser
->description
= $this->getContents();
1337 $this->info
->tempuser
->mailformat
= $this->getContents();
1340 $this->info
->tempuser
->maildisplay
= $this->getContents();
1343 $this->info
->tempuser
->htmleditor
= $this->getContents();
1345 case "AUTOSUBSCRIBE":
1346 $this->info
->tempuser
->autosubscribe
= $this->getContents();
1348 case "TIMEMODIFIED":
1349 $this->info
->tempuser
->timemodified
= $this->getContents();
1353 if ($this->level
== 6) {
1356 //We've finalized a role, get it
1357 $this->info
->tempuser
->roles
[$this->info
->temprole
->type
]->authority
=
1358 $this->info
->temprole
->authority
;
1359 $this->info
->tempuser
->roles
[$this->info
->temprole
->type
]->tea_role
=
1360 $this->info
->temprole
->tea_role
;
1361 $this->info
->tempuser
->roles
[$this->info
->temprole
->type
]->timestart
=
1362 $this->info
->temprole
->timestart
;
1363 $this->info
->tempuser
->roles
[$this->info
->temprole
->type
]->timeend
=
1364 $this->info
->temprole
->timeend
;
1365 $this->info
->tempuser
->roles
[$this->info
->temprole
->type
]->time
=
1366 $this->info
->temprole
->time
;
1367 unset($this->info
->temprole
);
1371 if ($this->level
== 7) {
1374 $this->info
->temprole
->type
= $this->getContents();
1377 $this->info
->temprole
->authority
= $this->getContents();
1380 $this->info
->temprole
->tea_role
= $this->getContents();
1383 $this->info
->temprole
->timestart
= $this->getContents();
1386 $this->info
->temprole
->timeend
= $this->getContents();
1389 $this->info
->temprole
->time
= $this->getContents();
1395 //Stop parsing if todo = USERS and tagName = USERS (en of the tag, of course)
1396 //Speed up a lot (avoid parse all)
1397 if ($tagName == "USERS" and $this->level
== 3) {
1398 $this->finished
= true;
1403 $this->tree
[$this->level
] = "";
1405 $this->content
= "";
1408 //This is the endTag handler we use where we are reading the modules zone (todo="QUESTIONS")
1409 function endElementQuestions($parser, $tagName) {
1410 //Check if we are into QUESTION_CATEGORIES zone
1411 if ($this->tree
[3] == "QUESTION_CATEGORIES") {
1412 //if (trim($this->content)) //Debug
1413 // echo "C".str_repeat(" ",($this->level+2)*2).$this->getContents()."<br>\n"; //Debug
1414 //echo $this->level.str_repeat(" ",$this->level*2)."</".$tagName."><br>\n"; //Debug
1415 //Acumulate data to info (content + close tag)
1416 //Reconvert: strip htmlchars again and trim to generate xml data
1417 $this->temp
.= htmlspecialchars(trim($this->content
))."</".$tagName.">";
1418 //If we've finished a mod, xmlize it an save to db
1419 if (($this->level
== 4) and ($tagName == "QUESTION_CATEGORY")) {
1420 //Prepend XML standard header to info gathered
1421 $xml_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".$this->temp
;
1422 //Call to xmlize for this portion of xml data (one MOD)
1423 //echo "-XMLIZE: ".strftime ("%X",time()),"-"; //Debug
1424 $data = xmlize($xml_data,0);
1425 //echo strftime ("%X",time())."<p>"; //Debug
1426 //traverse_xmlize($data); //Debug
1427 //print_object ($GLOBALS['traverse_array']); //Debug
1428 //$GLOBALS['traverse_array']=""; //Debug
1429 //Now, save data to db. We'll use it later
1430 //Get id and modtype from data
1431 $category_id = $data["QUESTION_CATEGORY"]["#"]["ID"]["0"]["#"];
1433 $status = backup_putid($this->preferences
->backup_unique_code
,"quiz_categories",$category_id,
1435 //Create returning info
1436 $ret_info->id
= $category_id;
1437 $this->info
[] = $ret_info;
1443 //Stop parsing if todo = QUESTION_CATEGORIES and tagName = QUESTION_CATEGORY (en of the tag, of course)
1444 //Speed up a lot (avoid parse all)
1445 if ($tagName == "QUESTION_CATEGORIES" and $this->level
== 3) {
1446 $this->finished
= true;
1450 $this->tree
[$this->level
] = "";
1452 $this->content
= "";
1455 //This is the endTag handler we use where we are reading the modules zone (todo="MODULES")
1456 function endElementModules($parser, $tagName) {
1457 //Check if we are into MODULES zone
1458 if ($this->tree
[3] == "MODULES") {
1459 //if (trim($this->content)) //Debug
1460 // echo "C".str_repeat(" ",($this->level+2)*2).$this->getContents()."<br>\n"; //Debug
1461 //echo $this->level.str_repeat(" ",$this->level*2)."</".$tagName."><br>\n"; //Debug
1462 //Acumulate data to info (content + close tag)
1463 //Reconvert: strip htmlchars again and trim to generate xml data
1464 $this->temp
.= htmlspecialchars(trim($this->content
))."</".$tagName.">";
1465 //If we've finished a mod, xmlize it an save to db
1466 if (($this->level
== 4) and ($tagName == "MOD")) {
1467 //Prepend XML standard header to info gathered
1468 $xml_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".$this->temp
;
1469 //Call to xmlize for this portion of xml data (one MOD)
1470 //echo "-XMLIZE: ".strftime ("%X",time()),"-"; //Debug
1471 $data = xmlize($xml_data,0);
1472 //echo strftime ("%X",time())."<p>"; //Debug
1473 //traverse_xmlize($data); //Debug
1474 //print_object ($GLOBALS['traverse_array']); //Debug
1475 //$GLOBALS['traverse_array']=""; //Debug
1476 //Now, save data to db. We'll use it later
1477 //Get id and modtype from data
1478 $mod_id = $data["MOD"]["#"]["ID"]["0"]["#"];
1479 $mod_type = $data["MOD"]["#"]["MODTYPE"]["0"]["#"];
1480 //Only if we've selected to restore it
1481 if ($this->preferences
->mods
[$mod_type]->restore
) {
1483 $status = backup_putid($this->preferences
->backup_unique_code
,$mod_type,$mod_id,
1485 //echo "<p>id: ".$mod_id."-".$mod_type." len.: ".strlen($sla_mod_temp)." to_db: ".$status."<p>"; //Debug
1486 //Create returning info
1487 $ret_info->id
= $mod_id;
1488 $ret_info->modtype
= $mod_type;
1489 $this->info
[] = $ret_info;
1496 //Stop parsing if todo = MODULES and tagName = MODULES (en of the tag, of course)
1497 //Speed up a lot (avoid parse all)
1498 if ($tagName == "MODULES" and $this->level
== 3) {
1499 $this->finished
= true;
1503 $this->tree
[$this->level
] = "";
1505 $this->content
= "";
1508 //This is the endTag default handler we use when todo is undefined
1509 function endElement($parser, $tagName) {
1510 if (trim($this->content
)) //Debug
1511 echo "C".str_repeat(" ",($this->level+
2)*2).$this->getContents()."<br>\n"; //Debug
1512 echo $this->level
.str_repeat(" ",$this->level
*2)."</".$tagName."><br>\n"; //Debug
1515 $this->tree
[$this->level
] = "";
1517 $this->content
= "";
1520 //This is the handler to read data contents (simple accumule it)
1521 function characterData($parser, $data) {
1522 $this->content
.= $data;
1526 //This function executes the MoodleParser
1527 function restore_read_xml ($xml_file,$todo,$preferences) {
1531 $xml_parser = xml_parser_create();
1532 $moodle_parser = new MoodleParser();
1533 $moodle_parser->todo
= $todo;
1534 $moodle_parser->preferences
= $preferences;
1535 xml_set_object($xml_parser,&$moodle_parser);
1536 //Depending of the todo we use some element_handler or another
1537 if ($todo == "INFO") {
1538 //Define handlers to that zone
1539 xml_set_element_handler($xml_parser, "startElementInfo", "endElementInfo");
1540 } else if ($todo == "COURSE_HEADER") {
1541 //Define handlers to that zone
1542 xml_set_element_handler($xml_parser, "startElementCourseHeader", "endElementCourseHeader");
1543 } else if ($todo == "SECTIONS") {
1544 //Define handlers to that zone
1545 xml_set_element_handler($xml_parser, "startElementSections", "endElementSections");
1546 } else if ($todo == "USERS") {
1547 //Define handlers to that zone
1548 xml_set_element_handler($xml_parser, "startElementUsers", "endElementUsers");
1549 } else if ($todo == "QUESTIONS") {
1550 //Define handlers to that zone
1551 xml_set_element_handler($xml_parser, "startElementQuestions", "endElementQuestions");
1552 } else if ($todo == "MODULES") {
1553 //Define handlers to that zone
1554 xml_set_element_handler($xml_parser, "startElementModules", "endElementModules");
1556 //Define default handlers (must no be invoked when everything become finished)
1557 xml_set_element_handler($xml_parser, "startElementInfo", "endElementInfo");
1559 xml_set_character_data_handler($xml_parser, "characterData");
1560 $fp = fopen($xml_file,"r")
1563 while ($data = fread($fp, 4096) and !$moodle_parser->finished
)
1564 xml_parse($xml_parser, $data, feof($fp))
1565 or die(sprintf("XML error: %s at line %d",
1566 xml_error_string(xml_get_error_code($xml_parser)),
1567 xml_get_current_line_number($xml_parser)));
1570 //Get info from parser
1571 $info = $moodle_parser->info
;
1574 xml_parser_free($xml_parser);
1576 if ($status && $info) {