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 modules in
89 function restore_read_xml_modules ($restore,$xml_file) {
91 //We call the main read_xml function, with todo = MODULES
92 $info = restore_read_xml ($xml_file,"MODULES",$restore);
97 //This function prints the contents from the info parammeter passed
98 function restore_print_info ($info) {
102 //This is tha align to every ingo table
103 $table->align
= array ("RIGHT","LEFT");
104 //This is the nowrap clause
105 $table->wrap
= array ("","NOWRAP");
107 $table->width
= "70%";
108 //Put interesting info in table
109 //The backup original name
110 $tab[0][0] = "<b>".get_string("backuporiginalname").":</b>";
111 $tab[0][1] = $info->backup_name
;
113 $tab[1][0] = "<b>".get_string("moodleversion").":</b>";
114 $tab[1][1] = $info->backup_moodle_release
." (".$info->backup_moodle_version
.")";
116 $tab[2][0] = "<b>".get_string("backupversion").":</b>";
117 $tab[2][1] = $info->backup_backup_release
." (".$info->backup_backup_version
.")";
119 $tab[3][0] = "<b>".get_string("backupdate").":</b>";
120 $tab[3][1] = userdate($info->backup_date
);
122 print_heading(get_string("backup").":");
124 //Print backup general info
126 //Now backup contents in another table
131 foreach ($mods as $key => $mod) {
132 $tab[$elem][0] = "<b>".get_string("modulenameplural",$key).":</b>";
133 if ($mod->backup
== "false") {
134 $tab[$elem][1] = get_string("notincluded");
136 if ($mod->userinfo
== "true") {
137 $tab[$elem][1] = get_string("included")." ".get_string("withuserdata");
139 $tab[$elem][1] = get_string("included")." ".get_string("withoutuserdata");
145 $tab[$elem][0] = "<b>".get_string("users").":</b>";
146 $tab[$elem][1] = get_string($info->backup_users
);
149 $tab[$elem][0] = "<b>".get_string("logs").":</b>";
150 if ($info->backup_logs
== "true") {
151 $tab[$elem][1] = get_string("yes");
153 $tab[$elem][1] = get_string("no");
157 $tab[$elem][0] = "<b>".get_string("userfiles").":</b>";
158 if ($info->backup_user_files
== "true") {
159 $tab[$elem][1] = get_string("yes");
161 $tab[$elem][1] = get_string("no");
165 $tab[$elem][0] = "<b>".get_string("coursefiles").":</b>";
166 if ($info->backup_course_files
== "true") {
167 $tab[$elem][1] = get_string("yes");
169 $tab[$elem][1] = get_string("no");
174 print_heading(get_string("backupdetails").":");
175 //Print backup general info
184 //This function prints the contents from the course_header parammeter passed
185 function restore_print_course_header ($course_header) {
188 if ($course_header) {
189 //This is tha align to every ingo table
190 $table->align
= array ("RIGHT","LEFT");
192 $table->width
= "70%";
193 //Put interesting course header in table
195 $tab[0][0] = "<b>".get_string("name").":</b>";
196 $tab[0][1] = $course_header->course_fullname
." (".$course_header->course_shortname
.")";
198 $tab[1][0] = "<b>".get_string("summary").":</b>";
199 $tab[1][1] = $course_header->course_summary
;
202 print_heading(get_string("course").":");
203 //Print backup course header info
211 //This function create a new course record.
212 //When finished, course_header contains the id of the new course
213 function restore_create_new_course($restore,&$course_header) {
219 $fullname = $course_header->course_fullname
;
220 $shortname = $course_header->course_shortname
;
221 $currentfullname = "";
222 $currentshortname = "";
224 //Iteratere while the name exists
227 $suffixfull = " ".get_string("copy")." ".$counter;
228 $suffixshort = "-".$counter;
233 $currentfullname = $fullname.$suffixfull;
234 $currentshortname = $shortname.$suffixshort;
235 $course = get_record("course","fullname",addslashes($currentfullname));
239 //New name = currentname
240 $course_header->course_fullname
= $currentfullname;
241 $course_header->course_shortname
= $currentshortname;
243 //Now calculate the category
244 $category = get_record("course_categories","id",$course_header->category
->id
,
245 "name",addslashes($course_header->category
->name
));
246 //If no exists, try by name only
248 $category = get_record("course_categories","name",addslashes($course_header->category
->name
));
250 //If no exists, get category id 1
252 $category = get_record("course_categories","id","1");
254 //If exists, put new category id
256 $course_header->category
->id
= $category->id
;
257 $course_header->category
->name
= $category->name
;
258 //Error, cannot locate category
260 $course_header->category
->id
= 0;
261 $course_header->category
->name
= getstring("unknowcategory");
265 //Create the course_object
267 $course->category
= addslashes($course_header->category
->id
);
268 $course->password
= addslashes($course_header->course_password
);
269 $course->fullname
= addslashes($course_header->course_fullname
);
270 $course->shortname
= addslashes($course_header->course_shortname
);
271 $course->summary
= addslashes($course_header->course_summary
);
272 $course->format
= addslashes($course_header->course_format
);
273 $course->newsitems
= addslashes($course_header->course_newsitems
);
274 $course->teacher
= addslashes($course_header->course_teacher
);
275 $course->teachers
= addslashes($course_header->course_teachers
);
276 $course->student
= addslashes($course_header->course_student
);
277 $course->students
= addslashes($course_header->course_students
);
278 $course->guest
= addslashes($course_header->course_guest
);
279 $course->startdate
= addslashes($course_header->course_startdate
);
280 $course->numsections
= addslashes($course_header->course_numsections
);
281 $course->showrecent
= addslashes($course_header->course_showrecent
);
282 $course->marker
= addslashes($course_header->course_marker
);
283 $course->timecreated
= addslashes($course_header->course_timecreated
);
284 $course->timemodified
= addslashes($course_header->course_timemodified
);
285 //Now insert the record
286 $newid = insert_record("course",$course);
288 //save old and new course id
289 backup_putid ($restore->backup_unique_code
,"course",$course_header->course_id
,$newid);
290 //Replace old course_id in course_header
291 $course_header->course_id
= $newid;
300 //This function creates all the course_sections and course_modules from xml
301 //when restoring in a new course or simply checks sections and create records
302 //in backup_ids when restoring in a existing course
303 function restore_create_sections($restore,$xml_file) {
309 if (!file_exists($xml_file)) {
314 $info = restore_read_xml_sections($xml_file);
316 //Put the info in the DB, recoding ids and saving the in backup tables
321 //For each, section, save it to db
322 foreach ($info->sections
as $key => $sect) {
324 $section->course
= $restore->course_id
;
325 $section->section
= $sect->number
;
326 $section->summary
= $sect->summary
;
327 $section->visible
= $sect->visible
;
328 $section->sequence
= "";
329 //Now calculate the section's newid
331 if ($restore->restoreto
== 1) {
332 //Save it to db (only if restoring to new course)
333 $newid = insert_record("course_sections",$section);
335 //Get section id when restoring in existing course
336 $rec = get_record("course_sections","course",$restore->course_id
,
337 "section",$section->section
);
338 //If that section doesn't exist, get section 0 (every mod will be
341 $rec = get_record("course_sections","course",$restore->course_id
,
345 $sequence = $rec->sequence
;
348 //save old and new section id
349 backup_putid ($restore->backup_unique_code
,"course_sections",$key,$newid);
353 //If all is OK, go with associated mods
355 //If we have mods in the section
357 //For each mod inside section
358 foreach ($sect->mods
as $keym => $mod) {
359 //Check if we've to restore this module
360 if ($restore->mods
[$mod->type
]->restore
) {
361 //Get the module id from modules
362 $module = get_record("modules","name",$mod->type
);
364 $course_module->course
= $restore->course_id
;
365 $course_module->module
= $module->id
;
366 $course_module->section
= $newid;
367 $course_module->added
= $mod->added
;
368 $course_module->deleted
= $mod->deleted
;
369 $course_module->score
= $mod->score
;
370 $course_module->visible
= $mod->visible
;
371 $course_module->instance
= null;
372 //NOTE: The instance (new) is calculated and updated in db in the
373 // final step of the restore. We don't know it yet.
374 //print_object($course_module); //Debug
376 $newidmod = insert_record("course_modules",$course_module);
378 //save old and new module id
379 //In the info field, we save the original instance of the module
381 backup_putid ($restore->backup_unique_code
,"course_modules",
382 $keym,$newidmod,$mod->instance
);
386 //Now, calculate the sequence field
389 $sequence .= ",".$newidmod;
391 $sequence = $newidmod;
401 //If all is OK, update sequence field in course_sections
404 $rec->sequence
= $sequence;
405 $status = update_record("course_sections",$rec);
414 //This function creates all the user, user_students, user_teachers
415 //user_course_creators and user_admins from xml
416 function restore_create_users($restore,$xml_file) {
422 if (!file_exists($xml_file)) {
427 //info will contain the old_id of every user
428 //in backup_ids->info will be the real info (serialized)
429 $info = restore_read_xml_users($restore,$xml_file);
432 //Now, get evey user_id from $info and user data from $backup_ids
433 //and create the necessary records (users, user_students, user_teachers
434 //user_course_creators and user_admins
436 //For each, user, take its info from backup_ids
437 foreach ($info->users
as $userid) {
438 $rec = backup_getid($restore->backup_unique_code
,"user",$userid);
439 //First strip slashes
440 $temp = stripslashes($rec->info
);
442 $user = unserialize($temp);
443 //Calculate if it is a course user
444 //Has role teacher or student or admin or coursecreator
445 $is_course_user = ($user->roles
[teacher
] or $user->roles
[student
] or
446 $user->roles
[admin
] or $user->roles
[coursecreator
]);
447 //Check if it's admin and coursecreator
448 $is_admin = ($user->roles
[admin
]);
449 $is_coursecreator = ($user->roles
[coursecreator
]);
450 //Check if it's teacher and student
451 $is_teacher = ($user->roles
[teacher
]);
452 $is_student = ($user->roles
[student
]);
453 //To store new ids created
455 //check if it exists (by username) and get its id
457 $user_data = get_record("user","username",$user->username
);
459 $user_exists = false;
461 $newid = $user_data->id
;
463 //Flags to see if we have to create the user and roles
465 $create_roles = true;
467 //If we are restoring course users and it isn't a course user
468 if ($restore->users
== 1 and !$is_course_user) {
469 //If only restoring course_users and user isn't a course_user, inform to $backup_ids
470 $status = backup_putid($restore->backup_unique_code
,"user",$userid,null,'notincourse');
471 $create_user = false;
472 $create_roles = false;
475 if ($user_exists and $create_user) {
476 //If user exists mark its newid in backup_ids (the same than old)
477 $status = backup_putid($restore->backup_unique_code
,"user",$userid,$newid,'exists');
478 $create_user = false;
481 //Here, if create_user, do it
483 //We are going to create the user
484 //The structure is exactly as we need
485 $newid = insert_record ("user",$user);
487 $status = backup_putid($restore->backup_unique_code
,"user",$userid,$newid,"new");
490 //Here, if create_roles, do it as necessary
492 //Get the newid and currecnt info from backup_ids
493 $data = backup_getid($restore->backup_unique_code
,"user",$userid);
494 $newid = $data->new_id
;
495 $currinfo = $data->info
.",";
496 //Now, depending of the role, create records in user_studentes and user_teacher
497 //and/or mark it in backup_ids
499 //If the record (user_admins) doesn't exists
500 if (!record_exists("user_admins","userid",$newid)) {
501 //Only put status in backup_ids
502 $currinfo = $currinfo."admin,";
503 $status = backup_putid($restore->backup_unique_code
,"user",$userid,$newid,$currinfo);
506 if ($is_coursecreator) {
507 //If the record (user_coursecreators) doesn't exists
508 if (!record_exists("user_coursecreators","userid",$newid)) {
509 //Only put status in backup_ids
510 $currinfo = $currinfo."coursecreator,";
511 $status = backup_putid($restore->backup_unique_code
,"user",$userid,$newid,$currinfo);
515 //If the record (teacher) doesn't exists
516 if (!record_exists("user_teachers","userid",$newid,"course", $restore->course_id
)) {
517 //Put status in backup_ids
518 $currinfo = $currinfo."teacher,";
519 $status = backup_putid($restore->backup_unique_code
,"user",$userid,$newid,$currinfo);
520 //Set course and user
521 $user->roles
[teacher
]->course
= $restore->course_id
;
522 $user->roles
[teacher
]->userid
= $newid;
523 //Insert data in user_teachers
524 //The structure is exactly as we need
525 $status = insert_record("user_teachers",$user->roles
[teacher
]);
529 //If the record (student) doesn't exists
530 if (!record_exists("user_students","userid",$newid,"course", $restore->course_id
)) {
531 //Put status in backup_ids
532 $currinfo = $currinfo."student,";
533 $status = backup_putid($restore->backup_unique_code
,"user",$userid,$newid,$currinfo);
534 //Set course and user
535 $user->roles
[student
]->course
= $restore->course_id
;
536 $user->roles
[student
]->userid
= $newid;
537 //Insert data in user_students
538 //The structure is exactly as we need
539 $status = insert_record("user_students",$user->roles
[student
]);
542 if (!$is_course_user) {
543 //If the record (user) doesn't exists
544 if (!record_exists("user","id",$newid)) {
545 //Put status in backup_ids
546 $currinfo = $currinfo."user,";
547 $status = backup_putid($restore->backup_unique_code
,"user",$userid,$newid,$currinfo);
559 //This function restores the userfiles from the temp (user_files) directory to the
560 //dataroot/users directory
561 function restore_user_files($restore) {
567 //First, we check to "users" exists and create is as necessary
569 $dest_dir = $CFG->dataroot
."/users";
570 $status = check_dir_exists($dest_dir,true);
572 //Now, we iterate over "user_files" records to check if that user dir must be
573 //copied (and renamed) to the "users" dir.
574 $rootdir = $CFG->dataroot
."/temp/backup/".$restore->backup_unique_code
."/user_files";
575 //Check if directory exists
576 if (is_dir($rootdir)) {
577 $list = list_directories ($rootdir);
581 foreach ($list as $dir) {
582 //Look for dir like username in backup_ids
583 $data = get_record ("backup_ids","backup_code",$restore->backup_unique_code
,
586 //If thar user exists in backup_ids
588 //Only it user has been created now
589 if (strpos($data->info
,"new") !== false) {
590 //Copy the old_dir to its new location (and name) !!
591 //Only if destination doesn't exists
592 if (!file_exists($dest_dir."/".$data->new_id
)) {
593 $status = backup_copy_file($rootdir."/".$dir,
594 $dest_dir."/".$data->new_id
);
602 //If status is ok and whe have dirs created, returns counter to inform
603 if ($status and $counter) {
610 //This function restores the course files from the temp (course_files) directory to the
611 //dataroot/course_id directory
612 function restore_course_files($restore) {
618 //First, we check to "course_id" exists and create is as necessary
620 $dest_dir = $CFG->dataroot
."/".$restore->course_id
;
621 $status = check_dir_exists($dest_dir,true);
623 //Now, we iterate over "course_files" records to check if that file/dir must be
624 //copied to the "dest_dir" dir.
625 $rootdir = $CFG->dataroot
."/temp/backup/".$restore->backup_unique_code
."/course_files";
626 //Check if directory exists
627 if (is_dir($rootdir)) {
628 $list = list_directories_and_files ($rootdir);
632 foreach ($list as $dir) {
633 //Copy the dir to its new location
634 //Only if destination file/dir doesn exists
635 if (!file_exists($dest_dir."/".$dir)) {
636 $status = backup_copy_file($rootdir."/".$dir,
643 //If status is ok and whe have dirs created, returns counter to inform
644 if ($status and $counter) {
652 //This function creates all the structures for every module in backup file
653 //Depending what has been selected.
654 function restore_create_modules($restore,$xml_file) {
660 if (!file_exists($xml_file)) {
665 //info will contain the id and modtype of every module
666 //in backup_ids->info will be the real info (serialized)
667 $info = restore_read_xml_modules($restore,$xml_file);
670 //Now, if we have anything in info, we have to restore that mods
671 //from backup_ids (calling every mod restore function)
673 //Iterate over each module
674 foreach ($info as $mod) {
675 $modrestore = $mod->modtype
."_restore_mods";
676 if (function_exists($modrestore)) {
677 $status = $modrestore($mod,$restore);
679 //Something was wrong. Function should exist.
689 //This function adjusts the instance field into course_modules. It's executed after
690 //modules restore. There, we KNOW the new instance id !!
691 function restore_check_instances($restore) {
697 //We are going to iterate over each course_module saved in backup_ids
698 $course_modules = get_records_sql("SELECT new_id,info as instance
699 FROM {$CFG->prefix}backup_ids
700 WHERE backup_code = '$restore->backup_unique_code' AND
701 table_name = 'course_modules'");
702 if ($course_modules) {
703 foreach($course_modules as $cm) {
704 //Now we are going to the REAL course_modules to get its type (field module)
705 $module = get_record("course_modules","id",$cm->new_id
);
707 //We know the module type id. Get the name from modules
708 $type = get_record("modules","id",$module->module
);
710 //We know the type name and the old_id. Get its new_id
711 //from backup_ids. It's the instance !!!
712 $instance = get_record("backup_ids","backup_code",$restore->backup_unique_code
,
713 "table_name",$type->name
,
714 "old_id",$cm->instance
);
716 //We have the new instance, so update the record in course_modules
717 $module->instance
= $instance->new_id
;
718 //print_object ($module); //Debug
719 $status = update_record("course_modules",$module);
738 //=====================================================================================
740 //== XML Functions (SAX) ==
742 //=====================================================================================
744 //This is the class used to do all the xml parse
747 var $level = 0; //Level we are
748 var $tree = array(); //Array of levels we are
749 var $content = ""; //Content under current level
750 var $todo = ""; //What we hav to do when parsing
751 var $info = ""; //Information collected. Temp storage. Used to return data after parsing.
752 var $temp = ""; //Temp storage.
753 var $preferences = ""; //Preferences about what to load !!
754 var $finished = false; //Flag to say xml_parse to stop
756 //This function is used to get the current contents property value
757 //They are trimed and converted from utf8
758 function getContents() {
759 return trim(utf8_decode($this->content
));
762 //This is the startTag handler we use where we are reading the info zone (todo="INFO")
763 function startElementInfo($parser, $tagName, $attrs) {
766 $this->tree
[$this->level
] = $tagName;
768 //Check if we are into INFO zone
769 //if ($this->tree[2] == "INFO") //Debug
770 // echo $this->level.str_repeat(" ",$this->level*2)."<".$tagName."><br>\n"; //Debug
773 //This is the startTag handler we use where we are reading the course header zone (todo="COURSE_HEADER")
774 function startElementCourseHeader($parser, $tagName, $attrs) {
777 $this->tree
[$this->level
] = $tagName;
779 //Check if we are into COURSE_HEADER zone
780 //if ($this->tree[3] == "HEADER") //Debug
781 // echo $this->level.str_repeat(" ",$this->level*2)."<".$tagName."><br>\n"; //Debug
784 //This is the startTag handler we use where we are reading the sections zone (todo="SECTIONS")
785 function startElementSections($parser, $tagName, $attrs) {
788 $this->tree
[$this->level
] = $tagName;
790 //Check if we are into SECTIONS zone
791 //if ($this->tree[3] == "SECTIONS") //Debug
792 // echo $this->level.str_repeat(" ",$this->level*2)."<".$tagName."><br>\n"; //Debug
795 //This is the startTag handler we use where we are reading the user zone (todo="USERS")
796 function startElementUsers($parser, $tagName, $attrs) {
799 $this->tree
[$this->level
] = $tagName;
800 //Check if we are into USERS zone
801 //if ($this->tree[3] == "USERS") //Debug
802 // echo $this->level.str_repeat(" ",$this->level*2)."<".$tagName."><br>\n"; //Debug
805 //This is the startTag handler we use where we are reading the modules zone (todo="MODULES")
806 function startElementModules($parser, $tagName, $attrs) {
809 $this->tree
[$this->level
] = $tagName;
810 //Check if we are into MODULES zone
811 //if ($this->tree[3] == "MODULES") //Debug
812 // echo $this->level.str_repeat(" ",$this->level*2)."<".$tagName."><br>\n"; //Debug
813 //If we are under a MOD tag under a MODULES zone, accumule it
814 if (($this->tree
[4] == "MOD") and ($this->tree
[3] == "MODULES")) {
815 $this->temp
.= "<".$tagName.">";
819 //This is the startTag default handler we use when todo is undefined
820 function startElement($parser, $tagName, $attrs) {
822 $this->tree
[$this->level
] = $tagName;
823 echo $this->level
.str_repeat(" ",$this->level
*2)."<".$tagName."><br>\n"; //Debug
826 //This is the endTag handler we use where we are reading the info zone (todo="INFO")
827 function endElementInfo($parser, $tagName) {
828 //Check if we are into INFO zone
829 if ($this->tree
[2] == "INFO") {
830 //if (trim($this->content)) //Debug
831 // echo "C".str_repeat(" ",($this->level+2)*2).$this->getContents()."<br>\n"; //Debug
832 //echo $this->level.str_repeat(" ",$this->level*2)."</".$tagName."><br>\n"; //Debug
833 //Dependig of different combinations, do different things
834 if ($this->level
== 3) {
837 $this->info
->backup_name
= $this->getContents();
839 case "MOODLE_VERSION":
840 $this->info
->backup_moodle_version
= $this->getContents();
842 case "MOODLE_RELEASE":
843 $this->info
->backup_moodle_release
= $this->getContents();
845 case "BACKUP_VERSION":
846 $this->info
->backup_backup_version
= $this->getContents();
848 case "BACKUP_RELEASE":
849 $this->info
->backup_backup_release
= $this->getContents();
852 $this->info
->backup_date
= $this->getContents();
856 if ($this->tree
[3] == "DETAILS") {
857 if ($this->level
== 4) {
860 $this->info
->backup_users
= $this->getContents();
863 $this->info
->backup_logs
= $this->getContents();
866 $this->info
->backup_user_files
= $this->getContents();
869 $this->info
->backup_course_files
= $this->getContents();
873 if ($this->level
== 5) {
876 $this->info
->tempName
= $this->getContents();
879 $this->info
->mods
[$this->info
->tempName
]->backup
= $this->getContents();
882 $this->info
->mods
[$this->info
->tempName
]->userinfo
= $this->getContents();
891 $this->tree
[$this->level
] = "";
895 //Stop parsing if todo = INFO and tagName = INFO (en of the tag, of course)
896 //Speed up a lot (avoid parse all)
897 if ($tagName == "INFO") {
898 $this->finished
= true;
902 //This is the endTag handler we use where we are reading the course_header zone (todo="COURSE_HEADER")
903 function endElementCourseHeader($parser, $tagName) {
904 //Check if we are into COURSE_HEADER zone
905 if ($this->tree
[3] == "HEADER") {
906 //if (trim($this->content)) //Debug
907 // echo "C".str_repeat(" ",($this->level+2)*2).$this->getContents()."<br>\n"; //Debug
908 //echo $this->level.str_repeat(" ",$this->level*2)."</".$tagName."><br>\n"; //Debug
909 //Dependig of different combinations, do different things
910 if ($this->level
== 4) {
913 $this->info
->course_id
= $this->getContents();
916 $this->info
->course_password
= $this->getContents();
919 $this->info
->course_fullname
= $this->getContents();
922 $this->info
->course_shortname
= $this->getContents();
925 $this->info
->course_summary
= $this->getContents();
928 $this->info
->course_format
= $this->getContents();
931 $this->info
->course_newsitems
= $this->getContents();
934 $this->info
->course_teacher
= $this->getContents();
937 $this->info
->course_teachers
= $this->getContents();
940 $this->info
->course_student
= $this->getContents();
943 $this->info
->course_students
= $this->getContents();
946 $this->info
->course_guest
= $this->getContents();
949 $this->info
->course_stardate
= $this->getContents();
952 $this->info
->course_numsections
= $this->getContents();
955 $this->info
->course_showrecent
= $this->getContents();
958 $this->info
->course_marker
= $this->getContents();
961 $this->info
->course_timecreated
= $this->getContents();
964 $this->info
->course_timemodified
= $this->getContents();
968 if ($this->tree
[4] == "CATEGORY") {
969 if ($this->level
== 5) {
972 $this->info
->category
->id
= $this->getContents();
975 $this->info
->category
->name
= $this->getContents();
983 $this->tree
[$this->level
] = "";
987 //Stop parsing if todo = COURSE_HEADER and tagName = HEADER (en of the tag, of course)
988 //Speed up a lot (avoid parse all)
989 if ($tagName == "HEADER") {
990 $this->finished
= true;
994 //This is the endTag handler we use where we are reading the sections zone (todo="SECTIONS")
995 function endElementSections($parser, $tagName) {
996 //Check if we are into SECTIONS zone
997 if ($this->tree
[3] == "SECTIONS") {
998 //if (trim($this->content)) //Debug
999 // echo "C".str_repeat(" ",($this->level+2)*2).$this->getContents()."<br>\n"; //Debug
1000 //echo $this->level.str_repeat(" ",$this->level*2)."</".$tagName."><br>\n"; //Debug
1001 //Dependig of different combinations, do different things
1002 if ($this->level
== 4) {
1005 //We've finalized a section, get it
1006 $this->info
->sections
[$this->info
->tempsection
->id
]->number
= $this->info
->tempsection
->number
;
1007 $this->info
->sections
[$this->info
->tempsection
->id
]->summary
= $this->info
->tempsection
->summary
;
1008 $this->info
->sections
[$this->info
->tempsection
->id
]->visible
= $this->info
->tempsection
->visible
;
1009 $this->info
->sections
[$this->info
->tempsection
->id
]->mods
= $this->info
->tempsection
->mods
;
1010 unset($this->info
->tempsection
);
1013 if ($this->level
== 5) {
1016 $this->info
->tempsection
->id
= $this->getContents();
1019 $this->info
->tempsection
->number
= $this->getContents();
1022 $this->info
->tempsection
->summary
= $this->getContents();
1025 $this->info
->tempsection
->visible
= $this->getContents();
1029 if ($this->level
== 6) {
1032 //We've finalized a mod, get it
1033 $this->info
->tempsection
->mods
[$this->info
->tempmod
->id
]->type
=
1034 $this->info
->tempmod
->type
;
1035 $this->info
->tempsection
->mods
[$this->info
->tempmod
->id
]->instance
=
1036 $this->info
->tempmod
->instance
;
1037 $this->info
->tempsection
->mods
[$this->info
->tempmod
->id
]->added
=
1038 $this->info
->tempmod
->added
;
1039 $this->info
->tempsection
->mods
[$this->info
->tempmod
->id
]->deleted
=
1040 $this->info
->tempmod
->deleted
;
1041 $this->info
->tempsection
->mods
[$this->info
->tempmod
->id
]->score
=
1042 $this->info
->tempmod
->score
;
1043 $this->info
->tempsection
->mods
[$this->info
->tempmod
->id
]->visible
=
1044 $this->info
->tempmod
->visible
;
1045 unset($this->info
->tempmod
);
1048 if ($this->level
== 7) {
1051 $this->info
->tempmod
->id
= $this->getContents();
1054 $this->info
->tempmod
->type
= $this->getContents();
1057 $this->info
->tempmod
->instance
= $this->getContents();
1060 $this->info
->tempmod
->added
= $this->getContents();
1063 $this->info
->tempmod
->deleted
= $this->getContents();
1066 $this->info
->tempmod
->score
= $this->getContents();
1069 $this->info
->tempmod
->visible
= $this->getContents();
1075 $this->tree
[$this->level
] = "";
1077 $this->content
= "";
1079 //Stop parsing if todo = SECTIONS and tagName = SECTIONS (en of the tag, of course)
1080 //Speed up a lot (avoid parse all)
1081 if ($tagName == "SECTIONS") {
1082 $this->finished
= true;
1086 //This is the endTag handler we use where we are reading the users zone (todo="USERS")
1087 function endElementUsers($parser, $tagName) {
1088 //Check if we are into USERS zone
1089 if ($this->tree
[3] == "USERS") {
1090 //if (trim($this->content)) //Debug
1091 // echo "C".str_repeat(" ",($this->level+2)*2).$this->getContents()."<br>\n"; //Debug
1092 //echo $this->level.str_repeat(" ",$this->level*2)."</".$tagName."><br>\n"; //Debug
1093 //Dependig of different combinations, do different things
1094 if ($this->level
== 4) {
1097 //We've finalized a user, get it and save to db
1099 $ser_temp = serialize($this->info
->tempuser
);
1101 $sla_temp = addslashes($ser_temp);
1103 backup_putid($this->preferences
->backup_unique_code
,"user",$this->info
->tempuser
->id
,
1105 //Delete temp obejct
1106 unset($this->info
->tempuser
);
1110 if ($this->level
== 5) {
1113 $this->info
->users
[$this->getContents()] = $this->getContents();
1114 $this->info
->tempuser
->id
= $this->getContents();
1117 $this->info
->tempuser
->confirmed
= $this->getContents();
1120 $this->info
->tempuser
->deleted
= $this->getContents();
1123 $this->info
->tempuser
->username
= $this->getContents();
1126 $this->info
->tempuser
->password
= $this->getContents();
1129 $this->info
->tempuser
->idnumber
= $this->getContents();
1132 $this->info
->tempuser
->firstname
= $this->getContents();
1135 $this->info
->tempuser
->lastname
= $this->getContents();
1138 $this->info
->tempuser
->email
= $this->getContents();
1141 $this->info
->tempuser
->icq
= $this->getContents();
1144 $this->info
->tempuser
->phone1
= $this->getContents();
1147 $this->info
->tempuser
->phone2
= $this->getContents();
1150 $this->info
->tempuser
->institution
= $this->getContents();
1153 $this->info
->tempuser
->department
= $this->getContents();
1156 $this->info
->tempuser
->address
= $this->getContents();
1159 $this->info
->tempuser
->city
= $this->getContents();
1162 $this->info
->tempuser
->country
= $this->getContents();
1165 $this->info
->tempuser
->lang
= $this->getContents();
1168 $this->info
->tempuser
->timezone
= $this->getContents();
1171 $this->info
->tempuser
->firstaccess
= $this->getContents();
1174 $this->info
->tempuser
->lastaccess
= $this->getContents();
1177 $this->info
->tempuser
->lastlogin
= $this->getContents();
1179 case "CURRENTLOGIN":
1180 $this->info
->tempuser
->currentlogin
= $this->getContents();
1183 $this->info
->tempuser
->lastip
= $this->getContents();
1186 $this->info
->tempuser
->secret
= $this->getContents();
1189 $this->info
->tempuser
->picture
= $this->getContents();
1192 $this->info
->tempuser
->url
= $this->getContents();
1195 $this->info
->tempuser
->description
= $this->getContents();
1198 $this->info
->tempuser
->mailformat
= $this->getContents();
1201 $this->info
->tempuser
->maildisplay
= $this->getContents();
1204 $this->info
->tempuser
->htmleditor
= $this->getContents();
1206 case "AUTOSUBSCRIBE":
1207 $this->info
->tempuser
->autosubscribe
= $this->getContents();
1209 case "TIMEMODIFIED":
1210 $this->info
->tempuser
->timemodified
= $this->getContents();
1214 if ($this->level
== 6) {
1217 //We've finalized a role, get it
1218 $this->info
->tempuser
->roles
[$this->info
->temprole
->type
]->authority
=
1219 $this->info
->temprole
->authority
;
1220 $this->info
->tempuser
->roles
[$this->info
->temprole
->type
]->tea_role
=
1221 $this->info
->temprole
->tea_role
;
1222 $this->info
->tempuser
->roles
[$this->info
->temprole
->type
]->timestart
=
1223 $this->info
->temprole
->timestart
;
1224 $this->info
->tempuser
->roles
[$this->info
->temprole
->type
]->timeend
=
1225 $this->info
->temprole
->timeend
;
1226 $this->info
->tempuser
->roles
[$this->info
->temprole
->type
]->time
=
1227 $this->info
->temprole
->time
;
1228 unset($this->info
->temprole
);
1232 if ($this->level
== 7) {
1235 $this->info
->temprole
->type
= $this->getContents();
1238 $this->info
->temprole
->authority
= $this->getContents();
1241 $this->info
->temprole
->tea_role
= $this->getContents();
1244 $this->info
->temprole
->timestart
= $this->getContents();
1247 $this->info
->temprole
->timeend
= $this->getContents();
1250 $this->info
->temprole
->time
= $this->getContents();
1256 //Stop parsing if todo = USERS and tagName = USERS (en of the tag, of course)
1257 //Speed up a lot (avoid parse all)
1258 if ($tagName == "USERS" and $this->level
== 3) {
1259 $this->finished
= true;
1263 $this->tree
[$this->level
] = "";
1265 $this->content
= "";
1268 //This is the endTag handler we use where we are reading the modules zone (todo="MODULES")
1269 function endElementModules($parser, $tagName) {
1270 //Check if we are into MODULES zone
1271 if ($this->tree
[3] == "MODULES") {
1272 //if (trim($this->content)) //Debug
1273 // echo "C".str_repeat(" ",($this->level+2)*2).$this->getContents()."<br>\n"; //Debug
1274 //echo $this->level.str_repeat(" ",$this->level*2)."</".$tagName."><br>\n"; //Debug
1275 //Acumulate data to info (content + close tag)
1276 //Reconvert: strip htmlchars again and trim to generate xml data
1277 $this->temp
.= htmlspecialchars(trim($this->content
))."</".$tagName.">";
1278 //If we've finished a mod, xmlize it an save to db
1279 if (($this->level
== 4) and ($tagName == "MOD")) {
1280 //Prepend XML standard header to info gathered
1281 $xml_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".$this->temp
;
1282 //Call to xmlize for this portion of xml data (one MOD)
1283 $data = xmlize($xml_data);
1284 //traverse_xmlize($data); //Debug
1285 //print_object ($GLOBALS['traverse_array']); //Debug
1286 //$GLOBALS['traverse_array']=""; //Debug
1287 //Now, save data to db. We'll use it later
1288 //Get id and modtype from data
1289 $mod_id = $data["MOD"]["#"]["ID"]["0"]["#"];
1290 $mod_type = $data["MOD"]["#"]["MODTYPE"]["0"]["#"];
1291 //Only if we've selected to restore it
1292 if ($this->preferences
->mods
[$mod_type]->restore
) {
1294 $mod_temp = serialize($data);
1296 $sla_mod_temp = addslashes($mod_temp);
1298 backup_putid($this->preferences
->backup_unique_code
,$mod_type,$mod_id,
1299 null,$sla_mod_temp);
1300 //Create returning info
1301 $ret_info->id
= $mod_id;
1302 $ret_info->modtype
= $mod_type;
1303 $this->info
[] = $ret_info;
1305 //Reset info to empty
1310 //Stop parsing if todo = MODULES and tagName = MODULES (en of the tag, of course)
1311 //Speed up a lot (avoid parse all)
1312 if ($tagName == "MODULES" and $this->level
== 3) {
1313 $this->finished
= true;
1317 $this->tree
[$this->level
] = "";
1319 $this->content
= "";
1322 //This is the endTag default handler we use when todo is undefined
1323 function endElement($parser, $tagName) {
1324 if (trim($this->content
)) //Debug
1325 echo "C".str_repeat(" ",($this->level+
2)*2).$this->getContents()."<br>\n"; //Debug
1326 echo $this->level
.str_repeat(" ",$this->level
*2)."</".$tagName."><br>\n"; //Debug
1329 $this->tree
[$this->level
] = "";
1331 $this->content
= "";
1334 //This is the handler to read data contents (simple accumule it)
1335 function characterData($parser, $data) {
1336 $this->content
.= $data;
1340 //This function executes the MoodleParser
1341 function restore_read_xml ($xml_file,$todo,$preferences) {
1345 $xml_parser = xml_parser_create();
1346 $moodle_parser = new MoodleParser();
1347 $moodle_parser->todo
= $todo;
1348 $moodle_parser->preferences
= $preferences;
1349 xml_set_object($xml_parser,&$moodle_parser);
1350 //Depending of the todo we use some element_handler or another
1351 if ($todo == "INFO") {
1352 //Define handlers to that zone
1353 xml_set_element_handler($xml_parser, "startElementInfo", "endElementInfo");
1354 } else if ($todo == "COURSE_HEADER") {
1355 //Define handlers to that zone
1356 xml_set_element_handler($xml_parser, "startElementCourseHeader", "endElementCourseHeader");
1357 } else if ($todo == "SECTIONS") {
1358 //Define handlers to that zone
1359 xml_set_element_handler($xml_parser, "startElementSections", "endElementSections");
1360 } else if ($todo == "USERS") {
1361 //Define handlers to that zone
1362 xml_set_element_handler($xml_parser, "startElementUsers", "endElementUsers");
1363 } else if ($todo == "MODULES") {
1364 //Define handlers to that zone
1365 xml_set_element_handler($xml_parser, "startElementModules", "endElementModules");
1367 //Define default handlers (must no be invoked when everything become finished)
1368 xml_set_element_handler($xml_parser, "startElementInfo", "endElementInfo");
1370 xml_set_character_data_handler($xml_parser, "characterData");
1371 $fp = fopen($xml_file,"r")
1374 while ($data = fread($fp, 4096) and !$moodle_parser->finished
)
1375 xml_parse($xml_parser, $data, feof($fp))
1376 or die(sprintf("XML error: %s at line %d",
1377 xml_error_string(xml_get_error_code($xml_parser)),
1378 xml_get_current_line_number($xml_parser)));
1381 //Get info from parser
1382 $info = $moodle_parser->info
;
1385 xml_parser_free($xml_parser);