Added support for timestart and timeend (user_teachers table) and
[moodle.git] / backup / restorelib.php
1 <?PHP //$Id$
2     //Functions used in restore
3    
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) {
7         
8         global $CFG;
10         $status = true;
12         if (empty($CFG->unzip)) {    // Use built-in php-based unzip function
13             include_once("$CFG->dirroot/lib/pclzip/pclzip.lib.php");
14             //include_once("$CFG->dirroot/lib/pclzip/pclerror.lib.php");    //Debug
15             //include_once("$CFG->dirroot/lib/pclzip/pcltrace.lib.php");    //Debug
16             //PclTraceOn(2);                                          //Debug
17             $archive = new PclZip($file);
18             if (!$list = $archive->extract(dirname($file))) {
19                 $status = false;
20             }
21             //PclTraceDisplay();                                       //Debug
22             //PclTraceOff();                                           //Debug
23         } else {                     // Use external unzip program
24             $command = "cd ".dirname($file)."; $CFG->unzip -o ".basename($file);
25             Exec($command);
26         }
28         return $status;
29     }
31     //This function checks if moodle.xml seems to be a valid xml file
32     //(exists, has an xml header and a course main tag
33     function restore_check_moodle_file ($file) {
34     
35         $status = true;
37         //Check if it exists
38         if ($status = is_file($file)) {
39             //Open it and read the first 200 bytes (chars)
40             $handle = fopen ($file, "r");
41             $first_chars = fread($handle,200);
42             $status = fclose ($handle);
43             //Chek if it has the requires strings
44             if ($status) {
45                 $status = strpos($first_chars,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
46                 if ($status !== false) {
47                     $status = strpos($first_chars,"<MOODLE_BACKUP>");
48                 }
49             }
50         }   
52         return $status;  
53     }   
55     //This function iterates over all modules in backup file, searching for a
56     //MODNAME_refresh_events() to execute. Perhaps it should ve moved to central Moodle...
57     function restore_refresh_events($restore) {
58    
59         global $CFG;
60         $status = true;
61         
62         //Take all modules in backup
63         $modules = $restore->mods;
64         //Iterate
65         foreach($modules as $name => $module) {
66             //Only if the module is being restored
67             if ($module->restore == 1) {
68                 //Include module library
69                 include_once("$CFG->dirroot/mod/$name/lib.php");
70                 //If module_refresh_events exists
71                 $function_name = $name."_refresh_events";
72                 if (function_exists($function_name)) {
73                     $status = $function_name($restore->course_id);
74                 }
75             }
76         }
77         return $status;
78     }
80     //This function makes all the necessary calls to xxxx_decode_content_links_caller()
81     //function in each module, passing them the desired contents to be decoded
82     //from backup format to destination site/course in order to mantain inter-activities
83     //working in the backup/restore process
84     function restore_decode_content_links($restore) {
86         global $CFG;
88         $status = true;
90         echo "<ul>";
91         foreach ($restore->mods as $name => $info) {
92             //If the module is being restored
93             if ($info->restore == 1) {
94                 //Check if the xxxx_decode_content_links_caller exists
95                 $function_name = $name."_decode_content_links_caller";
96                 if (function_exists($function_name)) {
97                     echo "<li>".get_string ("to")." ".get_string("modulenameplural",$name);
98                     $status = $function_name($restore);
99                 }
100             }
101         }
103         //Now I'm going to decode to their new location all the links in wiki texts
104         //having the syntax " modulename:moduleid".
105         echo "<li>wiki";
106         $status = restore_decode_wiki_texts($restore);
108         echo "</ul>";
110         return $status;
111     }
113     //This function search for some wiki texts in differenct parts of Moodle to
114     //decode them to their new ids.
115     function restore_decode_wiki_texts($restore) {
117         global $CFG;
119         $status = true;
121         echo "<ul>";
123         if (file_exists("$CFG->dirroot/mod/resource/lib.php")) {
124             include_once("$CFG->dirroot/mod/resource/lib.php");
125         }
127         $formatwiki = FORMAT_WIKI;
128         $typewiki = WIKITEXT;
129  
130         //FORUM: Decode every POST (message) in the course
131         //Check we are restoring forums
132         if ($restore->mods['forum']->restore == 1) {
133             echo "<li>".get_string("from")." ".get_string("modulenameplural","forum");
134             //Get all course posts
135             if ($posts = get_records_sql ("SELECT p.id, p.message
136                                        FROM {$CFG->prefix}forum_posts p,
137                                             {$CFG->prefix}forum_discussions d
138                                        WHERE d.course = $restore->course_id AND
139                                              p.discussion = d.id AND
140                                              p.format = $formatwiki")) {
141                 //Iterate over each post->message
142                 $i = 0;   //Counter to send some output to the browser to avoid timeouts
143                 foreach ($posts as $post) {
144                     //Increment counter
145                     $i++;
146                     $content = $post->message;
147                     //Decode it 
148                     $result = restore_decode_wiki_content($content,$restore);
150                     if ($result != $content) {
151                         //Update record
152                         $post->message = addslashes($result);
153                         $status = update_record("forum_posts",$post);
154                         if ($CFG->debug>7) {
155                             echo "<br><hr>".$content."<br>changed to</br>".$result."<hr><br>";
156                         }
157                     }
158                     //Do some output
159                     if (($i+1) % 5 == 0) {
160                         echo ".";
161                         if (($i+1) % 100 == 0) {
162                             echo "<br>";
163                         }
164                         backup_flush(300);
165                     }
166                 }
167             }
168         }
170         //RESOURCE: Decode every RESOURCE (alltext) in the coure
172         //Check we are restoring resources
173         if ($restore->mods['resource']->restore == 1) {
174             echo "<li>".get_string("from")." ".get_string("modulenameplural","resource");
175             //Get all course resources of type=8 WIKITEXT
176             if ($resources = get_records_sql ("SELECT r.id, r.alltext
177                                        FROM {$CFG->prefix}resource r
178                                        WHERE r.course = $restore->course_id AND
179                                              r.type = $typewiki")) {
180                 //Iterate over each resource->alltext
181                 $i = 0;   //Counter to send some output to the browser to avoid timeouts
182                 foreach ($resources as $resource) {
183                     //Increment counter
184                     $i++;
185                     $content = $resource->alltext;
186                     //Decode it
187                     $result = restore_decode_wiki_content($content,$restore);
188                     if ($result != $content) {
189                         //Update record
190                         $resource->alltext = addslashes($result);
191                         $status = update_record("resource",$resource);
192                         if ($CFG->debug>7) {
193                             echo "<br><hr>".$content."<br>changed to</br>".$result."<hr><br>";
194                         }
195                     }
196                     //Do some output
197                     if (($i+1) % 5 == 0) {
198                         echo ".";
199                         if (($i+1) % 100 == 0) {
200                             echo "<br>";
201                         }
202                         backup_flush(300);
203                     }
204                 }
205             }
206         }
207         echo "</ul>";
209         return $status;
211     }
213     //This function receives a wiki text in the restore process and
214     //return it with every link to modules " modulename:moduleid"
215     //converted if possible. See the space before modulename!!
216     function restore_decode_wiki_content($content,$restore) {
218         global $CFG;
219         
220         $result = $content;
221         
222         $searchstring='/ ([a-zA-Z]+):([0-9]+)\(([^)]+)\)/';
223         //We look for it
224         preg_match_all($searchstring,$content,$foundset);
225         //If found, then we are going to look for its new id (in backup tables)
226         if ($foundset[0]) { 
227             //print_object($foundset);                                     //Debug
228             //Iterate over foundset[2]. They are the old_ids               
229             foreach($foundset[2] as $old_id) {
230                 //We get the needed variables here (course id)
231                 $rec = backup_getid($restore->backup_unique_code,"course_modules",$old_id);
232                 //Personalize the searchstring
233                 $searchstring='/ ([a-zA-Z]+):'.$old_id.'\(([^)]+)\)/';
234                 //If it is a link to this course, update the link to its new location
235                 if($rec->new_id) {
236                     //Now replace it
237                     $result= preg_replace($searchstring,' $1:'.$rec->new_id.'($2)',$result);
238                 } else {
239                     //It's a foreign link so redirect it to its original URL
240                     $result= preg_replace($searchstring,$restore->original_wwwroot.'/mod/$1/view.php?id='.$old_id.'($2)',$result);
241                 }
242             }
243         }
244         return $result;
245     }
248     //This function read the xml file and store it data from the info zone in an object
249     function restore_read_xml_info ($xml_file) {
251         //We call the main read_xml function, with todo = INFO
252         $info = restore_read_xml ($xml_file,"INFO",false);
254         return $info;
255     }
257     //This function read the xml file and store it data from the course header zone in an object  
258     function restore_read_xml_course_header ($xml_file) {
260         //We call the main read_xml function, with todo = COURSE_HEADER
261         $info = restore_read_xml ($xml_file,"COURSE_HEADER",false);
263         return $info;
264     }
266     //This function read the xml file and store its data from the sections in a object
267     function restore_read_xml_sections ($xml_file) {
269         //We call the main read_xml function, with todo = SECTIONS
270         $info = restore_read_xml ($xml_file,"SECTIONS",false);
272         return $info;
273     }
274     
275     //This function read the xml file and store its data from the users in 
276     //backup_ids->info db (and user's id in $info)
277     function restore_read_xml_users ($restore,$xml_file) {
279         //We call the main read_xml function, with todo = USERS
280         $info = restore_read_xml ($xml_file,"USERS",$restore);
282         return $info;
283     }
285     //This function read the xml file and store its data from the questions in
286     //backup_ids->info db (and category's id in $info)
287     function restore_read_xml_questions ($restore,$xml_file) {
289         //We call the main read_xml function, with todo = QUESTIONS
290         $info = restore_read_xml ($xml_file,"QUESTIONS",$restore);
292         return $info;
293     }
295     //This function read the xml file and store its data from the scales in
296     //backup_ids->info db (and scale's id in $info)
297     function restore_read_xml_scales ($restore,$xml_file) {
299         //We call the main read_xml function, with todo = SCALES
300         $info = restore_read_xml ($xml_file,"SCALES",$restore);
302         return $info;
303     }
305     //This function read the xml file and store its data from the groups in
306     //backup_ids->info db (and group's id in $info)
307     function restore_read_xml_groups ($restore,$xml_file) {
309         //We call the main read_xml function, with todo = GROUPS
310         $info = restore_read_xml ($xml_file,"GROUPS",$restore);
312         return $info;
313     }
315     //This function read the xml file and store its data from the events (course) in
316     //backup_ids->info db (and event's id in $info)
317     function restore_read_xml_events ($restore,$xml_file) {
319         //We call the main read_xml function, with todo = EVENTS
320         $info = restore_read_xml ($xml_file,"EVENTS",$restore);
322         return $info;
323     }
325     //This function read the xml file and store its data from the modules in
326     //backup_ids->info
327     function restore_read_xml_modules ($restore,$xml_file) {
329         //We call the main read_xml function, with todo = MODULES
330         $info = restore_read_xml ($xml_file,"MODULES",$restore);
332         return $info;
333     }
335     //This function read the xml file and store its data from the logs in
336     //backup_ids->info
337     function restore_read_xml_logs ($restore,$xml_file) {
339         //We call the main read_xml function, with todo = LOGS
340         $info = restore_read_xml ($xml_file,"LOGS",$restore);
342         return $info;
343     }
345     //This function prints the contents from the info parammeter passed
346     function restore_print_info ($info) {
348         $status = true;
349         if ($info) {
350             //This is tha align to every ingo table      
351             $table->align = array ("RIGHT","LEFT");
352             //This is the nowrap clause 
353             $table->wrap = array ("","NOWRAP");
354             //The width
355             $table->width = "70%";
356             //Put interesting info in table
357             //The backup original name
358             $tab[0][0] = "<b>".get_string("backuporiginalname").":</b>";
359             $tab[0][1] = $info->backup_name;
360             //The moodle version
361             $tab[1][0] = "<b>".get_string("moodleversion").":</b>";
362             $tab[1][1] = $info->backup_moodle_release." (".$info->backup_moodle_version.")";
363             //The backup version
364             $tab[2][0] = "<b>".get_string("backupversion").":</b>";
365             $tab[2][1] = $info->backup_backup_release." (".$info->backup_backup_version.")";
366             //The backup date
367             $tab[3][0] = "<b>".get_string("backupdate").":</b>";
368             $tab[3][1] = userdate($info->backup_date);
369             //Print title
370             print_heading(get_string("backup").":");
371             $table->data = $tab;
372             //Print backup general info
373             print_table($table);
374             //Now backup contents in another table
375             $tab = array();
376             //First mods info
377             $mods = $info->mods;
378             $elem = 0;
379             foreach ($mods as $key => $mod) {
380                 $tab[$elem][0] = "<b>".get_string("modulenameplural",$key).":</b>";
381                 if ($mod->backup == "false") {
382                     $tab[$elem][1] = get_string("notincluded");
383                 } else {
384                     if ($mod->userinfo == "true") {
385                         $tab[$elem][1] = get_string("included")." ".get_string("withuserdata");
386                     } else {
387                         $tab[$elem][1] = get_string("included")." ".get_string("withoutuserdata");
388                     }
389                 }
390                 $elem++;
391             }
392             //Users info
393             $tab[$elem][0] = "<b>".get_string("users").":</b>";
394             $tab[$elem][1] = get_string($info->backup_users);
395             $elem++;
396             //Logs info
397             $tab[$elem][0] = "<b>".get_string("logs").":</b>";
398             if ($info->backup_logs == "true") {
399                 $tab[$elem][1] = get_string("yes");
400             } else {
401                 $tab[$elem][1] = get_string("no");
402             }
403             $elem++;
404             //User Files info
405             $tab[$elem][0] = "<b>".get_string("userfiles").":</b>";
406             if ($info->backup_user_files == "true") {
407                 $tab[$elem][1] = get_string("yes");
408             } else {
409                 $tab[$elem][1] = get_string("no");
410             }
411             $elem++;
412             //Course Files info
413             $tab[$elem][0] = "<b>".get_string("coursefiles").":</b>";
414             if ($info->backup_course_files == "true") {
415                 $tab[$elem][1] = get_string("yes");
416             } else {
417                 $tab[$elem][1] = get_string("no");
418             }
419             $elem++;
420             $table->data = $tab;
421             //Print title
422             print_heading(get_string("backupdetails").":");
423             //Print backup general info
424             print_table($table);
425         } else {
426             $status = false;
427         }
429         return $status;
430     }
432     //This function prints the contents from the course_header parammeter passed
433     function restore_print_course_header ($course_header) {
435         $status = true;
436         if ($course_header) {
437             //This is tha align to every ingo table
438             $table->align = array ("RIGHT","LEFT");
439             //The width
440             $table->width = "70%";
441             //Put interesting course header in table
442             //The course name
443             $tab[0][0] = "<b>".get_string("name").":</b>";
444             $tab[0][1] = $course_header->course_fullname." (".$course_header->course_shortname.")";
445             //The course summary
446             $tab[1][0] = "<b>".get_string("summary").":</b>";
447             $tab[1][1] = $course_header->course_summary;
448             $table->data = $tab;
449             //Print title
450             print_heading(get_string("course").":");
451             //Print backup course header info
452             print_table($table);
453         } else {
454             $status = false; 
455         }
456         return $status;
457     }
459     //This function create a new course record.
460     //When finished, course_header contains the id of the new course
461     function restore_create_new_course($restore,&$course_header) {
463         global $CFG;
464  
465         $status = true;
467         $fullname = $course_header->course_fullname;
468         $shortname = $course_header->course_shortname;
469         $currentfullname = "";
470         $currentshortname = "";
471         $counter = 0;
472         //Iteratere while the name exists
473         do {
474             if ($counter) {
475                 $suffixfull = " ".get_string("copy")." ".$counter;
476                 $suffixshort = "_".$counter;
477             } else {
478                 $suffixfull = "";
479                 $suffixshort = "";
480             }
481             $currentfullname = $fullname.$suffixfull;
482             $currentshortname = $shortname.$suffixshort;
483             $course = get_record("course","fullname",addslashes($currentfullname));
484             $counter++;
485         } while ($course);
487         //New name = currentname
488         $course_header->course_fullname = $currentfullname;
489         $course_header->course_shortname = $currentshortname;
490         
491         //Now calculate the category
492         $category = get_record("course_categories","id",$course_header->category->id,
493                                                    "name",addslashes($course_header->category->name));
494         //If no exists, try by name only
495         if (!$category) {
496             $category = get_record("course_categories","name",addslashes($course_header->category->name));
497         }
498         //If no exists, get category id 1
499         if (!$category) {
500             $category = get_record("course_categories","id","1");
501         }
502         //If category 1 doesn'exists, lets create the course category (get it from backup file)
503         if (!$category) {
504             $ins_category->name = addslashes($course_header->category->name);
505             $ins_category->parent = 0;
506             $ins_category->sortorder = 0;
507             $ins_category->coursecount = 0;
508             $ins_category->visible = 0;            //To avoid interferences with the rest of the site
509             $ins_category->timemodified = time();
510             $newid = insert_record("course_categories",$ins_category);
511             $category->id = $newid;
512             $category->name = $course_header->category->name;
513         }
514         //If exists, put new category id
515         if ($category) {
516             $course_header->category->id = $category->id;
517             $course_header->category->name = $category->name;
518         //Error, cannot locate category
519         } else {
520             $course_header->category->id = 0;
521             $course_header->category->name = get_string("unknowncategory");
522             $status = false;
523         }
525         //Create the course_object
526         if ($status) {
527             $course->category = addslashes($course_header->category->id);
528             $course->password = addslashes($course_header->course_password);
529             $course->fullname = addslashes($course_header->course_fullname);
530             $course->shortname = addslashes($course_header->course_shortname);
531             $course->idnumber = addslashes($course_header->course_idnumber);
532             $course->summary = addslashes($course_header->course_summary);
533             $course->format = addslashes($course_header->course_format);
534             $course->showgrades = addslashes($course_header->course_showgrades);
535             $course->blockinfo = addslashes($course_header->blockinfo);
536             $course->newsitems = addslashes($course_header->course_newsitems);
537             $course->teacher = addslashes($course_header->course_teacher);
538             $course->teachers = addslashes($course_header->course_teachers);
539             $course->student = addslashes($course_header->course_student);
540             $course->students = addslashes($course_header->course_students);
541             $course->guest = addslashes($course_header->course_guest);
542             $course->startdate = addslashes($course_header->course_startdate);
543             $course->numsections = addslashes($course_header->course_numsections);
544             //$course->showrecent = addslashes($course_header->course_showrecent);   INFO: This is out in 1.3
545             $course->maxbytes = addslashes($course_header->course_maxbytes);
546             $course->showreports = addslashes($course_header->course_showreports);
547             $course->groupmode = addslashes($course_header->course_groupmode);
548             $course->groupmodeforce = addslashes($course_header->course_groupmodeforce);
549             $course->lang = addslashes($course_header->course_lang);
550             $course->marker = addslashes($course_header->course_marker);
551             $course->visible = addslashes($course_header->course_visible);
552             $course->hiddensections = addslashes($course_header->course_hiddensections);
553             $course->timecreated = addslashes($course_header->course_timecreated);
554             $course->timemodified = addslashes($course_header->course_timemodified);
555             //Adjust blockinfo field.
556             //If the info doesn't exist in backup, we create defaults, else we recode it 
557             //to current site blocks.
558             if (!$course->blockinfo) {
559                 //Create blockinfo default content
560                 if ($course->format == "social") {
561                     $course->blockinfo = blocks_get_default_blocks (NULL,"participants,search_forums,calendar_month,calendar_upcoming,social_activities,recent_activity,admin,course_list");
562                 } else {
563                     //For topics and weeks formats (default built in the function)
564                     $course->blockinfo = blocks_get_default_blocks();
565                 }
566             } else {
567                 $course->blockinfo = blocks_get_block_ids($course->blockinfo);
568             }
569             //Now insert the record
570             $newid = insert_record("course",$course);
571             if ($newid) {
572                 //save old and new course id
573                 backup_putid ($restore->backup_unique_code,"course",$course_header->course_id,$newid);
574                 //Replace old course_id in course_header
575                 $course_header->course_id = $newid;
576             } else {
577                 $status = false;
578             }
579         }
581         return $status;
582     }
584     //This function creates all the course_sections and course_modules from xml
585     //when restoring in a new course or simply checks sections and create records
586     //in backup_ids when restoring in a existing course
587     function restore_create_sections($restore,$xml_file) {
589         global $CFG,$db;
591         $status = true;
592         //Check it exists
593         if (!file_exists($xml_file)) {
594             $status = false;
595         }
596         //Get info from xml
597         if ($status) {
598             $info = restore_read_xml_sections($xml_file);
599         }
600         //Put the info in the DB, recoding ids and saving the in backup tables
602         $sequence = "";
604         if ($info) {
605             //For each, section, save it to db
606             foreach ($info->sections as $key => $sect) {
607                 $sequence = "";
608                 $section->course = $restore->course_id;
609                 $section->section = $sect->number;
610                 $section->summary = addslashes($sect->summary);
611                 $section->visible = $sect->visible;
612                 $section->sequence = "";
613                 //Now calculate the section's newid
614                 $newid = 0;
615                 if ($restore->restoreto == 2) {
616                 //Save it to db (only if restoring to new course)
617                     $newid = insert_record("course_sections",$section);
618                 } else {
619                     //Get section id when restoring in existing course
620                     $rec = get_record("course_sections","course",$restore->course_id,
621                                                         "section",$section->section);
622                     //If that section doesn't exist, get section 0 (every mod will be
623                     //asigned there
624                     if(!$rec) {
625                         $rec = get_record("course_sections","course",$restore->course_id,
626                                                             "section","0");
627                     }
628                     //New check. If section 0 doesn't exist, insert it here !!
629                     //Teorically this never should happen but, in practice, some users
630                     //have reported this issue. 
631                     if(!$rec) {
632                         $zero_sec->course = $restore->course_id;
633                         $zero_sec->section = 0;
634                         $zero_sec->summary = "";
635                         $zero_sec->sequence = "";
636                         $newid = insert_record("course_sections",$zero_sec);
637                         $rec->id = $newid;
638                         $rec->sequence = "";
639                     }
640                     $newid = $rec->id;
641                     $sequence = $rec->sequence;
642                 }
643                 if ($newid) {
644                     //save old and new section id
645                     backup_putid ($restore->backup_unique_code,"course_sections",$key,$newid);
646                 } else {
647                     $status = false;
648                 }
649                 //If all is OK, go with associated mods
650                 if ($status) {
651                     //If we have mods in the section
652                     if (!empty($sect->mods)) {
653                         //For each mod inside section
654                         foreach ($sect->mods as $keym => $mod) {
655                             //Check if we've to restore this module
656                             if ($restore->mods[$mod->type]->restore) {
657                                 //Get the module id from modules
658                                 $module = get_record("modules","name",$mod->type);
659                                 if ($module) {
660                                     $course_module->course = $restore->course_id;
661                                     $course_module->module = $module->id;
662                                     $course_module->section = $newid;
663                                     $course_module->added = $mod->added;
664                                     $course_module->deleted = $mod->deleted;
665                                     $course_module->score = $mod->score;
666                                     $course_module->indent = $mod->indent;
667                                     $course_module->visible = $mod->visible;
668                                     $course_module->groupmode = $mod->groupmode;
669                                     $course_module->instance = null;
670                                     //NOTE: The instance (new) is calculated and updated in db in the
671                                     //      final step of the restore. We don't know it yet.
672                                     //print_object($course_module);                                     //Debug
673                                     //Save it to db
674                                     $newidmod = insert_record("course_modules",$course_module); 
675                                     if ($newidmod) {
676                                         //save old and new module id
677                                         //In the info field, we save the original instance of the module
678                                         //to use it later
679                                         backup_putid ($restore->backup_unique_code,"course_modules",
680                                                                 $keym,$newidmod,$mod->instance);
681                                     } else {
682                                         $status = false;
683                                     }
684                                     //Now, calculate the sequence field
685                                     if ($status) {
686                                         if ($sequence) {
687                                             $sequence .= ",".$newidmod;
688                                         } else {
689                                             $sequence = $newidmod;
690                                         }
691                                     }
692                                 } else {
693                                     $status = false;
694                                 }
695                             }
696                         }
697                     }
698                 }
699                 //If all is OK, update sequence field in course_sections
700                 if ($status) {
701                     if (isset($sequence)) {
702                         $update_rec->id = $newid;
703                         $update_rec->sequence = $sequence;
704                         $status = update_record("course_sections",$update_rec);
705                     }
706                 }
707             }
708         } else {
709             $status = false;
710         }
711         return $status;
712     }
713     
714     //This function creates all the user, user_students, user_teachers
715     //user_course_creators and user_admins from xml
716     function restore_create_users($restore,$xml_file) {
718         global $CFG, $db;
720         $status = true;
721         //Check it exists
722         if (!file_exists($xml_file)) {
723             $status = false;
724         }
725         //Get info from xml
726         if ($status) {
727             //info will contain the old_id of every user
728             //in backup_ids->info will be the real info (serialized)
729             $info = restore_read_xml_users($restore,$xml_file);
730         }
732         //Now, get evey user_id from $info and user data from $backup_ids
733         //and create the necessary records (users, user_students, user_teachers
734         //user_course_creators and user_admins
735         if (!empty($info->users)) {
736             //For each user, take its info from backup_ids
737             foreach ($info->users as $userid) {
738                 $rec = backup_getid($restore->backup_unique_code,"user",$userid); 
739                 $user = $rec->info;
741                 //Check if it's admin and coursecreator
742                 $is_admin =         !empty($user->roles['admin']);
743                 $is_coursecreator = !empty($user->roles['coursecreator']);
745                 //Check if it's teacher and student
746                 $is_teacher = !empty($user->roles['teacher']);
747                 $is_student = !empty($user->roles['student']);
749                 //Check if it's needed
750                 $is_needed = !empty($user->roles['needed']);
752                 //Calculate if it is a course user
753                 //Has role teacher or student or needed
754                 $is_course_user = ($is_teacher or $is_student or $is_needed);
756                 //To store new ids created
757                 $newid=null;
758                 //check if it exists (by username) and get its id
759                 $user_exists = true;
760                 $user_data = get_record("user","username",addslashes($user->username));
761                 if (!$user_data) {
762                     $user_exists = false;
763                 } else {
764                     $newid = $user_data->id;
765                 }
766                 //Flags to see if we have to create the user, roles and preferences
767                 $create_user = true;
768                 $create_roles = true;
769                 $create_preferences = true;
771                 //If we are restoring course users and it isn't a course user
772                 if ($restore->users == 1 and !$is_course_user) {
773                     //If only restoring course_users and user isn't a course_user, inform to $backup_ids
774                     $status = backup_putid($restore->backup_unique_code,"user",$userid,null,'notincourse');
775                     $create_user = false;
776                     $create_roles = false;
777                     $create_preferences = false;
778                 }
780                 if ($user_exists and $create_user) {
781                     //If user exists mark its newid in backup_ids (the same than old)
782                     $status = backup_putid($restore->backup_unique_code,"user",$userid,$newid,'exists');
783                     $create_user = false;
784                 }
786                 //Here, if create_user, do it
787                 if ($create_user) {
788                     //Unset the id because it's going to be inserted with a new one
789                     unset ($user->id);
790                     //We addslashes to necessary fields
791                     $user->username = addslashes($user->username);
792                     $user->firstname = addslashes($user->firstname);
793                     $user->lastname = addslashes($user->lastname);
794                     $user->email = addslashes($user->email);
795                     $user->institution = addslashes($user->institution);
796                     $user->department = addslashes($user->department);
797                     $user->address = addslashes($user->address);
798                     $user->city = addslashes($user->city);
799                     $user->url = addslashes($user->url);
800                     $user->description = addslashes($user->description);
801                     //We are going to create the user
802                     //The structure is exactly as we need
803                     $newid = insert_record ("user",$user);
804                     //Put the new id
805                     $status = backup_putid($restore->backup_unique_code,"user",$userid,$newid,"new");
806                 }
808                 //Here, if create_roles, do it as necessary
809                 if ($create_roles) {
810                     //Get the newid and current info from backup_ids
811                     $data = backup_getid($restore->backup_unique_code,"user",$userid);
812                     $newid = $data->new_id;
813                     $currinfo = $data->info.",";
815                     //Now, depending of the role, create records in user_studentes and user_teacher 
816                     //and/or mark it in backup_ids
817                     
818                     if ($is_admin) {
819                         //If the record (user_admins) doesn't exists
820                         if (!record_exists("user_admins","userid",$newid)) {
821                             //Only put status in backup_ids
822                             $currinfo = $currinfo."admin,";
823                             $status = backup_putid($restore->backup_unique_code,"user",$userid,$newid,$currinfo);
824                         }
825                     } 
826                     if ($is_coursecreator) {
827                         //If the record (user_coursecreators) doesn't exists
828                         if (!record_exists("user_coursecreators","userid",$newid)) {
829                             //Only put status in backup_ids
830                             $currinfo = $currinfo."coursecreator,";
831                             $status = backup_putid($restore->backup_unique_code,"user",$userid,$newid,$currinfo);
832                         }
833                     } 
834                     if ($is_needed) {
835                         //Only put status in backup_ids
836                         $currinfo = $currinfo."needed,";
837                         $status = backup_putid($restore->backup_unique_code,"user",$userid,$newid,$currinfo);
838                     }
839                     if ($is_teacher) {
840                         //If the record (teacher) doesn't exists
841                         if (!record_exists("user_teachers","userid",$newid,"course", $restore->course_id)) {
842                             //Put status in backup_ids 
843                             $currinfo = $currinfo."teacher,";
844                             $status = backup_putid($restore->backup_unique_code,"user",$userid,$newid,$currinfo);
845                             //Set course and user
846                             $user->roles['teacher']->course = $restore->course_id;
847                             $user->roles['teacher']->userid = $newid;
848                             //Insert data in user_teachers
849                             //The structure is exactly as we need
850                             $status = insert_record("user_teachers",$user->roles['teacher']);
851                         }
852                     } 
853                     if ($is_student) {
854                         //If the record (student) doesn't exists
855                         if (!record_exists("user_students","userid",$newid,"course", $restore->course_id)) {
856                             //Put status in backup_ids
857                             $currinfo = $currinfo."student,";
858                             $status = backup_putid($restore->backup_unique_code,"user",$userid,$newid,$currinfo);
859                             //Set course and user
860                             $user->roles['student']->course = $restore->course_id;
861                             $user->roles['student']->userid = $newid;
862                             //Insert data in user_students
863                             //The structure is exactly as we need
864                             $status = insert_record("user_students",$user->roles['student']);
865                         }
866                     }
867                     if (!$is_course_user) {
868                         //If the record (user) doesn't exists
869                         if (!record_exists("user","id",$newid)) {
870                             //Put status in backup_ids
871                             $currinfo = $currinfo."user,";
872                             $status = backup_putid($restore->backup_unique_code,"user",$userid,$newid,$currinfo);
873                         }
874                     }
875                 }
877                 //Here, if create_preferences, do it as necessary
878                 if ($create_preferences) {
879                     //echo "Checking for preferences of user ".$user->username."<br>";         //Debug
880                     //Get user new id from backup_ids
881                     $data = backup_getid($restore->backup_unique_code,"user",$userid);
882                     $newid = $data->new_id;
883                     if (isset($user->user_preferences)) {
884                         //echo "Preferences exist in backup file<br>";                         //Debug
885                         foreach($user->user_preferences as $user_preference) {
886                             //echo $user_preference->name." = ".$user_preference->value."<br>";    //Debug
887                             //We check if that user_preference exists in DB
888                             if (!record_exists("user_preferences","userid",$newid,"name",$user_preference->name)) {
889                                 //echo "Creating it<br>";                                              //Debug
890                                 //Prepare the record and insert it
891                                 $user_preference->userid = $newid;
892                                 $status = insert_record("user_preferences",$user_preference);
893                             }
894                         }
895                     }
896                 }
897             }
898         }
900         return $status;
901     }
903     //This function creates all the categories and questions
904     //from xml (STEP1 of quiz restore)
905     function restore_create_questions($restore,$xml_file) {
907         global $CFG, $db;
909         $status = true;
910         //Check it exists
911         if (!file_exists($xml_file)) {
912             $status = false;
913         }
914         //Get info from xml
915         if ($status) {
916             //info will contain the old_id of every category
917             //in backup_ids->info will be the real info (serialized)
918             $info = restore_read_xml_questions($restore,$xml_file);
919         }
920         //Now, if we have anything in info, we have to restore that
921         //categories/questions
922         if ($info) {
923             if ($info !== true) {
924                 //Iterate over each category
925                 foreach ($info as $category) {
926                     $catrestore = "quiz_restore_question_categories";
927                     if (function_exists($catrestore)) {
928                         //print_object ($category);                                                //Debug
929                         $status = $catrestore($category,$restore);
930                     } else {
931                         //Something was wrong. Function should exist.
932                         $status = false;
933                     }
934                 }
935             }
936         } else {
937             $status = false;
938         }   
939         return $status;
940     }
942     //This function creates all the scales
943     function restore_create_scales($restore,$xml_file) {
945         global $CFG, $db;
947         $status = true;
948         //Check it exists
949         if (!file_exists($xml_file)) {
950             $status = false;
951         }
952         //Get info from xml
953         if ($status) {
954             //scales will contain the old_id of every scale
955             //in backup_ids->info will be the real info (serialized)
956             $scales = restore_read_xml_scales($restore,$xml_file);
957         }
958         //Now, if we have anything in scales, we have to restore that
959         //scales
960         if ($scales) {
961             if ($scales !== true) {
962                 //Iterate over each scale
963                 foreach ($scales as $scale) {
964                     //Get record from backup_ids
965                     $data = backup_getid($restore->backup_unique_code,"scale",$scale->id);
966                     //Init variables
967                     $create_scale = false;
969                     if ($data) {
970                         //Now get completed xmlized object
971                         $info = $data->info;
972                         //traverse_xmlize($info);                                                                     //Debug
973                         //print_object ($GLOBALS['traverse_array']);                                                  //Debug
974                         //$GLOBALS['traverse_array']="";                                                              //Debug
976                         //Now build the SCALE record structure
977                         $sca->courseid = backup_todb($info['SCALE']['#']['COURSEID']['0']['#']);
978                         $sca->userid = backup_todb($info['SCALE']['#']['USERID']['0']['#']);
979                         $sca->name = backup_todb($info['SCALE']['#']['NAME']['0']['#']);
980                         $sca->scale = backup_todb($info['SCALE']['#']['SCALETEXT']['0']['#']);
981                         $sca->description = backup_todb($info['SCALE']['#']['DESCRIPTION']['0']['#']);
982                         $sca->timemodified = backup_todb($info['SCALE']['#']['TIMEMODIFIED']['0']['#']);
984                         //Now search if that scale exists (by scale field) in course 0 (Standar scale)
985                         //or in restore->course_id course (Personal scale)
986                         if ($sca->courseid == 0) {
987                             $course_to_search = 0;
988                         } else {
989                             $course_to_search = $restore->course_id;
990                         }
991                         $sca_db = get_record("scale","scale",$sca->scale,"courseid",$course_to_search);
992                         //If it doesn't exist, create
993                         if (!$sca_db) {
994                             $create_scale = true;
995                         } 
996                         //If we must create the scale
997                         if ($create_scale) {
998                             //Me must recode the courseid if it's <> 0 (common scale)
999                             if ($sca->courseid != 0) {
1000                                 $sca->courseid = $restore->course_id;
1001                             }
1002                             //We must recode the userid
1003                             $user = backup_getid($restore->backup_unique_code,"user",$sca->userid);
1004                             if ($user) {
1005                                 $sca->userid = $user->new_id;
1006                             } else {
1007                                 //Assign it to admin
1008                                 $sca->userid = 1;
1009                             }
1010                             //The structure is equal to the db, so insert the scale
1011                             $newid = insert_record ("scale",$sca);
1012                         } else {
1013                             //get current scale id
1014                             $newid = $sca_db->id;
1015                         }
1016                         if ($newid) {
1017                             //We have the newid, update backup_ids
1018                             backup_putid($restore->backup_unique_code,"scale",
1019                                          $scale->id, $newid);
1020                         }
1021                     }
1022                 }
1023             }
1024         } else {
1025             $status = false;
1026         }  
1027         return $status;
1028     }
1030     //This function creates all the groups
1031     function restore_create_groups($restore,$xml_file) {
1033         global $CFG, $db;
1035         $status = true;
1036         $status2 = true;
1037         //Check it exists
1038         if (!file_exists($xml_file)) {
1039             $status = false;
1040         }
1041         //Get info from xml
1042         if ($status) {
1043             //groups will contain the old_id of every group
1044             //in backup_ids->info will be the real info (serialized)
1045             $groups = restore_read_xml_groups($restore,$xml_file);
1046         }
1047         //Now, if we have anything in groups, we have to restore that
1048         //groups
1049         if ($groups) {
1050             if ($groups !== true) {
1051                 //Iterate over each group
1052                 foreach ($groups as $group) {
1053                     //Get record from backup_ids
1054                     $data = backup_getid($restore->backup_unique_code,"group",$group->id);
1055                     //Init variables
1056                     $create_group = false;
1058                     if ($data) {
1059                         //Now get completed xmlized object
1060                         $info = $data->info;
1061                         //traverse_xmlize($info);                                                                     //Debug
1062                         //print_object ($GLOBALS['traverse_array']);                                                  //Debug
1063                         //$GLOBALS['traverse_array']="";                                                              //Debug
1064                         //Now build the GROUP record structure
1065                         $gro->courseid = backup_todb($info['GROUP']['#']['COURSEID']['0']['#']);
1066                         $gro->name = backup_todb($info['GROUP']['#']['NAME']['0']['#']);
1067                         $gro->description = backup_todb($info['GROUP']['#']['DESCRIPTION']['0']['#']);
1068                         $gro->lang = backup_todb($info['GROUP']['#']['LANG']['0']['#']);
1069                         $gro->picture = backup_todb($info['GROUP']['#']['PICTURE']['0']['#']);
1070                         $gro->hidepicture = backup_todb($info['GROUP']['#']['HIDEPICTURE']['0']['#']);
1071                         $gro->timecreated = backup_todb($info['GROUP']['#']['TIMECREATED']['0']['#']);
1072                         $gro->timemodified = backup_todb($info['GROUP']['#']['TIMEMODIFIED']['0']['#']);
1073                 
1074                         //Now search if that group exists (by name and description field) in 
1075                         //restore->course_id course 
1076                         $gro_db = get_record("groups","courseid",$restore->course_id,"name",$gro->name,"description",$gro->description);
1077                         //If it doesn't exist, create
1078                         if (!$gro_db) {
1079                             $create_group = true;
1080                         }
1081                         //If we must create the group
1082                         if ($create_group) {
1083                             //Me must recode the courseid to the restore->course_id 
1084                             $gro->courseid = $restore->course_id;
1085                             //The structure is equal to the db, so insert the group
1086                             $newid = insert_record ("groups",$gro);
1087                         } else { 
1088                             //get current group id
1089                             $newid = $gro_db->id;
1090                         }
1091                         if ($newid) {
1092                             //We have the newid, update backup_ids
1093                             backup_putid($restore->backup_unique_code,"group",
1094                                          $group->id, $newid);
1095                         }
1096                         //Now restore members in the groups_members
1097                         $status2 = restore_create_groups_members($newid,$info,$restore);
1098                     }   
1099                 }
1100             }
1101         } else {
1102             $status = false;
1103         } 
1104         return ($status && $status2);
1105     }
1107     //This function restores the groups_members
1108     function restore_create_groups_members($group_id,$info,$restore) {
1110         global $CFG;
1112         $status = true;
1114         //Get the members array
1115         $members = $info['GROUP']['#']['MEMBERS']['0']['#']['MEMBER'];
1117         //Iterate over members
1118         for($i = 0; $i < sizeof($members); $i++) {
1119             $mem_info = $members[$i];
1120             //traverse_xmlize($mem_info);                                                                 //Debug
1121             //print_object ($GLOBALS['traverse_array']);                                                  //Debug
1122             //$GLOBALS['traverse_array']="";                                                              //Debug
1124             //Now, build the GROUPS_MEMBERS record structure
1125             $group_member->groupid = $group_id;
1126             $group_member->userid = backup_todb($mem_info['#']['USERID']['0']['#']);
1127             $group_member->timeadded = backup_todb($mem_info['#']['TIMEADDED']['0']['#']);
1129             //We have to recode the userid field
1130             $user = backup_getid($restore->backup_unique_code,"user",$group_member->userid);
1131             if ($user) {
1132                 $group_member->userid = $user->new_id;
1133             }
1135             //The structure is equal to the db, so insert the groups_members
1136             $newid = insert_record ("groups_members",$group_member);
1138             //Do some output
1139             if (($i+1) % 50 == 0) {
1140                 echo ".";
1141                 if (($i+1) % 1000 == 0) {
1142                     echo "<br>";
1143                 }
1144                 backup_flush(300);
1145             }
1146             
1147             if (!$newid) {
1148                 $status = false;
1149             }
1150         }
1152         return $status;
1153     }
1155     //This function creates all the course events
1156     function restore_create_events($restore,$xml_file) {
1158         global $CFG, $db;
1160         $status = true;
1161         //Check it exists
1162         if (!file_exists($xml_file)) {
1163             $status = false;
1164         }
1165         //Get info from xml
1166         if ($status) {
1167             //events will contain the old_id of every event
1168             //in backup_ids->info will be the real info (serialized)
1169             $events = restore_read_xml_events($restore,$xml_file);
1170         }
1171         //Now, if we have anything in events, we have to restore that
1172         //events
1173         if ($events) {
1174             if ($events !== true) {
1175                 //Iterate over each event
1176                 foreach ($events as $event) {
1177                     //Get record from backup_ids
1178                     $data = backup_getid($restore->backup_unique_code,"event",$event->id);
1179                     //Init variables
1180                     $create_event = false;
1182                     if ($data) {
1183                         //Now get completed xmlized object
1184                         $info = $data->info;
1185                         //traverse_xmlize($info);                                                                     //Debug
1186                         //print_object ($GLOBALS['traverse_array']);                                                  //Debug
1187                         //$GLOBALS['traverse_array']="";                                                              //Debug
1189                         //Now build the EVENT record structure
1190                         $eve->name = backup_todb($info['EVENT']['#']['NAME']['0']['#']);
1191                         $eve->description = backup_todb($info['EVENT']['#']['DESCRIPTION']['0']['#']);
1192                         $eve->format = backup_todb($info['EVENT']['#']['FORMAT']['0']['#']);
1193                         $eve->courseid = $restore->course_id;
1194                         $eve->groupid = backup_todb($info['EVENT']['#']['GROUPID']['0']['#']);
1195                         $eve->userid = backup_todb($info['EVENT']['#']['USERID']['0']['#']);
1196                         $eve->modulename = "";
1197                         $eve->instance = 0;
1198                         $eve->eventtype = backup_todb($info['EVENT']['#']['EVENTTYPE']['0']['#']);
1199                         $eve->timestart = backup_todb($info['EVENT']['#']['TIMESTART']['0']['#']);
1200                         $eve->timeduration = backup_todb($info['EVENT']['#']['TIMEDURATION']['0']['#']);
1201                         $eve->visible = backup_todb($info['EVENT']['#']['VISIBLE']['0']['#']);
1202                         $eve->timemodified = backup_todb($info['EVENT']['#']['TIMEMODIFIED']['0']['#']);
1204                         //Now search if that event exists (by description and timestart field) in
1205                         //restore->course_id course 
1206                         $eve_db = get_record("event","courseid",$eve->courseid,"description",$eve->description,"timestart",$eve->timestart);
1207                         //If it doesn't exist, create
1208                         if (!$eve_db) {
1209                             $create_event = true;
1210                         }
1211                         //If we must create the event
1212                         if ($create_event) {
1214                             //We must recode the userid
1215                             $user = backup_getid($restore->backup_unique_code,"user",$eve->userid);
1216                             if ($user) {
1217                                 $eve->userid = $user->new_id;
1218                             } else {
1219                                 //Assign it to admin
1220                                 $eve->userid = 1;
1221                             }
1222                             //We have to recode the groupid field
1223                             $group = backup_getid($restore->backup_unique_code,"group",$eve->groupid);
1224                             if ($group) {
1225                                 $eve->groupid = $group->new_id;
1226                             } else {
1227                                 //Assign it to group 0
1228                                 $eve->groupid = 0;
1229                             }
1231                             //The structure is equal to the db, so insert the event
1232                             $newid = insert_record ("event",$eve);
1233                         } else {
1234                             //get current event id
1235                             $newid = $eve_db->id;
1236                         }
1237                         if ($newid) {
1238                             //We have the newid, update backup_ids
1239                             backup_putid($restore->backup_unique_code,"event",
1240                                          $event->id, $newid);
1241                         }
1242                     }
1243                 }
1244             }
1245         } else {
1246             $status = false;
1247         } 
1248         return $status;
1249     }
1251     //This function decode things to make restore multi-site fully functional
1252     //It does this conversions:
1253     //    - $@FILEPHP@$ -------------------------------> $CFG->wwwroot/file.php/courseid
1254     //
1255     //Note: Inter-activities linking is being implemented as a final
1256     //step in the restore execution, because we need to have it 
1257     //finished to know all the oldid, newid equivaleces
1258     function restore_decode_absolute_links($content) {
1259                                      
1260         global $CFG,$restore;    
1262         //Now decode wwwroot and file.php calls
1263         $search = array ("$@FILEPHP@$");
1264         
1265         $replace = array ($CFG->wwwroot."/file.php/".$restore->course_id);
1266     
1267         $result = str_replace($search,$replace,$content);
1269         if ($result != $content && $CFG->debug>7) {                                  //Debug
1270             echo "<br><hr>".$content."<br>changed to<br>".$result."<hr><br>";        //Debug
1271         }                                                                            //Debug
1273         return $result;
1274     }
1276     //This function restores the userfiles from the temp (user_files) directory to the
1277     //dataroot/users directory
1278     function restore_user_files($restore) {
1280         global $CFG;
1282         $status = true;
1284         $counter = 0;
1286         //First, we check to "users" exists and create is as necessary
1287         //in CFG->dataroot
1288         $dest_dir = $CFG->dataroot."/users";
1289         $status = check_dir_exists($dest_dir,true);
1291         //Now, we iterate over "user_files" records to check if that user dir must be
1292         //copied (and renamed) to the "users" dir.
1293         $rootdir = $CFG->dataroot."/temp/backup/".$restore->backup_unique_code."/user_files";
1294         //Check if directory exists
1295         if (is_dir($rootdir)) {
1296             $list = list_directories ($rootdir);
1297             if ($list) {
1298                 //Iterate
1299                 $counter = 0;
1300                 foreach ($list as $dir) {
1301                     //Look for dir like username in backup_ids
1302                     $data = get_record ("backup_ids","backup_code",$restore->backup_unique_code,
1303                                                      "table_name","user",
1304                                                      "old_id",$dir);
1305                     //If thar user exists in backup_ids
1306                     if ($data) {
1307                         //Only it user has been created now
1308                         //or if it existed previously, but he hasn't image (see bug 1123)
1309                         if ((strpos($data->info,"new") !== false) or 
1310                             (!check_dir_exists($dest_dir."/".$data->new_id,false))) {
1311                             //Copy the old_dir to its new location (and name) !!
1312                             //Only if destination doesn't exists
1313                             if (!file_exists($dest_dir."/".$data->new_id)) {
1314                                 $status = backup_copy_file($rootdir."/".$dir,
1315                                               $dest_dir."/".$data->new_id);
1316                                 $counter ++;
1317                             }
1318                             //Do some output
1319                             if ($counter % 2 == 0) {
1320                                 echo ".";
1321                                 if ($counter % 40 == 0) {
1322                                 echo "<br>";
1323                                 }
1324                                 backup_flush(300);
1325                             }
1326                         }
1327                     }
1328                 }
1329             }
1330         }
1331         //If status is ok and whe have dirs created, returns counter to inform
1332         if ($status and $counter) {
1333             return $counter;
1334         } else {
1335             return $status;
1336         }
1337     }
1339     //This function restores the course files from the temp (course_files) directory to the
1340     //dataroot/course_id directory
1341     function restore_course_files($restore) {
1343         global $CFG;
1345         $status = true;
1346  
1347         $counter = 0;
1349         //First, we check to "course_id" exists and create is as necessary
1350         //in CFG->dataroot
1351         $dest_dir = $CFG->dataroot."/".$restore->course_id;
1352         $status = check_dir_exists($dest_dir,true);
1354         //Now, we iterate over "course_files" records to check if that file/dir must be
1355         //copied to the "dest_dir" dir.
1356         $rootdir = $CFG->dataroot."/temp/backup/".$restore->backup_unique_code."/course_files";
1357         //Check if directory exists
1358         if (is_dir($rootdir)) {
1359             $list = list_directories_and_files ($rootdir);
1360             if ($list) {
1361                 //Iterate
1362                 $counter = 0;
1363                 foreach ($list as $dir) {
1364                     //Copy the dir to its new location 
1365                     //Only if destination file/dir doesn exists
1366                     if (!file_exists($dest_dir."/".$dir)) {
1367                         $status = backup_copy_file($rootdir."/".$dir,
1368                                       $dest_dir."/".$dir);
1369                         $counter ++;
1370                     }
1371                     //Do some output
1372                     if ($counter % 2 == 0) {       
1373                         echo ".";
1374                         if ($counter % 40 == 0) {       
1375                         echo "<br>";
1376                         }
1377                         backup_flush(300);
1378                     }
1379                 }
1380             }
1381         }
1382         //If status is ok and whe have dirs created, returns counter to inform
1383         if ($status and $counter) {
1384             return $counter;
1385         } else {
1386             return $status;
1387         }
1388     }
1389    
1391     //This function creates all the structures for every module in backup file
1392     //Depending what has been selected.
1393     function restore_create_modules($restore,$xml_file) {
1395         global $CFG;
1397         $status = true;
1398         //Check it exists
1399         if (!file_exists($xml_file)) {
1400             $status = false;
1401         }
1402         //Get info from xml
1403         if ($status) {
1404             //info will contain the id and modtype of every module
1405             //in backup_ids->info will be the real info (serialized)
1406             $info = restore_read_xml_modules($restore,$xml_file);
1407         }
1409         //Now, if we have anything in info, we have to restore that mods
1410         //from backup_ids (calling every mod restore function)
1411         if ($info) {
1412             if ($info !== true) {
1413                 //Iterate over each module
1414                 foreach ($info as $mod) {
1415                     $modrestore = $mod->modtype."_restore_mods";
1416                     if (function_exists($modrestore)) {
1417                         //print_object ($mod);                                                //Debug
1418                         $status = $modrestore($mod,$restore);
1419                     } else {
1420                         //Something was wrong. Function should exist.
1421                         $status = false;
1422                     }
1423                 }
1424             }
1425         } else {
1426             $status = false;
1427         }
1428        return $status;
1429     }
1431     //This function creates all the structures for every log in backup file
1432     //Depending what has been selected.
1433     function restore_create_logs($restore,$xml_file) {
1434             
1435         global $CFG,$db;
1437         //Number of records to get in every chunk
1438         $recordset_size = 4;
1439         //Counter, points to current record
1440         $counter = 0;
1441         //To count all the recods to restore
1442         $count_logs = 0;
1443         
1444         $status = true;
1445         //Check it exists 
1446         if (!file_exists($xml_file)) { 
1447             $status = false;
1448         }
1449         //Get info from xml
1450         if ($status) {
1451             //count_logs will contain the number of logs entries to process
1452             //in backup_ids->info will be the real info (serialized)
1453             $count_logs = restore_read_xml_logs($restore,$xml_file);
1454         }
1455  
1456         //Now, if we have records in count_logs, we have to restore that logs
1457         //from backup_ids. This piece of code makes calls to:
1458         // - restore_log_course() if it's a course log
1459         // - restore_log_user() if it's a user log
1460         // - restore_log_module() if it's a module log.
1461         //And all is segmented in chunks to allow large recordsets to be restored !!
1462         if ($count_logs > 0) {
1463             while ($counter < $count_logs) {
1464                 //Get a chunk of records
1465                 //Take old_id twice to avoid adodb limitation
1466                 $logs = get_records_select("backup_ids","table_name = 'log' AND backup_code = '$restore->backup_unique_code'","old_id","old_id,old_id",$counter,$recordset_size);
1467                 //We have logs
1468                 if ($logs) {
1469                     //Iterate
1470                     foreach ($logs as $log) {
1471                         //Get the full record from backup_ids
1472                         $data = backup_getid($restore->backup_unique_code,"log",$log->old_id);
1473                         if ($data) {
1474                             //Now get completed xmlized object
1475                             $info = $data->info;
1476                             //traverse_xmlize($info);                                                                     //Debug
1477                             //print_object ($GLOBALS['traverse_array']);                                                  //Debug
1478                             //$GLOBALS['traverse_array']="";                                                              //Debug
1479                             //Now build the LOG record structure
1480                             $dblog->time = backup_todb($info['LOG']['#']['TIME']['0']['#']);
1481                             $dblog->userid = backup_todb($info['LOG']['#']['USERID']['0']['#']);
1482                             $dblog->ip = backup_todb($info['LOG']['#']['IP']['0']['#']);
1483                             $dblog->course = $restore->course_id;
1484                             $dblog->module = backup_todb($info['LOG']['#']['MODULE']['0']['#']);
1485                             $dblog->cmid = backup_todb($info['LOG']['#']['CMID']['0']['#']);
1486                             $dblog->action = backup_todb($info['LOG']['#']['ACTION']['0']['#']);
1487                             $dblog->url = backup_todb($info['LOG']['#']['URL']['0']['#']);
1488                             $dblog->info = backup_todb($info['LOG']['#']['INFO']['0']['#']);
1489                             //We have to recode the userid field
1490                             $user = backup_getid($restore->backup_unique_code,"user",$dblog->userid);
1491                             if ($user) {
1492                                 //echo "User ".$dblog->userid." to user ".$user->new_id."<br>";                             //Debug
1493                                 $dblog->userid = $user->new_id;
1494                             }
1495                             //We have to recode the cmid field (if module isn't "course" or "user")
1496                             if ($dblog->module != "course" and $dblog->module != "user") {
1497                                 $cm = backup_getid($restore->backup_unique_code,"course_modules",$dblog->cmid);
1498                                 if ($cm) {
1499                                     //echo "Module ".$dblog->cmid." to module ".$cm->new_id."<br>";                         //Debug
1500                                     $dblog->cmid = $cm->new_id;
1501                                 } else {
1502                                     $dblog->cmid = 0;
1503                                 }
1504                             }
1505                             //print_object ($dblog);                                                                        //Debug
1506                             //Now, we redirect to the needed function to make all the work
1507                             if ($dblog->module == "course") {
1508                                 //It's a course log,
1509                                 $stat = restore_log_course($restore,$dblog);
1510                             } elseif ($dblog->module == "user") {
1511                                 //It's a user log,
1512                                 $stat = restore_log_user($restore,$dblog);
1513                             } else {
1514                                 //It's a module log,
1515                                 $stat = restore_log_module($restore,$dblog);
1516                             }
1517                         }
1519                         //Do some output
1520                         $counter++;
1521                         if ($counter % 10 == 0) {
1522                             echo ".";
1523                             if ($counter % 200 == 0) {
1524                                 echo "<br>";
1525                             }
1526                             backup_flush(300);
1527                         }
1528                     }
1529                 } else {
1530                     //We never should arrive here
1531                     $counter = $count_logs;
1532                     $status = false;
1533                 }
1534             }
1535         }
1537         return $status;
1538     }
1540     //This function inserts a course log record, calculating the URL field as necessary
1541     function restore_log_course($restore,$log) {
1543         $status = true;
1544         $toinsert = false;
1546         //echo "<hr>Before transformations<br>";                                        //Debug
1547         //print_object($log);                                                           //Debug
1548         //Depending of the action, we recode different things
1549         switch ($log->action) {
1550         case "view":
1551             $log->url = "view.php?id=".$log->course;
1552             $log->info = $log->course;
1553             $toinsert = true;
1554             break;
1555         case "user report":
1556             //recode the info field (it's the user id)
1557             $user = backup_getid($restore->backup_unique_code,"user",$log->info);
1558             if ($user) {
1559                 $log->info = $user->new_id;
1560                 //Now, extract the mode from the url field
1561                 $mode = substr(strrchr($log->url,"="),1);
1562                 $log->url = "user.php?id=".$log->course."&user=".$log->info."&mode=".$mode;
1563                 $toinsert = true;
1564             }
1565             break;
1566         case "add mod":
1567             //Extract the course_module from the url field
1568             $cmid = substr(strrchr($log->url,"="),1);
1569             //recode the course_module to see it it has been restored
1570             $cm = backup_getid($restore->backup_unique_code,"course_modules",$cmid);
1571             if ($cm) {
1572                 $cmid = $cm->new_id;
1573                 //Extract the module name and the module id from the info field
1574                 $modname = strtok($log->info," ");
1575                 $modid = strtok(" ");
1576                 //recode the module id to see if it has been restored
1577                 $mod = backup_getid($restore->backup_unique_code,$modname,$modid);
1578                 if ($mod) {
1579                     $modid = $mod->new_id;
1580                     //Now I have everything so reconstruct url and info
1581                     $log->info = $modname." ".$modid;
1582                     $log->url = "../mod/".$modname."/view.php?id=".$cmid;
1583                     $toinsert = true;
1584                 }
1585             }
1586             break;
1587         case "update mod":
1588             //Extract the course_module from the url field
1589             $cmid = substr(strrchr($log->url,"="),1);
1590             //recode the course_module to see it it has been restored
1591             $cm = backup_getid($restore->backup_unique_code,"course_modules",$cmid);
1592             if ($cm) {
1593                 $cmid = $cm->new_id;
1594                 //Extract the module name and the module id from the info field
1595                 $modname = strtok($log->info," ");
1596                 $modid = strtok(" ");
1597                 //recode the module id to see if it has been restored
1598                 $mod = backup_getid($restore->backup_unique_code,$modname,$modid);
1599                 if ($mod) {
1600                     $modid = $mod->new_id;
1601                     //Now I have everything so reconstruct url and info
1602                     $log->info = $modname." ".$modid;
1603                     $log->url = "../mod/".$modname."/view.php?id=".$cmid;
1604                     $toinsert = true;
1605                 }
1606             }
1607             break;
1608         case "delete mod":
1609             $log->url = "view.php?id=".$log->course;
1610             $toinsert = true;
1611             break;
1612         case "update":
1613             $log->url = "edit.php?id=".$log->course;
1614             $log->info = "";
1615             $toinsert = true;
1616             break;
1617         case "unenrol":
1618             //recode the info field (it's the user id)
1619             $user = backup_getid($restore->backup_unique_code,"user",$log->info);
1620             if ($user) {
1621                 $log->info = $user->new_id;
1622                 $log->url = "view.php?id=".$log->course;
1623                 $toinsert = true;
1624             }
1625             break;
1626         case "enrol":
1627             //recode the info field (it's the user id)
1628             $user = backup_getid($restore->backup_unique_code,"user",$log->info);
1629             if ($user) {
1630                 $log->info = $user->new_id;
1631                 $log->url = "view.php?id=".$log->course;
1632                 $toinsert = true;
1633             }
1634             break;
1635         case "editsection":
1636             //Extract the course_section from the url field
1637             $secid = substr(strrchr($log->url,"="),1);
1638             //recode the course_section to see if it has been restored
1639             $sec = backup_getid($restore->backup_unique_code,"course_sections",$secid);
1640             if ($sec) {
1641                 $secid = $sec->new_id;
1642                 //Now I have everything so reconstruct url and info
1643                 $log->url = "editsection.php?id=".$secid;
1644                 $toinsert = true;
1645             }
1646             break;
1647         case "new":
1648             $log->url = "view.php?id=".$log->course;
1649             $log->info = "";
1650             $toinsert = true;
1651             break;
1652         default:
1653             echo "action (".$log->module."-".$log->action.") unknow. Not restored<br>";                 //Debug
1654             break;
1655         }
1657         //echo "After transformations<br>";                                             //Debug
1658         //print_object($log);                                                           //Debug
1660         //Now if $toinsert is set, insert the record
1661         if ($toinsert) {
1662             //echo "Inserting record<br>";                                              //Debug
1663             $status = insert_record("log",$log);
1664         }
1665         return $status;
1666     }
1668     //This function inserts a user log record, calculating the URL field as necessary
1669     function restore_log_user($restore,$log) {
1671         $status = true;
1672         $toinsert = false;
1673         
1674         //echo "<hr>Before transformations<br>";                                        //Debug
1675         //print_object($log);                                                           //Debug
1676         //Depending of the action, we recode different things                           
1677         switch ($log->action) {
1678         case "view":
1679             //recode the info field (it's the user id)
1680             $user = backup_getid($restore->backup_unique_code,"user",$log->info);
1681             if ($user) {
1682                 $log->info = $user->new_id;
1683                 $log->url = "view.php?id=".$log->info."&course=".$log->course;
1684                 $toinsert = true;
1685             }
1686             break;
1687         case "change password":
1688             //recode the info field (it's the user id)
1689             $user = backup_getid($restore->backup_unique_code,"user",$log->info);
1690             if ($user) {
1691                 $log->info = $user->new_id;
1692                 $log->url = "view.php?id=".$log->info."&course=".$log->course;
1693                 $toinsert = true;
1694             }
1695             break;
1696         case "view all":
1697             $log->url = "view.php?id=".$log->course;
1698             $log->info = "";
1699             $toinsert = true;
1700         case "update":
1701             //We split the url by ampersand char 
1702             $first_part = strtok($log->url,"&");
1703             //Get data after the = char. It's the user being updated
1704             $userid = substr(strrchr($first_part,"="),1);
1705             //Recode the user
1706             $user = backup_getid($restore->backup_unique_code,"user",$userid);
1707             if ($user) {
1708                 $log->info = "";
1709                 $log->url = "view.php?id=".$user->new_id."&course=".$log->course;
1710                 $toinsert = true;
1711             }
1712             break;
1713         default:
1714             echo "action (".$log->module."-".$log->action.") unknow. Not restored<br>";                 //Debug
1715             break;
1716         }
1718         //echo "After transformations<br>";                                             //Debug
1719         //print_object($log);                                                           //Debug
1721         //Now if $toinsert is set, insert the record
1722         if ($toinsert) {
1723             //echo "Inserting record<br>";                                              //Debug
1724             $status = insert_record("log",$log);
1725         }
1726         return $status;
1727     }
1729     //This function inserts a module log record, calculating the URL field as necessary
1730     function restore_log_module($restore,$log) {
1732         $status = true;
1733         $toinsert = false;
1735         //echo "<hr>Before transformations<br>";                                        //Debug
1736         //print_object($log);                                                           //Debug
1738         //Now we see if the required function in the module exists
1739         $function = $log->module."_restore_logs";
1740         if (function_exists($function)) {
1741             //Call the function
1742             $log = $function($restore,$log);
1743             //If everything is ok, mark the insert flag
1744             if ($log) {
1745                 $toinsert = true;
1746             }
1747         }
1749         //echo "After transformations<br>";                                             //Debug
1750         //print_object($log);                                                           //Debug
1752         //Now if $toinsert is set, insert the record
1753         if ($toinsert) {
1754             //echo "Inserting record<br>";                                              //Debug
1755             $status = insert_record("log",$log);
1756         }
1757         return $status;
1758     }
1760     //This function adjusts the instance field into course_modules. It's executed after
1761     //modules restore. There, we KNOW the new instance id !!
1762     function restore_check_instances($restore) {
1764         global $CFG;
1766         $status = true;
1768         //We are going to iterate over each course_module saved in backup_ids
1769         $course_modules = get_records_sql("SELECT old_id,new_id
1770                                            FROM {$CFG->prefix}backup_ids
1771                                            WHERE backup_code = '$restore->backup_unique_code' AND
1772                                                  table_name = 'course_modules'");
1773         if ($course_modules) {
1774             foreach($course_modules as $cm) {
1775                 //Get full record, using backup_getids
1776                 $cm_module = backup_getid($restore->backup_unique_code,"course_modules",$cm->old_id);
1777                 //Now we are going to the REAL course_modules to get its type (field module)
1778                 $module = get_record("course_modules","id",$cm_module->new_id);
1779                 if ($module) {
1780                     //We know the module type id. Get the name from modules
1781                     $type = get_record("modules","id",$module->module);
1782                     if ($type) {
1783                         //We know the type name and the old_id. Get its new_id
1784                         //from backup_ids. It's the instance !!!
1785                         $instance =  backup_getid($restore->backup_unique_code,$type->name,$cm_module->info);
1786                         if ($instance) {
1787                             //We have the new instance, so update the record in course_modules
1788                             $module->instance = $instance->new_id;
1789                             //print_object ($module);                                                   //Debug
1790                             $status = update_record("course_modules",$module);
1791                         } else {
1792                             $status = false;
1793                         }
1794                     } else {
1795                         $status = false;
1796                     }
1797                 } else {
1798                     $status = false;
1799                }
1800             }
1801         }
1804         return $status;
1805     }
1807     //=====================================================================================
1808     //==                                                                                 ==
1809     //==                         XML Functions (SAX)                                     ==
1810     //==                                                                                 ==
1811     //=====================================================================================
1813     //This is the class used to do all the xml parse
1814     class MoodleParser {
1816         var $level = 0;        //Level we are
1817         var $counter = 0;      //Counter
1818         var $tree = array();   //Array of levels we are
1819         var $content = "";     //Content under current level
1820         var $todo = "";        //What we hav to do when parsing
1821         var $info = "";        //Information collected. Temp storage. Used to return data after parsing.
1822         var $temp = "";        //Temp storage.
1823         var $preferences = ""; //Preferences about what to load !!
1824         var $finished = false; //Flag to say xml_parse to stop
1826         //This function is used to get the current contents property value
1827         //They are trimed and converted from utf8
1828         function getContents() {
1829             return trim(utf8_decode($this->content));
1830         }
1831  
1832         //This is the startTag handler we use where we are reading the info zone (todo="INFO")
1833         function startElementInfo($parser, $tagName, $attrs) {
1834             //Refresh properties
1835             $this->level++;
1836             $this->tree[$this->level] = $tagName;
1838             //Output something to avoid browser timeouts...
1839             backup_flush();
1841             //Check if we are into INFO zone
1842             //if ($this->tree[2] == "INFO")                                                             //Debug
1843             //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br>\n";   //Debug
1844         }
1846         //This is the startTag handler we use where we are reading the course header zone (todo="COURSE_HEADER")
1847         function startElementCourseHeader($parser, $tagName, $attrs) {
1848             //Refresh properties
1849             $this->level++;
1850             $this->tree[$this->level] = $tagName;
1852             //Output something to avoid browser timeouts...
1853             backup_flush();
1855             //Check if we are into COURSE_HEADER zone
1856             //if ($this->tree[3] == "HEADER")                                                           //Debug
1857             //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br>\n";   //Debug
1858         }
1860         //This is the startTag handler we use where we are reading the sections zone (todo="SECTIONS")
1861         function startElementSections($parser, $tagName, $attrs) {
1862             //Refresh properties     
1863             $this->level++;
1864             $this->tree[$this->level] = $tagName;   
1866             //Output something to avoid browser timeouts...
1867             backup_flush();
1869             //Check if we are into SECTIONS zone
1870             //if ($this->tree[3] == "SECTIONS")                                                         //Debug
1871             //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br>\n";   //Debug
1872         }
1873         
1874         //This is the startTag handler we use where we are reading the user zone (todo="USERS")
1875         function startElementUsers($parser, $tagName, $attrs) {
1876             //Refresh properties     
1877             $this->level++;
1878             $this->tree[$this->level] = $tagName;   
1880             //Check if we are into USERS zone  
1881             //if ($this->tree[3] == "USERS")                                                            //Debug
1882             //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br>\n";   //Debug
1883         }
1885         //This is the startTag handler we use where we are reading the questions zone (todo="QUESTIONS")
1886         function startElementQuestions($parser, $tagName, $attrs) {
1887             //Refresh properties
1888             $this->level++;
1889             $this->tree[$this->level] = $tagName;
1891             //if ($tagName == "QUESTION_CATEGORY" && $this->tree[3] == "QUESTION_CATEGORIES") {        //Debug
1892             //    echo "<P>QUESTION_CATEGORY: ".strftime ("%X",time()),"-";                            //Debug
1893             //}                                                                                        //Debug
1895             //Output something to avoid browser timeouts...
1896             backup_flush();
1898             //Check if we are into QUESTION_CATEGORIES zone
1899             //if ($this->tree[3] == "QUESTION_CATEGORIES")                                              //Debug
1900             //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br>\n";   //Debug
1902             //If we are under a QUESTION_CATEGORY tag under a QUESTION_CATEGORIES zone, accumule it
1903             if (isset($this->tree[4]) and isset($this->tree[3])) {
1904                 if (($this->tree[4] == "QUESTION_CATEGORY") and ($this->tree[3] == "QUESTION_CATEGORIES")) {
1905                     if (!isset($this->temp)) {
1906                         $this->temp = "";
1907                     }
1908                     $this->temp .= "<".$tagName.">";
1909                 }
1910             }
1911         }
1913         //This is the startTag handler we use where we are reading the scales zone (todo="SCALES")
1914         function startElementScales($parser, $tagName, $attrs) {
1915             //Refresh properties          
1916             $this->level++;
1917             $this->tree[$this->level] = $tagName;
1919             //if ($tagName == "SCALE" && $this->tree[3] == "SCALES") {                                 //Debug
1920             //    echo "<P>SCALE: ".strftime ("%X",time()),"-";                                        //Debug
1921             //}                                                                                        //Debug
1923             //Output something to avoid browser timeouts...
1924             backup_flush();
1926             //Check if we are into SCALES zone
1927             //if ($this->tree[3] == "SCALES")                                                           //Debug
1928             //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br>\n";   //Debug
1930             //If we are under a SCALE tag under a SCALES zone, accumule it
1931             if (isset($this->tree[4]) and isset($this->tree[3])) {
1932                 if (($this->tree[4] == "SCALE") and ($this->tree[3] == "SCALES")) {
1933                     if (!isset($this->temp)) {
1934                         $this->temp = "";
1935                     }
1936                     $this->temp .= "<".$tagName.">";
1937                 }
1938             }
1939         }
1941         function startElementGroups($parser, $tagName, $attrs) {
1942             //Refresh properties
1943             $this->level++;
1944             $this->tree[$this->level] = $tagName;
1946             //if ($tagName == "GROUP" && $this->tree[3] == "GROUPS") {                                 //Debug
1947             //    echo "<P>GROUP: ".strftime ("%X",time()),"-";                                        //Debug
1948             //}                                                                                        //Debug
1950             //Output something to avoid browser timeouts...
1951             backup_flush();
1953             //Check if we are into GROUPS zone
1954             //if ($this->tree[3] == "GROUPS")                                                           //Debug
1955             //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br>\n";   //Debug
1957             //If we are under a GROUP tag under a GROUPS zone, accumule it
1958             if (isset($this->tree[4]) and isset($this->tree[3])) {
1959                 if (($this->tree[4] == "GROUP") and ($this->tree[3] == "GROUPS")) {
1960                     if (!isset($this->temp)) {
1961                         $this->temp = "";
1962                     }
1963                     $this->temp .= "<".$tagName.">";
1964                 }
1965             }
1966         }
1968         //This is the startTag handler we use where we are reading the events zone (todo="EVENTS")
1969         function startElementEvents($parser, $tagName, $attrs) {
1970             //Refresh properties
1971             $this->level++;
1972             $this->tree[$this->level] = $tagName;
1974             //if ($tagName == "EVENT" && $this->tree[3] == "EVENTS") {                                 //Debug
1975             //    echo "<P>EVENT: ".strftime ("%X",time()),"-";                                        //Debug
1976             //}                                                                                        //Debug
1978             //Output something to avoid browser timeouts...
1979             backup_flush();
1981             //Check if we are into EVENTS zone
1982             //if ($this->tree[3] == "EVENTS")                                                           //Debug
1983             //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br>\n";   //Debug
1985             //If we are under a EVENT tag under a EVENTS zone, accumule it
1986             if (isset($this->tree[4]) and isset($this->tree[3])) {
1987                 if (($this->tree[4] == "EVENT") and ($this->tree[3] == "EVENTS")) {
1988                     if (!isset($this->temp)) {
1989                         $this->temp = "";
1990                     }
1991                     $this->temp .= "<".$tagName.">";
1992                 }
1993             }
1994         }
1996         //This is the startTag handler we use where we are reading the modules zone (todo="MODULES")
1997         function startElementModules($parser, $tagName, $attrs) {
1998             //Refresh properties
1999             $this->level++;
2000             $this->tree[$this->level] = $tagName;
2002             //if ($tagName == "MOD" && $this->tree[3] == "MODULES") {                                     //Debug
2003             //    echo "<P>MOD: ".strftime ("%X",time()),"-";                                             //Debug
2004             //}                                                                                           //Debug
2006             //Output something to avoid browser timeouts...
2007             backup_flush();
2009             //Check if we are into MODULES zone
2010             //if ($this->tree[3] == "MODULES")                                                          //Debug
2011             //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br>\n";   //Debug
2013             //If we are under a MOD tag under a MODULES zone, accumule it
2014             if (isset($this->tree[4]) and isset($this->tree[3])) {
2015                 if (($this->tree[4] == "MOD") and ($this->tree[3] == "MODULES")) {
2016                     if (!isset($this->temp)) {
2017                         $this->temp = "";
2018                     }
2019                     $this->temp .= "<".$tagName.">";
2020                 }
2021             }
2022         }
2024         //This is the startTag handler we use where we are reading the logs zone (todo="LOGS")
2025         function startElementLogs($parser, $tagName, $attrs) {
2026             //Refresh properties
2027             $this->level++;
2028             $this->tree[$this->level] = $tagName;
2030             //if ($tagName == "LOG" && $this->tree[3] == "LOGS") {                                        //Debug
2031             //    echo "<P>LOG: ".strftime ("%X",time()),"-";                                             //Debug
2032             //}                                                                                           //Debug
2034             //Output something to avoid browser timeouts...
2035             backup_flush();
2037             //Check if we are into LOGS zone
2038             //if ($this->tree[3] == "LOGS")                                                             //Debug
2039             //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br>\n";   //Debug
2041             //If we are under a LOG tag under a LOGS zone, accumule it
2042             if (isset($this->tree[4]) and isset($this->tree[3])) {
2043                 if (($this->tree[4] == "LOG") and ($this->tree[3] == "LOGS")) {
2044                     if (!isset($this->temp)) {
2045                         $this->temp = "";
2046                     }
2047                     $this->temp .= "<".$tagName.">";
2048                 }
2049             }
2050         }
2052         //This is the startTag default handler we use when todo is undefined
2053         function startElement($parser, $tagName, $attrs) {
2054             $this->level++;
2055             $this->tree[$this->level] = $tagName;
2057             //Output something to avoid browser timeouts...
2058             backup_flush();
2060             echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br>\n";   //Debug
2061         }
2062  
2063         //This is the endTag handler we use where we are reading the info zone (todo="INFO")
2064         function endElementInfo($parser, $tagName) {
2065             //Check if we are into INFO zone
2066             if ($this->tree[2] == "INFO") {
2067                 //if (trim($this->content))                                                                     //Debug
2068                 //    echo "C".str_repeat("&nbsp;",($this->level+2)*2).$this->getContents()."<br>\n";           //Debug
2069                 //echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;/".$tagName."&gt;<br>\n";          //Debug
2070                 //Dependig of different combinations, do different things
2071                 if ($this->level == 3) {
2072                     switch ($tagName) {
2073                         case "NAME":
2074                             $this->info->backup_name = $this->getContents();
2075                             break;
2076                         case "MOODLE_VERSION":
2077                             $this->info->backup_moodle_version = $this->getContents();
2078                             break;
2079                         case "MOODLE_RELEASE":
2080                             $this->info->backup_moodle_release = $this->getContents();
2081                             break;
2082                         case "BACKUP_VERSION":
2083                             $this->info->backup_backup_version = $this->getContents();
2084                             break;
2085                         case "BACKUP_RELEASE":
2086                             $this->info->backup_backup_release = $this->getContents();
2087                             break;
2088                         case "DATE":
2089                             $this->info->backup_date = $this->getContents();
2090                             break;
2091                         case "ORIGINAL_WWWROOT":
2092                             $this->info->original_wwwroot = $this->getContents();
2093                             break;
2094                     }
2095                 }
2096                 if ($this->tree[3] == "DETAILS") {
2097                     if ($this->level == 4) {
2098                         switch ($tagName) {
2099                             case "USERS":
2100                                 $this->info->backup_users = $this->getContents();
2101                                 break;
2102                             case "LOGS":
2103                                 $this->info->backup_logs = $this->getContents();
2104                                 break;
2105                             case "USERFILES":
2106                                 $this->info->backup_user_files = $this->getContents();
2107                                 break;
2108                             case "COURSEFILES":
2109                                 $this->info->backup_course_files = $this->getContents();
2110                                 break;
2111                         }
2112                     }
2113                     if ($this->level == 5) {
2114                         switch ($tagName) {
2115                             case "NAME":
2116                                 $this->info->tempName = $this->getContents();
2117                                 break;
2118                             case "INCLUDED":
2119                                 $this->info->mods[$this->info->tempName]->backup = $this->getContents();
2120                                 break;
2121                             case "USERINFO":
2122                                 $this->info->mods[$this->info->tempName]->userinfo = $this->getContents();
2123                                 break;
2124                         }
2125                     }
2126                 }
2127             }
2130             //Clear things
2131             $this->tree[$this->level] = "";
2132             $this->level--;
2133             $this->content = "";
2135             //Stop parsing if todo = INFO and tagName = INFO (en of the tag, of course)
2136             //Speed up a lot (avoid parse all)
2137             if ($tagName == "INFO") {
2138                 $this->finished = true;
2139             }
2140         }
2142         //This is the endTag handler we use where we are reading the course_header zone (todo="COURSE_HEADER")
2143         function endElementCourseHeader($parser, $tagName) {
2144             //Check if we are into COURSE_HEADER zone
2145             if ($this->tree[3] == "HEADER") {
2146                 //if (trim($this->content))                                                                     //Debug
2147                 //    echo "C".str_repeat("&nbsp;",($this->level+2)*2).$this->getContents()."<br>\n";           //Debug
2148                 //echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;/".$tagName."&gt;<br>\n";          //Debug
2149                 //Dependig of different combinations, do different things
2150                 if ($this->level == 4) {
2151                     switch ($tagName) {
2152                         case "ID":
2153                             $this->info->course_id = $this->getContents();
2154                             break;
2155                         case "PASSWORD":
2156                             $this->info->course_password = $this->getContents();
2157                             break;
2158                         case "FULLNAME":
2159                             $this->info->course_fullname = $this->getContents();
2160                             break;
2161                         case "SHORTNAME":
2162                             $this->info->course_shortname = $this->getContents();
2163                             break;
2164                         case "IDNUMBER":
2165                             $this->info->course_idnumber = $this->getContents();
2166                             break;
2167                         case "SUMMARY":
2168                             $this->info->course_summary = $this->getContents();
2169                             break;
2170                         case "FORMAT":
2171                             $this->info->course_format = $this->getContents();
2172                             break;
2173                         case "SHOWGRADES":
2174                             $this->info->course_showgrades = $this->getContents();
2175                             break;
2176                         case "BLOCKINFO":
2177                             $this->info->blockinfo = $this->getContents();
2178                             break;
2179                         case "NEWSITEMS":
2180                             $this->info->course_newsitems = $this->getContents();
2181                             break;
2182                         case "TEACHER":
2183                             $this->info->course_teacher = $this->getContents();
2184                             break;
2185                         case "TEACHERS":
2186                             $this->info->course_teachers = $this->getContents();
2187                             break;
2188                         case "STUDENT":
2189                             $this->info->course_student = $this->getContents();
2190                             break;
2191                         case "STUDENTS":
2192                             $this->info->course_students = $this->getContents();
2193                             break;
2194                         case "GUEST":
2195                             $this->info->course_guest = $this->getContents();
2196                             break;
2197                         case "STARTDATE":
2198                             $this->info->course_startdate = $this->getContents();
2199                             break;
2200                         case "NUMSECTIONS":
2201                             $this->info->course_numsections = $this->getContents();
2202                             break;
2203                         //case "SHOWRECENT":                                          INFO: This is out in 1.3
2204                         //    $this->info->course_showrecent = $this->getContents();
2205                         //    break;
2206                         case "MAXBYTES":
2207                             $this->info->course_maxbytes = $this->getContents();
2208                             break;
2209                         case "SHOWREPORTS":
2210                             $this->info->course_showreports = $this->getContents();
2211                             break;
2212                         case "GROUPMODE":
2213                             $this->info->course_groupmode = $this->getContents();
2214                             break;
2215                         case "GROUPMODEFORCE":
2216                             $this->info->course_groupmodeforce = $this->getContents();
2217                             break;
2218                         case "LANG":
2219                             $this->info->course_lang = $this->getContents();
2220                             break;
2221                         case "MARKER":
2222                             $this->info->course_marker = $this->getContents();
2223                             break;
2224                         case "VISIBLE":
2225                             $this->info->course_visible = $this->getContents();
2226                             break;
2227                         case "HIDDENSECTIONS":
2228                             $this->info->course_hiddensections = $this->getContents();
2229                             break;
2230                         case "TIMECREATED":
2231                             $this->info->course_timecreated = $this->getContents();
2232                             break;
2233                         case "TIMEMODIFIED":
2234                             $this->info->course_timemodified = $this->getContents();
2235                             break;
2236                     }
2237                 }
2238                 if ($this->tree[4] == "CATEGORY") {
2239                     if ($this->level == 5) {
2240                         switch ($tagName) {
2241                             case "ID":
2242                                 $this->info->category->id = $this->getContents();
2243                                 break;
2244                             case "NAME":
2245                                 $this->info->category->name = $this->getContents();
2246                                 break;
2247                         }
2248                     }
2249                 }
2251             }
2252             //Clear things
2253             $this->tree[$this->level] = "";
2254             $this->level--;
2255             $this->content = "";
2257             //Stop parsing if todo = COURSE_HEADER and tagName = HEADER (en of the tag, of course)
2258             //Speed up a lot (avoid parse all)
2259             if ($tagName == "HEADER") {
2260                 $this->finished = true;
2261             }
2262         }
2264         //This is the endTag handler we use where we are reading the sections zone (todo="SECTIONS")
2265         function endElementSections($parser, $tagName) {
2266             //Check if we are into SECTIONS zone
2267             if ($this->tree[3] == "SECTIONS") {
2268                 //if (trim($this->content))                                                                     //Debug
2269                 //    echo "C".str_repeat("&nbsp;",($this->level+2)*2).$this->getContents()."<br>\n";           //Debug
2270                 //echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;/".$tagName."&gt;<br>\n";          //Debug
2271                 //Dependig of different combinations, do different things
2272                 if ($this->level == 4) {
2273                     switch ($tagName) {
2274                         case "SECTION":
2275                             //We've finalized a section, get it
2276                             $this->info->sections[$this->info->tempsection->id] = $this->info->tempsection;
2277                             unset($this->info->tempsection);
2278                     }
2279                 }
2280                 if ($this->level == 5) {
2281                     switch ($tagName) {
2282                         case "ID":
2283                             $this->info->tempsection->id = $this->getContents();
2284                             break;
2285                         case "NUMBER":
2286                             $this->info->tempsection->number = $this->getContents();
2287                             break;
2288                         case "SUMMARY":
2289                             $this->info->tempsection->summary = $this->getContents();
2290                             break;
2291                         case "VISIBLE":
2292                             $this->info->tempsection->visible = $this->getContents();
2293                             break;
2294                     }
2295                 }
2296                 if ($this->level == 6) {
2297                     switch ($tagName) {
2298                         case "MOD":
2299                             //We've finalized a mod, get it
2300                             $this->info->tempsection->mods[$this->info->tempmod->id]->type = 
2301                                 $this->info->tempmod->type;
2302                             $this->info->tempsection->mods[$this->info->tempmod->id]->instance = 
2303                                 $this->info->tempmod->instance;
2304                             $this->info->tempsection->mods[$this->info->tempmod->id]->added = 
2305                                 $this->info->tempmod->added;
2306                             $this->info->tempsection->mods[$this->info->tempmod->id]->deleted = 
2307                                 $this->info->tempmod->deleted;
2308                             $this->info->tempsection->mods[$this->info->tempmod->id]->score = 
2309                                 $this->info->tempmod->score;
2310                             $this->info->tempsection->mods[$this->info->tempmod->id]->indent = 
2311                                 $this->info->tempmod->indent;
2312                             $this->info->tempsection->mods[$this->info->tempmod->id]->visible = 
2313                                 $this->info->tempmod->visible;
2314                             $this->info->tempsection->mods[$this->info->tempmod->id]->groupmode = 
2315                                 $this->info->tempmod->groupmode;
2316                             unset($this->info->tempmod);
2317                     }
2318                 }
2319                 if ($this->level == 7) {
2320                     switch ($tagName) {
2321                         case "ID":
2322                             $this->info->tempmod->id = $this->getContents();
2323                             break;
2324                         case "TYPE":
2325                             $this->info->tempmod->type = $this->getContents();
2326                             break;
2327                         case "INSTANCE":
2328                             $this->info->tempmod->instance = $this->getContents();
2329                             break;
2330                         case "ADDED":
2331                             $this->info->tempmod->added = $this->getContents();
2332                             break;
2333                         case "DELETED":
2334                             $this->info->tempmod->deleted = $this->getContents();
2335                             break;
2336                         case "SCORE":
2337                             $this->info->tempmod->score = $this->getContents();
2338                             break;
2339                         case "INDENT":
2340                             $this->info->tempmod->indent = $this->getContents();
2341                             break;
2342                         case "VISIBLE":
2343                             $this->info->tempmod->visible = $this->getContents();
2344                             break;
2345                         case "GROUPMODE":
2346                             $this->info->tempmod->groupmode = $this->getContents();
2347                             break;
2348                     }
2349                 }
2350             }
2351             //Clear things
2352             $this->tree[$this->level] = "";
2353             $this->level--;
2354             $this->content = "";
2356             //Stop parsing if todo = SECTIONS and tagName = SECTIONS (en of the tag, of course)
2357             //Speed up a lot (avoid parse all)
2358             if ($tagName == "SECTIONS") {
2359                 $this->finished = true;
2360             }
2361         }
2362         
2363         //This is the endTag handler we use where we are reading the users zone (todo="USERS")
2364         function endElementUsers($parser, $tagName) {
2365             //Check if we are into USERS zone
2366             if ($this->tree[3] == "USERS") {
2367                 //if (trim($this->content))                                                                     //Debug
2368                 //    echo "C".str_repeat("&nbsp;",($this->level+2)*2).$this->getContents()."<br>\n";           //Debug
2369                 //echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;/".$tagName."&gt;<br>\n";          //Debug
2370                 //Dependig of different combinations, do different things
2371                 if ($this->level == 4) {
2372                     switch ($tagName) {
2373                         case "USER":
2374                             //Increment counter
2375                             $this->counter++;
2376                             //Save to db
2377                             backup_putid($this->preferences->backup_unique_code,"user",$this->info->tempuser->id,
2378                                           null,$this->info->tempuser);
2380                             //Do some output   
2381                             if ($this->counter % 10 == 0) {
2382                                 echo ".";
2383                                 if ($this->counter % 200 == 0) {
2384                                 echo "<br>";
2385                                 }
2386                                 backup_flush(300);
2387                             }
2389                             //Delete temp obejct
2390                             unset($this->info->tempuser);
2391                             break;
2392                     }
2393                 }
2394                 if ($this->level == 5) {
2395                     switch ($tagName) {
2396                         case "ID": 
2397                             $this->info->users[$this->getContents()] = $this->getContents();
2398                             $this->info->tempuser->id = $this->getContents();
2399                             break;
2400                         case "CONFIRMED": 
2401                             $this->info->tempuser->confirmed = $this->getContents();
2402                             break;
2403                         case "DELETED": 
2404                             $this->info->tempuser->deleted = $this->getContents();
2405                             break;
2406                         case "USERNAME": 
2407                             $this->info->tempuser->username = $this->getContents();
2408                             break;
2409                         case "PASSWORD": 
2410                             $this->info->tempuser->password = $this->getContents();
2411                             break;
2412                         case "IDNUMBER": 
2413                             $this->info->tempuser->idnumber = $this->getContents();
2414                             break;
2415                         case "FIRSTNAME": 
2416                             $this->info->tempuser->firstname = $this->getContents();
2417                             break;
2418                         case "LASTNAME": 
2419                             $this->info->tempuser->lastname = $this->getContents();
2420                             break;
2421                         case "EMAIL": 
2422                             $this->info->tempuser->email = $this->getContents();
2423                             break;
2424                         case "EMAILSTOP": 
2425                             $this->info->tempuser->emailstop = $this->getContents();
2426                             break;
2427                         case "ICQ": 
2428                             $this->info->tempuser->icq = $this->getContents();
2429                             break;
2430                         case "PHONE1": 
2431                             $this->info->tempuser->phone1 = $this->getContents();
2432                             break;
2433                         case "PHONE2": 
2434                             $this->info->tempuser->phone2 = $this->getContents();
2435                             break;
2436                         case "INSTITUTION": 
2437                             $this->info->tempuser->institution = $this->getContents();
2438                             break;
2439                         case "DEPARTMENT": 
2440                             $this->info->tempuser->department = $this->getContents();
2441                             break;
2442                         case "ADDRESS": 
2443                             $this->info->tempuser->address = $this->getContents();
2444                             break;
2445                         case "CITY": 
2446                             $this->info->tempuser->city = $this->getContents();
2447                             break;
2448                         case "COUNTRY": 
2449                             $this->info->tempuser->country = $this->getContents();
2450                             break;
2451                         case "LANG": 
2452                             $this->info->tempuser->lang = $this->getContents();
2453                             break;
2454                         case "TIMEZONE": 
2455                             $this->info->tempuser->timezone = $this->getContents();
2456                             break;
2457                         case "FIRSTACCESS": 
2458                             $this->info->tempuser->firstaccess = $this->getContents();
2459                             break;
2460                         case "LASTACCESS": 
2461                             $this->info->tempuser->lastaccess = $this->getContents();
2462                             break;
2463                         case "LASTLOGIN": 
2464                             $this->info->tempuser->lastlogin = $this->getContents();
2465                             break;
2466                         case "CURRENTLOGIN": 
2467                             $this->info->tempuser->currentlogin = $this->getContents();
2468                             break;
2469                         case "LASTIP": 
2470                             $this->info->tempuser->lastip = $this->getContents();
2471                             break;
2472                         case "SECRET": 
2473                             $this->info->tempuser->secret = $this->getContents();
2474                             break;
2475                         case "PICTURE": 
2476                             $this->info->tempuser->picture = $this->getContents();
2477                             break;
2478                         case "URL": 
2479                             $this->info->tempuser->url = $this->getContents();
2480                             break;
2481                         case "DESCRIPTION": 
2482                             $this->info->tempuser->description = $this->getContents();
2483                             break;
2484                         case "MAILFORMAT": 
2485                             $this->info->tempuser->mailformat = $this->getContents();
2486                             break;
2487                         case "MAILDISPLAY": 
2488                             $this->info->tempuser->maildisplay = $this->getContents();
2489                             break;
2490                         case "HTMLEDITOR": 
2491                             $this->info->tempuser->htmleditor = $this->getContents();
2492                             break;
2493                         case "AUTOSUBSCRIBE": 
2494                             $this->info->tempuser->autosubscribe = $this->getContents();
2495                             break;
2496                         case "TIMEMODIFIED": 
2497                             $this->info->tempuser->timemodified = $this->getContents();
2498                             break;
2499                     }
2500                 }
2501                 if ($this->level == 6) {
2502                     switch ($tagName) {
2503                         case "ROLE":
2504                             //We've finalized a role, get it
2505                             $this->info->tempuser->roles[$this->info->temprole->type] = $this->info->temprole;
2506                             unset($this->info->temprole);
2507                             break;
2508                         case "USER_PREFERENCE":
2509                             //We've finalized a user_preference, get it
2510                             $this->info->tempuser->user_preferences[$this->info->tempuserpreference->name] = $this->info->tempuserpreference;
2511                             unset($this->info->tempuserpreference);
2512                             break;
2513                     }
2514                 }
2515                 if ($this->level == 7) {
2516                     switch ($tagName) {
2517                         case "TYPE":
2518                             $this->info->temprole->type = $this->getContents();
2519                             break;
2520                         case "AUTHORITY":
2521                             $this->info->temprole->authority = $this->getContents();
2522                             break;
2523                         case "TEA_ROLE":
2524                             $this->info->temprole->tea_role = $this->getContents();
2525                             break;
2526                         case "EDITALL":
2527                             $this->info->temprole->editall = $this->getContents();
2528                             break;
2529                         case "TIMESTART":
2530                             $this->info->temprole->timestart = $this->getContents();
2531                             break;
2532                         case "TIMEEND":
2533                             $this->info->temprole->timeend = $this->getContents();
2534                             break;
2535                         case "TIMEMODIFIED":
2536                             $this->info->temprole->timemodified = $this->getContents();
2537                             break;
2538                         case "TIMESTART":
2539                             $this->info->temprole->timestart = $this->getContents();
2540                             break;
2541                         case "TIMEEND":
2542                             $this->info->temprole->timeend = $this->getContents();
2543                             break;
2544                         case "TIME":
2545                             $this->info->temprole->time = $this->getContents();
2546                             break;
2547                         case "TIMEACCESS":
2548                             $this->info->temprole->timeaccess = $this->getContents();
2549                             break;
2550                         case "NAME":
2551                             $this->info->tempuserpreference->name = $this->getContents();
2552                             break;
2553                         case "VALUE":
2554                             $this->info->tempuserpreference->value = $this->getContents();
2555                             break;
2556                     }
2557                 }
2558             }
2560             //Stop parsing if todo = USERS and tagName = USERS (en of the tag, of course)
2561             //Speed up a lot (avoid parse all)
2562             if ($tagName == "USERS" and $this->level == 3) {
2563                 $this->finished = true;
2564                 $this->counter = 0;
2565             }
2567             //Clear things
2568             $this->tree[$this->level] = "";
2569             $this->level--;
2570             $this->content = "";
2571         }
2573         //This is the endTag handler we use where we are reading the questions zone (todo="QUESTIONS")  
2574         function endElementQuestions($parser, $tagName) {
2575             //Check if we are into QUESTION_CATEGORIES zone
2576             if ($this->tree[3] == "QUESTION_CATEGORIES") {
2577                 //if (trim($this->content))                                                                     //Debug
2578                 //    echo "C".str_repeat("&nbsp;",($this->level+2)*2).$this->getContents()."<br>\n";           //Debug
2579                 //echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;/".$tagName."&gt;<br>\n";          //Debug
2580                 //Acumulate data to info (content + close tag)
2581                 //Reconvert: strip htmlchars again and trim to generate xml data
2582                 if (!isset($this->temp)) {
2583                     $this->temp = "";
2584                 }
2585                 $this->temp .= htmlspecialchars(trim($this->content))."</".$tagName.">";
2586                 //If we've finished a mod, xmlize it an save to db
2587                 if (($this->level == 4) and ($tagName == "QUESTION_CATEGORY")) {
2588                     //Prepend XML standard header to info gathered
2589                     $xml_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".$this->temp;
2590                     //Call to xmlize for this portion of xml data (one QUESTION_CATEGORY)
2591                     //echo "-XMLIZE: ".strftime ("%X",time()),"-";                                                //Debug
2592                     $data = xmlize($xml_data,0);
2593                     //echo strftime ("%X",time())."<p>";                                                          //Debug
2594                     //traverse_xmlize($data);                                                                     //Debug
2595                     //print_object ($GLOBALS['traverse_array']);                                                  //Debug
2596                     //$GLOBALS['traverse_array']="";                                                              //Debug
2597                     //Now, save data to db. We'll use it later
2598                     //Get id from data
2599                     $category_id = $data["QUESTION_CATEGORY"]["#"]["ID"]["0"]["#"];
2600                     //Save to db
2601                     $status = backup_putid($this->preferences->backup_unique_code,"quiz_categories",$category_id,
2602                                      null,$data);
2603                     //Create returning info
2604                     $ret_info->id = $category_id;
2605                     $this->info[] = $ret_info;
2606                     //Reset temp
2607                     unset($this->temp);
2608                 }
2609             }
2611             //Stop parsing if todo = QUESTION_CATEGORIES and tagName = QUESTION_CATEGORY (en of the tag, of course)
2612             //Speed up a lot (avoid parse all)
2613             if ($tagName == "QUESTION_CATEGORIES" and $this->level == 3) {
2614                 $this->finished = true;
2615             }
2617             //Clear things
2618             $this->tree[$this->level] = "";
2619             $this->level--;
2620             $this->content = "";
2621         }
2623         //This is the endTag handler we use where we are reading the scales zone (todo="SCALES")
2624         function endElementScales($parser, $tagName) {
2625             //Check if we are into SCALES zone
2626             if ($this->tree[3] == "SCALES") {
2627                 //if (trim($this->content))                                                                     //Debug
2628                 //    echo "C".str_repeat("&nbsp;",($this->level+2)*2).$this->getContents()."<br>\n";           //Debug
2629                 //echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;/".$tagName."&gt;<br>\n";          //Debug
2630                 //Acumulate data to info (content + close tag)
2631                 //Reconvert: strip htmlchars again and trim to generate xml data
2632                 if (!isset($this->temp)) {
2633                     $this->temp = "";
2634                 }
2635                 $this->temp .= htmlspecialchars(trim($this->content))."</".$tagName.">";
2636                 //If we've finished a scale, xmlize it an save to db
2637                 if (($this->level == 4) and ($tagName == "SCALE")) {
2638                     //Prepend XML standard header to info gathered
2639                     $xml_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".$this->temp;
2640                     //Call to xmlize for this portion of xml data (one SCALE)
2641                     //echo "-XMLIZE: ".strftime ("%X",time()),"-";                                                //Debug
2642                     $data = xmlize($xml_data,0);
2643                     //echo strftime ("%X",time())."<p>";                                                          //Debug
2644                     //traverse_xmlize($data);                                                                     //Debug
2645                     //print_object ($GLOBALS['traverse_array']);                                                  //Debug
2646                     //$GLOBALS['traverse_array']="";                                                              //Debug
2647                     //Now, save data to db. We'll use it later
2648                     //Get id and from data
2649                     $scale_id = $data["SCALE"]["#"]["ID"]["0"]["#"];
2650                     //Save to db
2651                     $status = backup_putid($this->preferences->backup_unique_code,"scale",$scale_id,
2652                                      null,$data);
2653                     //Create returning info
2654                     $ret_info->id = $scale_id;
2655                     $this->info[] = $ret_info;
2656                     //Reset temp
2657                     unset($this->temp);
2658                 }
2659             }
2661             //Stop parsing if todo = SCALES and tagName = SCALE (en of the tag, of course)
2662             //Speed up a lot (avoid parse all)
2663             if ($tagName == "SCALES" and $this->level == 3) {
2664                 $this->finished = true;
2665             }
2667             //Clear things
2668             $this->tree[$this->level] = "";
2669             $this->level--;
2670             $this->content = "";
2671         }
2673         //This is the endTag handler we use where we are reading the groups zone (todo="GROUPS")
2674         function endElementGroups($parser, $tagName) {
2675             //Check if we are into GROUPS zone
2676             if ($this->tree[3] == "GROUPS") {
2677                 //if (trim($this->content))                                                                     //Debug
2678                 //    echo "C".str_repeat("&nbsp;",($this->level+2)*2).$this->getContents()."<br>\n";           //Debug
2679                 //echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;/".$tagName."&gt;<br>\n";          //Debug
2680                 //Acumulate data to info (content + close tag)
2681                 //Reconvert: strip htmlchars again and trim to generate xml data
2682                 if (!isset($this->temp)) {
2683                     $this->temp = "";
2684                 }
2685                 $this->temp .= htmlspecialchars(trim($this->content))."</".$tagName.">";
2686                 //If we've finished a group, xmlize it an save to db
2687                 if (($this->level == 4) and ($tagName == "GROUP")) {
2688                     //Prepend XML standard header to info gathered
2689                     $xml_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".$this->temp;
2690                     //Call to xmlize for this portion of xml data (one GROUP)
2691                     //echo "-XMLIZE: ".strftime ("%X",time()),"-";                                                //Debug
2692                     $data = xmlize($xml_data,0);
2693                     //echo strftime ("%X",time())."<p>";                                                          //Debug
2694                     //traverse_xmlize($data);                                                                     //Debug
2695                     //print_object ($GLOBALS['traverse_array']);                                                  //Debug
2696                     //$GLOBALS['traverse_array']="";                                                              //Debug
2697                     //Now, save data to db. We'll use it later
2698                     //Get id and from data
2699                     $group_id = $data["GROUP"]["#"]["ID"]["0"]["#"];
2700                     //Save to db
2701                     $status = backup_putid($this->preferences->backup_unique_code,"group",$group_id,
2702                                      null,$data);
2703                     //Create returning info
2704                     $ret_info->id = $group_id;
2705                     $this->info[] = $ret_info;
2706                     //Reset temp
2707                     unset($this->temp);
2708                 }
2709             }
2711             //Stop parsing if todo = GROUPS and tagName = GROUP (en of the tag, of course)
2712             //Speed up a lot (avoid parse all)
2713             if ($tagName == "GROUPS" and $this->level == 3) {
2714                 $this->finished = true;
2715             }
2717             //Clear things
2718             $this->tree[$this->level] = "";
2719             $this->level--;
2720             $this->content = "";
2721         }
2723         //This is the endTag handler we use where we are reading the events zone (todo="EVENTS")
2724         function endElementEvents($parser, $tagName) {
2725             //Check if we are into EVENTS zone
2726             if ($this->tree[3] == "EVENTS") {
2727                 //if (trim($this->content))                                                                     //Debug
2728                 //    echo "C".str_repeat("&nbsp;",($this->level+2)*2).$this->getContents()."<br>\n";           //Debug
2729                 //echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;/".$tagName."&gt;<br>\n";          //Debug
2730                 //Acumulate data to info (content + close tag)
2731                 //Reconvert: strip htmlchars again and trim to generate xml data
2732                 if (!isset($this->temp)) {
2733                     $this->temp = "";
2734                 }
2735                 $this->temp .= htmlspecialchars(trim($this->content))."</".$tagName.">";
2736                 //If we've finished a event, xmlize it an save to db
2737                 if (($this->level == 4) and ($tagName == "EVENT")) {
2738                     //Prepend XML standard header to info gathered
2739                     $xml_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".$this->temp;
2740                     //Call to xmlize for this portion of xml data (one EVENT)
2741                     //echo "-XMLIZE: ".strftime ("%X",time()),"-";                                                //Debug
2742                     $data = xmlize($xml_data,0);
2743                     //echo strftime ("%X",time())."<p>";                                                          //Debug
2744                     //traverse_xmlize($data);                                                                     //Debug
2745                     //print_object ($GLOBALS['traverse_array']);                                                  //Debug
2746                     //$GLOBALS['traverse_array']="";                                                              //Debug
2747                     //Now, save data to db. We'll use it later
2748                     //Get id and from data
2749                     $event_id = $data["EVENT"]["#"]["ID"]["0"]["#"];
2750                     //Save to db
2751                     $status = backup_putid($this->preferences->backup_unique_code,"event",$event_id,
2752                                      null,$data);
2753                     //Create returning info
2754                     $ret_info->id = $event_id;
2755                     $this->info[] = $ret_info;
2756                     //Reset temp
2757                     unset($this->temp);
2758                 }
2759             }
2761             //Stop parsing if todo = EVENTS and tagName = EVENT (en of the tag, of course)
2762             //Speed up a lot (avoid parse all)
2763             if ($tagName == "EVENTS" and $this->level == 3) {
2764                 $this->finished = true;
2765             }
2767             //Clear things
2768             $this->tree[$this->level] = "";
2769             $this->level--;
2770             $this->content = "";
2771         }
2773         //This is the endTag handler we use where we are reading the modules zone (todo="MODULES")
2774         function endElementModules($parser, $tagName) {
2775             //Check if we are into MODULES zone
2776             if ($this->tree[3] == "MODULES") {
2777                 //if (trim($this->content))                                                                     //Debug
2778                 //    echo "C".str_repeat("&nbsp;",($this->level+2)*2).$this->getContents()."<br>\n";           //Debug
2779                 //echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;/".$tagName."&gt;<br>\n";          //Debug
2780                 //Acumulate data to info (content + close tag)
2781                 //Reconvert: strip htmlchars again and trim to generate xml data
2782                 if (!isset($this->temp)) {
2783                     $this->temp = "";
2784                 }
2785                 $this->temp .= htmlspecialchars(trim($this->content))."</".$tagName.">";
2786                 //If we've finished a mod, xmlize it an save to db
2787                 if (($this->level == 4) and ($tagName == "MOD")) {
2788                     //Prepend XML standard header to info gathered
2789                     $xml_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".$this->temp;
2790                     //Call to xmlize for this portion of xml data (one MOD)
2791                     //echo "-XMLIZE: ".strftime ("%X",time()),"-";                                                  //Debug
2792                     $data = xmlize($xml_data,0);         
2793                     //echo strftime ("%X",time())."<p>";                                                            //Debug
2794                     //traverse_xmlize($data);                                                                     //Debug
2795                     //print_object ($GLOBALS['traverse_array']);                                                  //Debug
2796                     //$GLOBALS['traverse_array']="";                                                              //Debug
2797                     //Now, save data to db. We'll use it later
2798                     //Get id and modtype from data
2799                     $mod_id = $data["MOD"]["#"]["ID"]["0"]["#"];
2800                     $mod_type = $data["MOD"]["#"]["MODTYPE"]["0"]["#"];
2801                     //Only if we've selected to restore it
2802                     if  ($this->preferences->mods[$mod_type]->restore) {
2803                         //Save to db
2804                         $status = backup_putid($this->preferences->backup_unique_code,$mod_type,$mod_id,
2805                                      null,$data);
2806                         //echo "<p>id: ".$mod_id."-".$mod_type." len.: ".strlen($sla_mod_temp)." to_db: ".$status."<p>";   //Debug
2807                         //Create returning info
2808                         $ret_info->id = $mod_id;
2809                         $ret_info->modtype = $mod_type;
2810                         $this->info[] = $ret_info;
2811                     }
2812                     //Reset temp
2813                     unset($this->temp);
2814                 }
2815             }
2817             //Stop parsing if todo = MODULES and tagName = MODULES (en of the tag, of course)
2818             //Speed up a lot (avoid parse all)
2819             if ($tagName == "MODULES" and $this->level == 3) {
2820                 $this->finished = true;
2821             }
2823             //Clear things
2824             $this->tree[$this->level] = "";
2825             $this->level--;
2826             $this->content = "";
2827         }
2829         //This is the endTag handler we use where we are reading the logs zone (todo="LOGS")
2830         function endElementLogs($parser, $tagName) {
2831             //Check if we are into LOGS zone
2832             if ($this->tree[3] == "LOGS") {
2833                 //if (trim($this->content))                                                                     //Debug
2834                 //    echo "C".str_repeat("&nbsp;",($this->level+2)*2).$this->getContents()."<br>\n";           //Debug
2835                 //echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;/".$tagName."&gt;<br>\n";          //Debug
2836                 //Acumulate data to info (content + close tag)
2837                 //Reconvert: strip htmlchars again and trim to generate xml data
2838                 if (!isset($this->temp)) {
2839                     $this->temp = "";
2840                 }
2841                 $this->temp .= htmlspecialchars(trim($this->content))."</".$tagName.">";
2842                 //If we've finished a log, xmlize it an save to db
2843                 if (($this->level == 4) and ($tagName == "LOG")) {
2844                     //Prepend XML standard header to info gathered
2845                     $xml_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".$this->temp;
2846                     //Call to xmlize for this portion of xml data (one LOG)
2847                     //echo "-XMLIZE: ".strftime ("%X",time()),"-";                                                //Debug
2848                     $data = xmlize($xml_data,0);
2849                     //echo strftime ("%X",time())."<p>";                                                          //Debug
2850                     //traverse_xmlize($data);                                                                     //Debug
2851                     //print_object ($GLOBALS['traverse_array']);                                                  //Debug
2852                     //$GLOBALS['traverse_array']="";                                                              //Debug
2853                     //Now, save data to db. We'll use it later
2854                     //Get id and modtype from data
2855                     $log_id = $data["LOG"]["#"]["ID"]["0"]["#"];