Added support for timestart and timeend (user_teachers table) and
[moodle.git] / backup / restorelib.php
CommitLineData
52376d94 1<?PHP //$Id$
b9846a9b 2 //Functions used in restore
3
785ae439 4 //This function unzips a zip file in the same directory that it is
b9846a9b 5 //It automatically uses pclzip or command line unzip
9c1ae5ae 6 function restore_unzip ($file) {
b9846a9b 7
8 global $CFG;
9
10 $status = true;
11
12 if (empty($CFG->unzip)) { // Use built-in php-based unzip function
d37ca7c7 13 include_once("$CFG->dirroot/lib/pclzip/pclzip.lib.php");
300ae26c 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
b9846a9b 17 $archive = new PclZip($file);
18 if (!$list = $archive->extract(dirname($file))) {
19 $status = false;
20 }
300ae26c 21 //PclTraceDisplay(); //Debug
22 //PclTraceOff(); //Debug
b9846a9b 23 } else { // Use external unzip program
24 $command = "cd ".dirname($file)."; $CFG->unzip -o ".basename($file);
25 Exec($command);
26 }
27
28 return $status;
29 }
30
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;
36
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 }
51
52 return $status;
53 }
785ae439 54
df9a165e 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 }
79
56eea82e 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) {
85
86 global $CFG;
87
88 $status = true;
89
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)) {
3a238a35 97 echo "<li>".get_string ("to")." ".get_string("modulenameplural",$name);
56eea82e 98 $status = $function_name($restore);
99 }
100 }
101 }
c484d58c 102
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);
107
56eea82e 108 echo "</ul>";
109
110 return $status;
111 }
112
c484d58c 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) {
116
117 global $CFG;
118
119 $status = true;
120
121 echo "<ul>";
122
123 if (file_exists("$CFG->dirroot/mod/resource/lib.php")) {
124 include_once("$CFG->dirroot/mod/resource/lib.php");
125 }
126
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);
149
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 }
169
170 //RESOURCE: Decode every RESOURCE (alltext) in the coure
171
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 }
c2e684d6 207 echo "</ul>";
c484d58c 208
209 return $status;
210
211 }
212
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) {
217
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 }
246
247
fd43f7d0 248 //This function read the xml file and store it data from the info zone in an object
785ae439 249 function restore_read_xml_info ($xml_file) {
250
251 //We call the main read_xml function, with todo = INFO
252 $info = restore_read_xml ($xml_file,"INFO",false);
253
254 return $info;
785ae439 255 }
256
fd43f7d0 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) {
259
260 //We call the main read_xml function, with todo = COURSE_HEADER
261 $info = restore_read_xml ($xml_file,"COURSE_HEADER",false);
262
263 return $info;
264 }
76bf541d 265
7ba74615 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) {
268
269 //We call the main read_xml function, with todo = SECTIONS
270 $info = restore_read_xml ($xml_file,"SECTIONS",false);
a2c7397c 271
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) {
278
279 //We call the main read_xml function, with todo = USERS
280 $info = restore_read_xml ($xml_file,"USERS",$restore);
7ba74615 281
282 return $info;
283 }
284
56f56ca0 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) {
288
289 //We call the main read_xml function, with todo = QUESTIONS
290 $info = restore_read_xml ($xml_file,"QUESTIONS",$restore);
291
292 return $info;
293 }
294
42f1ff47 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) {
298
299 //We call the main read_xml function, with todo = SCALES
300 $info = restore_read_xml ($xml_file,"SCALES",$restore);
301
302 return $info;
303 }
304
dfa14bc9 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) {
308
309 //We call the main read_xml function, with todo = GROUPS
310 $info = restore_read_xml ($xml_file,"GROUPS",$restore);
311
312 return $info;
313 }
314
cd44fdcb 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) {
318
319 //We call the main read_xml function, with todo = EVENTS
320 $info = restore_read_xml ($xml_file,"EVENTS",$restore);
321
322 return $info;
323 }
324
e3df3ece 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) {
328
329 //We call the main read_xml function, with todo = MODULES
330 $info = restore_read_xml ($xml_file,"MODULES",$restore);
331
332 return $info;
333 }
334
2ecad742 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) {
338
339 //We call the main read_xml function, with todo = LOGS
340 $info = restore_read_xml ($xml_file,"LOGS",$restore);
341
342 return $info;
343 }
344
76bf541d 345 //This function prints the contents from the info parammeter passed
346 function restore_print_info ($info) {
347
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 }
428
429 return $status;
430 }
431
432 //This function prints the contents from the course_header parammeter passed
433 function restore_print_course_header ($course_header) {
434
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 }
7ba74615 458
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) {
462
463 global $CFG;
464
465 $status = true;
466
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) {
f28aefbe 475 $suffixfull = " ".get_string("copy")." ".$counter;
4f7a557d 476 $suffixshort = "_".$counter;
7ba74615 477 } else {
478 $suffixfull = "";
479 $suffixshort = "";
480 }
f28aefbe 481 $currentfullname = $fullname.$suffixfull;
482 $currentshortname = $shortname.$suffixshort;
7ba74615 483 $course = get_record("course","fullname",addslashes($currentfullname));
484 $counter++;
485 } while ($course);
486
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 }
46f1f782 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 }
7ba74615 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;
7140a97a 521 $course_header->category->name = get_string("unknowncategory");
7ba74615 522 $status = false;
523 }
524
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);
e0f8b50d 531 $course->idnumber = addslashes($course_header->course_idnumber);
7ba74615 532 $course->summary = addslashes($course_header->course_summary);
533 $course->format = addslashes($course_header->course_format);
fff79722 534 $course->showgrades = addslashes($course_header->course_showgrades);
0f3fe4b6 535 $course->blockinfo = addslashes($course_header->blockinfo);
7ba74615 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);
3c01fbf4 544 //$course->showrecent = addslashes($course_header->course_showrecent); INFO: This is out in 1.3
6ecc3ea8 545 $course->maxbytes = addslashes($course_header->course_maxbytes);
3f125001 546 $course->showreports = addslashes($course_header->course_showreports);
568d750b 547 $course->groupmode = addslashes($course_header->course_groupmode);
548 $course->groupmodeforce = addslashes($course_header->course_groupmodeforce);
3a4b33c3 549 $course->lang = addslashes($course_header->course_lang);
7ba74615 550 $course->marker = addslashes($course_header->course_marker);
d4f2e3fb 551 $course->visible = addslashes($course_header->course_visible);
750024e8 552 $course->hiddensections = addslashes($course_header->course_hiddensections);
7ba74615 553 $course->timecreated = addslashes($course_header->course_timecreated);
554 $course->timemodified = addslashes($course_header->course_timemodified);
0f3fe4b6 555 //Adjust blockinfo field.
229f852a 556 //If the info doesn't exist in backup, we create defaults, else we recode it
557 //to current site blocks.
0f3fe4b6 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 }
229f852a 566 } else {
567 $course->blockinfo = blocks_get_block_ids($course->blockinfo);
0f3fe4b6 568 }
7ba74615 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 }
580
581 return $status;
582 }
583
584 //This function creates all the course_sections and course_modules from xml
64eed73f 585 //when restoring in a new course or simply checks sections and create records
586 //in backup_ids when restoring in a existing course
7ba74615 587 function restore_create_sections($restore,$xml_file) {
588
64eed73f 589 global $CFG,$db;
7ba74615 590
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
601
602 $sequence = "";
603
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;
d223ada0 610 $section->summary = addslashes($sect->summary);
7ba74615 611 $section->visible = $sect->visible;
612 $section->sequence = "";
64eed73f 613 //Now calculate the section's newid
614 $newid = 0;
642ac848 615 if ($restore->restoreto == 2) {
64eed73f 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 }
bd96236e 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 }
64eed73f 640 $newid = $rec->id;
641 $sequence = $rec->sequence;
642 }
7ba74615 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
830ce824 652 if (!empty($sect->mods)) {
7ba74615 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;
aac94fd0 666 $course_module->indent = $mod->indent;
7ba74615 667 $course_module->visible = $mod->visible;
e695cd3f 668 $course_module->groupmode = $mod->groupmode;
5146bf9f 669 $course_module->instance = null;
670 //NOTE: The instance (new) is calculated and updated in db in the
7ba74615 671 // final step of the restore. We don't know it yet.
5146bf9f 672 //print_object($course_module); //Debug
7ba74615 673 //Save it to db
674 $newidmod = insert_record("course_modules",$course_module);
675 if ($newidmod) {
676 //save old and new module id
5146bf9f 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);
7ba74615 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) {
bd96236e 701 if (isset($sequence)) {
702 $update_rec->id = $newid;
703 $update_rec->sequence = $sequence;
704 $status = update_record("course_sections",$update_rec);
705 }
7ba74615 706 }
707 }
708 } else {
709 $status = false;
710 }
7ba74615 711 return $status;
712 }
a2c7397c 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) {
717
13e1a20f 718 global $CFG, $db;
a2c7397c 719
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 }
731
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
e23defdb 735 if (!empty($info->users)) {
736 //For each user, take its info from backup_ids
a2c7397c 737 foreach ($info->users as $userid) {
738 $rec = backup_getid($restore->backup_unique_code,"user",$userid);
af9cd955 739 $user = $rec->info;
830ce824 740
a2c7397c 741 //Check if it's admin and coursecreator
830ce824 742 $is_admin = !empty($user->roles['admin']);
743 $is_coursecreator = !empty($user->roles['coursecreator']);
744
a2c7397c 745 //Check if it's teacher and student
830ce824 746 $is_teacher = !empty($user->roles['teacher']);
747 $is_student = !empty($user->roles['student']);
748
0611af10 749 //Check if it's needed
750 $is_needed = !empty($user->roles['needed']);
751
830ce824 752 //Calculate if it is a course user
0611af10 753 //Has role teacher or student or needed
754 $is_course_user = ($is_teacher or $is_student or $is_needed);
830ce824 755
0be7c25e 756 //To store new ids created
757 $newid=null;
758 //check if it exists (by username) and get its id
a2c7397c 759 $user_exists = true;
79619daf 760 $user_data = get_record("user","username",addslashes($user->username));
0be7c25e 761 if (!$user_data) {
a2c7397c 762 $user_exists = false;
0be7c25e 763 } else {
764 $newid = $user_data->id;
a2c7397c 765 }
41fd7fe4 766 //Flags to see if we have to create the user, roles and preferences
a2c7397c 767 $create_user = true;
768 $create_roles = true;
41fd7fe4 769 $create_preferences = true;
a2c7397c 770
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;
41fd7fe4 777 $create_preferences = false;
a2c7397c 778 }
779
780 if ($user_exists and $create_user) {
781 //If user exists mark its newid in backup_ids (the same than old)
0be7c25e 782 $status = backup_putid($restore->backup_unique_code,"user",$userid,$newid,'exists');
a2c7397c 783 $create_user = false;
784 }
785
786 //Here, if create_user, do it
787 if ($create_user) {
1a6c02fa 788 //Unset the id because it's going to be inserted with a new one
789 unset ($user->id);
13e1a20f 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);
a2c7397c 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
4848d55a 805 $status = backup_putid($restore->backup_unique_code,"user",$userid,$newid,"new");
a2c7397c 806 }
807
808 //Here, if create_roles, do it as necessary
809 if ($create_roles) {
0611af10 810 //Get the newid and current info from backup_ids
a2c7397c 811 $data = backup_getid($restore->backup_unique_code,"user",$userid);
812 $newid = $data->new_id;
4848d55a 813 $currinfo = $data->info.",";
eb06f902 814
a2c7397c 815 //Now, depending of the role, create records in user_studentes and user_teacher
816 //and/or mark it in backup_ids
eb06f902 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 }
0611af10 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 }
a2c7397c 839 if ($is_teacher) {
a2c7397c 840 //If the record (teacher) doesn't exists
841 if (!record_exists("user_teachers","userid",$newid,"course", $restore->course_id)) {
0be7c25e 842 //Put status in backup_ids
4848d55a 843 $currinfo = $currinfo."teacher,";
844 $status = backup_putid($restore->backup_unique_code,"user",$userid,$newid,$currinfo);
a2c7397c 845 //Set course and user
830ce824 846 $user->roles['teacher']->course = $restore->course_id;
847 $user->roles['teacher']->userid = $newid;
a2c7397c 848 //Insert data in user_teachers
849 //The structure is exactly as we need
830ce824 850 $status = insert_record("user_teachers",$user->roles['teacher']);
a2c7397c 851 }
852 }
853 if ($is_student) {
a2c7397c 854 //If the record (student) doesn't exists
855 if (!record_exists("user_students","userid",$newid,"course", $restore->course_id)) {
0be7c25e 856 //Put status in backup_ids
4848d55a 857 $currinfo = $currinfo."student,";
858 $status = backup_putid($restore->backup_unique_code,"user",$userid,$newid,$currinfo);
a2c7397c 859 //Set course and user
830ce824 860 $user->roles['student']->course = $restore->course_id;
861 $user->roles['student']->userid = $newid;
a2c7397c 862 //Insert data in user_students
863 //The structure is exactly as we need
830ce824 864 $status = insert_record("user_students",$user->roles['student']);
a2c7397c 865 }
866 }
867 if (!$is_course_user) {
4848d55a 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 }
a2c7397c 874 }
875 }
41fd7fe4 876
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 }
a2c7397c 897 }
a2c7397c 898 }
899
900 return $status;
901 }
1bdeb2ca 902
56f56ca0 903 //This function creates all the categories and questions
904 //from xml (STEP1 of quiz restore)
905 function restore_create_questions($restore,$xml_file) {
906
907 global $CFG, $db;
908
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 }
941
42f1ff47 942 //This function creates all the scales
943 function restore_create_scales($restore,$xml_file) {
944
945 global $CFG, $db;
946
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;
968
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
975
976 //Now build the SCALE record structure
42f1ff47 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']['#']);
983
93e9a4c9 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);
42f1ff47 992 //If it doesn't exist, create
993 if (!$sca_db) {
994 $create_scale = true;
93e9a4c9 995 }
42f1ff47 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 }
1029
dfa14bc9 1030 //This function creates all the groups
1031 function restore_create_groups($restore,$xml_file) {
1032
1033 global $CFG, $db;
1034
1035 $status = true;
66ee4791 1036 $status2 = true;
dfa14bc9 1037 //Check it exists
1038 if (!file_exists($xml_file)) {
1039 $status = false;
1040 }
1041 //Get info from xml
1042 if ($status) {
2ecad742 1043 //groups will contain the old_id of every group
dfa14bc9 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;
1057
1058 if ($data) {
1059 //Now get completed xmlized object
1060 $info = $data->info;
50dbc51f 1061 //traverse_xmlize($info); //Debug
1062 //print_object ($GLOBALS['traverse_array']); //Debug
1063 //$GLOBALS['traverse_array']=""; //Debug
dfa14bc9 1064 //Now build the GROUP record structure
dfa14bc9 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']['#']);
3c0561cf 1070 $gro->hidepicture = backup_todb($info['GROUP']['#']['HIDEPICTURE']['0']['#']);
dfa14bc9 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
fb2c01fb 1089 $newid = $gro_db->id;
dfa14bc9 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 }
1106
1107 //This function restores the groups_members
1108 function restore_create_groups_members($group_id,$info,$restore) {
1109
1110 global $CFG;
1111
1112 $status = true;
1113
1114 //Get the members array
1115 $members = $info['GROUP']['#']['MEMBERS']['0']['#']['MEMBER'];
1116
1117 //Iterate over members
1118 for($i = 0; $i < sizeof($members); $i++) {
1119 $mem_info = $members[$i];
50dbc51f 1120 //traverse_xmlize($mem_info); //Debug
1121 //print_object ($GLOBALS['traverse_array']); //Debug
1122 //$GLOBALS['traverse_array']=""; //Debug
dfa14bc9 1123
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']['#']);
1128
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 }
1134
1135 //The structure is equal to the db, so insert the groups_members
1136 $newid = insert_record ("groups_members",$group_member);
1137
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 }
1151
1152 return $status;
1153 }
1154
cd44fdcb 1155 //This function creates all the course events
1156 function restore_create_events($restore,$xml_file) {
1157
1158 global $CFG, $db;
1159
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;
1181
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
1188
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']['#']);
d2b5f1e8 1192 $eve->format = backup_todb($info['EVENT']['#']['FORMAT']['0']['#']);
cd44fdcb 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']['#']);
4c49c802 1201 $eve->visible = backup_todb($info['EVENT']['#']['VISIBLE']['0']['#']);
cd44fdcb 1202 $eve->timemodified = backup_todb($info['EVENT']['#']['TIMEMODIFIED']['0']['#']);
1203
cd44fdcb 1204 //Now search if that event exists (by description and timestart field) in
1205 //restore->course_id course
df9a165e 1206 $eve_db = get_record("event","courseid",$eve->courseid,"description",$eve->description,"timestart",$eve->timestart);
cd44fdcb 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) {
1213
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;
22c8200f 1226 } else {
1227 //Assign it to group 0
b9f2b9bd 1228 $eve->groupid = 0;
cd44fdcb 1229 }
1230
1231 //The structure is equal to the db, so insert the event
1232 $newid = insert_record ("event",$eve);
fb2c01fb 1233 } else {
1234 //get current event id
1235 $newid = $eve_db->id;
cd44fdcb 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 }
1250
01f50e06 1251 //This function decode things to make restore multi-site fully functional
1252 //It does this conversions:
4c49c802 1253 // - $@FILEPHP@$ -------------------------------> $CFG->wwwroot/file.php/courseid
56eea82e 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
01f50e06 1258 function restore_decode_absolute_links($content) {
1259
1260 global $CFG,$restore;
56eea82e 1261
1262 //Now decode wwwroot and file.php calls
4c49c802 1263 $search = array ("$@FILEPHP@$");
01f50e06 1264
4c49c802 1265 $replace = array ($CFG->wwwroot."/file.php/".$restore->course_id);
01f50e06 1266
1267 $result = str_replace($search,$replace,$content);
1268
56eea82e 1269 if ($result != $content && $CFG->debug>7) { //Debug
1270 echo "<br><hr>".$content."<br>changed to<br>".$result."<hr><br>"; //Debug
1271 } //Debug
01f50e06 1272
1273 return $result;
1274 }
1275
1bdeb2ca 1276 //This function restores the userfiles from the temp (user_files) directory to the
1277 //dataroot/users directory
1278 function restore_user_files($restore) {
1279
1280 global $CFG;
1281
1282 $status = true;
1283
dfa14bc9 1284 $counter = 0;
1285
1bdeb2ca 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);
1290
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
063a8895 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))) {
1bdeb2ca 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 }
4912fae1 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 }
1bdeb2ca 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 }
1338
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) {
1342
1343 global $CFG;
1344
1345 $status = true;
dfa14bc9 1346
1347 $counter = 0;
1bdeb2ca 1348
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);
1353
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 }
4912fae1 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 }
1bdeb2ca 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 }
fd43f7d0 1389
1390
e3df3ece 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) {
1394
1395 global $CFG;
1396
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) {
04b353e4 1404 //info will contain the id and modtype of every module
e3df3ece 1405 //in backup_ids->info will be the real info (serialized)
1406 $info = restore_read_xml_modules($restore,$xml_file);
1407 }
1408
04b353e4 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) {
af9cd955 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 }
5146bf9f 1423 }
1424 }
1425 } else {
1426 $status = false;
1427 }
56f56ca0 1428 return $status;
5146bf9f 1429 }
1430
2ecad742 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;
1436
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;
ea3591e4 1501 } else {
1502 $dblog->cmid = 0;
2ecad742 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 }
1518
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 }
1536
1537 return $status;
1538 }
1539
1540 //This function inserts a course log record, calculating the URL field as necessary
1541 function restore_log_course($restore,$log) {
1542
1543 $status = true;
1544 $toinsert = false;
1545
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:
ea3591e4 1653 echo "action (".$log->module."-".$log->action.") unknow. Not restored<br>"; //Debug
2ecad742 1654 break;
1655 }
1656
1657 //echo "After transformations<br>"; //Debug
1658 //print_object($log); //Debug
1659
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 }
1667
1668 //This function inserts a user log record, calculating the URL field as necessary
1669 function restore_log_user($restore,$log) {
1670
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;
cd44fdcb 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;
2ecad742 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:
0f318c26 1714 echo "action (".$log->module."-".$log->action.") unknow. Not restored<br>"; //Debug
2ecad742 1715 break;
1716 }
1717
1718 //echo "After transformations<br>"; //Debug
1719 //print_object($log); //Debug
1720
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 }
1728
1729 //This function inserts a module log record, calculating the URL field as necessary
1730 function restore_log_module($restore,$log) {
1731
1732 $status = true;
ea3591e4 1733 $toinsert = false;
1734
1735 //echo "<hr>Before transformations<br>"; //Debug
1736 //print_object($log); //Debug
1737
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 }
2ecad742 1748
ea3591e4 1749 //echo "After transformations<br>"; //Debug
1750 //print_object($log); //Debug
1751
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 }
2ecad742 1757 return $status;
1758 }
1759
5146bf9f 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) {
1763
1764 global $CFG;
1765
1766 $status = true;
04b353e4 1767
5146bf9f 1768 //We are going to iterate over each course_module saved in backup_ids
af9cd955 1769 $course_modules = get_records_sql("SELECT old_id,new_id
5146bf9f 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) {
af9cd955 1775 //Get full record, using backup_getids
1776 $cm_module = backup_getid($restore->backup_unique_code,"course_modules",$cm->old_id);
5146bf9f 1777 //Now we are going to the REAL course_modules to get its type (field module)
af9cd955 1778 $module = get_record("course_modules","id",$cm_module->new_id);
5146bf9f 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 !!!
af9cd955 1785 $instance = backup_getid($restore->backup_unique_code,$type->name,$cm_module->info);
5146bf9f 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 }
04b353e4 1801 }
1802
04b353e4 1803
5146bf9f 1804 return $status;
e3df3ece 1805 }
1806
785ae439 1807 //=====================================================================================
1808 //== ==
1809 //== XML Functions (SAX) ==
1810 //== ==
1811 //=====================================================================================
1812
1813 //This is the class used to do all the xml parse
1814 class MoodleParser {
1815
1816 var $level = 0; //Level we are
af9cd955 1817 var $counter = 0; //Counter
785ae439 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
04b353e4 1821 var $info = ""; //Information collected. Temp storage. Used to return data after parsing.
1822 var $temp = ""; //Temp storage.
785ae439 1823 var $preferences = ""; //Preferences about what to load !!
1824 var $finished = false; //Flag to say xml_parse to stop
fd43f7d0 1825
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 }
ca212942 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;
1837
13e1a20f 1838 //Output something to avoid browser timeouts...
1839 backup_flush();
1840
ca212942 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 }
785ae439 1845
fd43f7d0 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;
1851
13e1a20f 1852 //Output something to avoid browser timeouts...
1853 backup_flush();
1854
fd43f7d0 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 }
1859
7ba74615 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;
1865
13e1a20f 1866 //Output something to avoid browser timeouts...
1867 backup_flush();
1868
7ba74615 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 }
a2c7397c 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;
13e1a20f 1879
a2c7397c 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 }
7ba74615 1884
56f56ca0 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;
1890
ad80e394 1891 //if ($tagName == "QUESTION_CATEGORY" && $this->tree[3] == "QUESTION_CATEGORIES") { //Debug
1892 // echo "<P>QUESTION_CATEGORY: ".strftime ("%X",time()),"-"; //Debug
1893 //} //Debug
56f56ca0 1894
1895 //Output something to avoid browser timeouts...
1896 backup_flush();
1897
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
1901
1902 //If we are under a QUESTION_CATEGORY tag under a QUESTION_CATEGORIES zone, accumule it
830ce824 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 }
56f56ca0 1910 }
1911 }
1912
42f1ff47 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;
1918
1919 //if ($tagName == "SCALE" && $this->tree[3] == "SCALES") { //Debug
1920 // echo "<P>SCALE: ".strftime ("%X",time()),"-"; //Debug
1921 //} //Debug
1922
1923 //Output something to avoid browser timeouts...
1924 backup_flush();
1925
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
1929
1930 //If we are under a SCALE tag under a SCALES zone, accumule it
830ce824 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 }
42f1ff47 1938 }
1939 }
1940
dfa14bc9 1941 function startElementGroups($parser, $tagName, $attrs) {
1942 //Refresh properties
1943 $this->level++;
1944 $this->tree[$this->level] = $tagName;
1945
1946 //if ($tagName == "GROUP" && $this->tree[3] == "GROUPS") { //Debug
1947 // echo "<P>GROUP: ".strftime ("%X",time()),"-"; //Debug
1948 //} //Debug
1949
1950 //Output something to avoid browser timeouts...
1951 backup_flush();
1952
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
1956
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 }
1967
cd44fdcb 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;
1973
1974 //if ($tagName == "EVENT" && $this->tree[3] == "EVENTS") { //Debug
1975 // echo "<P>EVENT: ".strftime ("%X",time()),"-"; //Debug
1976 //} //Debug
1977
1978 //Output something to avoid browser timeouts...
1979 backup_flush();
1980
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
1984
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 }
1995
e3df3ece 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;
13e1a20f 2001
04ab6cab 2002 //if ($tagName == "MOD" && $this->tree[3] == "MODULES") { //Debug
2003 // echo "<P>MOD: ".strftime ("%X",time()),"-"; //Debug
2004 //} //Debug
af9cd955 2005
13e1a20f 2006 //Output something to avoid browser timeouts...
2007 backup_flush();
2008
e3df3ece 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
13e1a20f 2012
e3df3ece 2013 //If we are under a MOD tag under a MODULES zone, accumule it
830ce824 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 }
e3df3ece 2021 }
2022 }
2023
2ecad742 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;
2029
2030 //if ($tagName == "LOG" && $this->tree[3] == "LOGS") { //Debug
2031 // echo "<P>LOG: ".strftime ("%X",time()),"-"; //Debug
2032 //} //Debug
2033
2034 //Output something to avoid browser timeouts...
2035 backup_flush();
2036
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
2040
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 }
2051
ca212942 2052 //This is the startTag default handler we use when todo is undefined
785ae439 2053 function startElement($parser, $tagName, $attrs) {
785ae439 2054 $this->level++;
a4ad03f1 2055 $this->tree[$this->level] = $tagName;
13e1a20f 2056
2057 //Output something to avoid browser timeouts...
2058 backup_flush();
2059
a4ad03f1 2060 echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br>\n"; //Debug
785ae439 2061 }
ca212942 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
fd43f7d0 2068 // echo "C".str_repeat("&nbsp;",($this->level+2)*2).$this->getContents()."<br>\n"; //Debug
ca212942 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":
fd43f7d0 2074 $this->info->backup_name = $this->getContents();
ca212942 2075 break;
2076 case "MOODLE_VERSION":
fd43f7d0 2077 $this->info->backup_moodle_version = $this->getContents();
ca212942 2078 break;
2079 case "MOODLE_RELEASE":
fd43f7d0 2080 $this->info->backup_moodle_release = $this->getContents();
ca212942 2081 break;
2082 case "BACKUP_VERSION":
fd43f7d0 2083 $this->info->backup_backup_version = $this->getContents();
ca212942 2084 break;
2085 case "BACKUP_RELEASE":
fd43f7d0 2086 $this->info->backup_backup_release = $this->getContents();
ca212942 2087 break;
2088 case "DATE":
fd43f7d0 2089 $this->info->backup_date = $this->getContents();
ca212942 2090 break;
c9c89845 2091 case "ORIGINAL_WWWROOT":
2092 $this->info->original_wwwroot = $this->getContents();
2093 break;
ca212942 2094 }
2095 }
2096 if ($this->tree[3] == "DETAILS") {
2097 if ($this->level == 4) {
2098 switch ($tagName) {
2099 case "USERS":
fd43f7d0 2100 $this->info->backup_users = $this->getContents();
ca212942 2101 break;
2102 case "LOGS":
fd43f7d0 2103 $this->info->backup_logs = $this->getContents();
ca212942 2104 break;
2105 case "USERFILES":
fd43f7d0 2106 $this->info->backup_user_files = $this->getContents();
ca212942 2107 break;
2108 case "COURSEFILES":
fd43f7d0 2109 $this->info->backup_course_files = $this->getContents();
ca212942 2110 break;
2111 }
2112 }
2113 if ($this->level == 5) {
2114 switch ($tagName) {
2115 case "NAME":
fd43f7d0 2116 $this->info->tempName = $this->getContents();
ca212942 2117 break;
2118 case "INCLUDED":
fd43f7d0 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();
ca212942 2123 break;
2124 }
2125 }
2126 }
fd43f7d0 2127 }
ca212942 2128
785ae439 2129
fd43f7d0 2130 //Clear things
2131 $this->tree[$this->level] = "";
2132 $this->level--;
2133 $this->content = "";
ca212942 2134
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 }
2141
fd43f7d0 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;
e0f8b50d 2164 case "IDNUMBER":
2165 $this->info->course_idnumber = $this->getContents();
2166 break;
fd43f7d0 2167 case "SUMMARY":
2168 $this->info->course_summary = $this->getContents();
2169 break;
2170 case "FORMAT":
2171 $this->info->course_format = $this->getContents();
2172 break;
fff79722 2173 case "SHOWGRADES":
2174 $this->info->course_showgrades = $this->getContents();
2175 break;
229f852a 2176 case "BLOCKINFO":
2177 $this->info->blockinfo = $this->getContents();
2178 break;
fd43f7d0 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;
92ffd629 2197 case "STARTDATE":
2198 $this->info->course_startdate = $this->getContents();
fd43f7d0 2199 break;
2200 case "NUMSECTIONS":
2201 $this->info->course_numsections = $this->getContents();
2202 break;
3c01fbf4 2203 //case "SHOWRECENT": INFO: This is out in 1.3
2204 // $this->info->course_showrecent = $this->getContents();
2205 // break;
6ecc3ea8 2206 case "MAXBYTES":
2207 $this->info->course_maxbytes = $this->getContents();
2208 break;
3f125001 2209 case "SHOWREPORTS":
2210 $this->info->course_showreports = $this->getContents();
2211 break;
568d750b 2212 case "GROUPMODE":
2213 $this->info->course_groupmode = $this->getContents();
2214 break;
2215 case "GROUPMODEFORCE":
2216 $this->info->course_groupmodeforce = $this->getContents();
2217 break;
3a4b33c3 2218 case "LANG":
2219 $this->info->course_lang = $this->getContents();
2220 break;
fd43f7d0 2221 case "MARKER":
2222 $this->info->course_marker = $this->getContents();
2223 break;
d4f2e3fb 2224 case "VISIBLE":
2225 $this->info->course_visible = $this->getContents();
2226 break;
750024e8 2227 case "HIDDENSECTIONS":
2228 $this->info->course_hiddensections = $this->getContents();
87808d0a 2229 break;
fd43f7d0 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 }
2250
2251 }
2252 //Clear things
2253 $this->tree[$this->level] = "";
2254 $this->level--;
2255 $this->content = "";
2256
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 }
2263
7ba74615 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
830ce824 2276 $this->info->sections[$this->info->tempsection->id] = $this->info->tempsection;
7ba74615 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":
a2c7397c 2299 //We've finalized a mod, get it
2300 $this->info->tempsection->mods[$this->info->tempmod->id]->type =
7ba74615 2301 $this->info->tempmod->type;
a2c7397c 2302 $this->info->tempsection->mods[$this->info->tempmod->id]->instance =
7ba74615 2303 $this->info->tempmod->instance;
a2c7397c 2304 $this->info->tempsection->mods[$this->info->tempmod->id]->added =
7ba74615 2305 $this->info->tempmod->added;
a2c7397c 2306 $this->info->tempsection->mods[$this->info->tempmod->id]->deleted =
7ba74615 2307 $this->info->tempmod->deleted;
a2c7397c 2308 $this->info->tempsection->mods[$this->info->tempmod->id]->score =
7ba74615 2309 $this->info->tempmod->score;
aac94fd0 2310 $this->info->tempsection->mods[$this->info->tempmod->id]->indent =
2311 $this->info->tempmod->indent;
a2c7397c 2312 $this->info->tempsection->mods[$this->info->tempmod->id]->visible =
7ba74615 2313 $this->info->tempmod->visible;
e695cd3f 2314 $this->info->tempsection->mods[$this->info->tempmod->id]->groupmode =
2315 $this->info->tempmod->groupmode;
7ba74615 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;
aac94fd0 2339 case "INDENT":
2340 $this->info->tempmod->indent = $this->getContents();
2341 break;
7ba74615 2342 case "VISIBLE":
2343 $this->info->tempmod->visible = $this->getContents();
2344 break;
e695cd3f 2345 case "GROUPMODE":
2346 $this->info->tempmod->groupmode = $this->getContents();
2347 break;
7ba74615 2348 }
2349 }
2350 }
2351 //Clear things
2352 $this->tree[$this->level] = "";
2353 $this->level--;
2354 $this->content = "";
2355
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 }
a2c7397c 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":
af9cd955 2374 //Increment counter
2375 $this->counter++;
e3df3ece 2376 //Save to db
a2c7397c 2377 backup_putid($this->preferences->backup_unique_code,"user",$this->info->tempuser->id,
af9cd955 2378 null,$this->info->tempuser);
2379
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 }
2388
a2c7397c 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;
8199e3f0 2424 case "EMAILSTOP":
2425 $this->info->tempuser->emailstop = $this->getContents();
2426 break;
a2c7397c 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
830ce824 2505 $this->info->tempuser->roles[$this->info->temprole->type] = $this->info->temprole;
a2c7397c 2506 unset($this->info->temprole);
2507 break;
41fd7fe4 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;
a2c7397c 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;
35a14ba0 2526 case "EDITALL":
2527 $this->info->temprole->editall = $this->getContents();
2528 break;
e0f8b50d 2529 case "TIMESTART":
2530 $this->info->temprole->timestart = $this->getContents();
2531 break;
2532 case "TIMEEND":
2533 $this->info->temprole->timeend = $this->getContents();
2534 break;
35a14ba0 2535 case "TIMEMODIFIED":
2536 $this->info->temprole->timemodified = $this->getContents();
2537 break;
a2c7397c 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;
dabf73b4 2547 case "TIMEACCESS":
2548 $this->info->temprole->timeaccess = $this->getContents();
2549 break;
41fd7fe4 2550 case "NAME":
2551 $this->info->tempuserpreference->name = $this->getContents();
2552 break;
2553 case "VALUE":
2554 $this->info->tempuserpreference->value = $this->getContents();
2555 break;
a2c7397c 2556 }
2557 }
2558 }
2559
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;
af9cd955 2564 $this->counter = 0;
a2c7397c 2565 }
2566
2567 //Clear things
2568 $this->tree[$this->level] = "";
2569 $this->level--;
2570 $this->content = "";
2571 }
7ba74615 2572
42f1ff47 2573 //This is the endTag handler we use where we are reading the questions zone (todo="QUESTIONS")
56f56ca0 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
830ce824 2582 if (!isset($this->temp)) {
2583 $this->temp = "";
2584 }
56f56ca0 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;
42f1ff47 2590 //Call to xmlize for this portion of xml data (one QUESTION_CATEGORY)
ad80e394 2591 //echo "-XMLIZE: ".strftime ("%X",time()),"-"; //Debug
ca5c2e1d 2592 $data = xmlize($xml_data,0);
ad80e394 2593 //echo strftime ("%X",time())."<p>"; //Debug
56f56ca0 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
42f1ff47 2598 //Get id from data
56f56ca0 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 }
2610
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 }
2616
2617 //Clear things
2618 $this->tree[$this->level] = "";
2619 $this->level--;
2620 $this->content = "";
2621 }
2622
42f1ff47 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
830ce824 2632 if (!isset($this->temp)) {
2633 $this->temp = "";
2634 }
42f1ff47 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 }
2660
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 }
2666
2667 //Clear things
2668 $this->tree[$this->level] = "";
2669 $this->level--;
2670 $this->content = "";
2671 }
2672
dfa14bc9 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 }
2710
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 }
2716
2717 //Clear things
2718 $this->tree[$this->level] = "";
2719 $this->level--;
2720 $this->content = "";
2721 }
2722
cd44fdcb 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 }
2760
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 }
2766
2767 //Clear things
2768 $this->tree[$this->level] = "";
2769 $this->level--;
2770 $this->content = "";
2771 }
2772
e3df3ece 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)
5146bf9f 2781 //Reconvert: strip htmlchars again and trim to generate xml data
830ce824 2782 if (!isset($this->temp)) {
2783 $this->temp = "";
2784 }
5146bf9f 2785 $this->temp .= htmlspecialchars(trim($this->content))."</".$tagName.">";
e3df3ece 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
04b353e4 2789 $xml_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".$this->temp;
e3df3ece 2790 //Call to xmlize for this portion of xml data (one MOD)
04ab6cab 2791 //echo "-XMLIZE: ".strftime ("%X",time()),"-"; //Debug
ca5c2e1d 2792 $data = xmlize($xml_data,0);
04ab6cab 2793 //echo strftime ("%X",time())."<p>"; //Debug
e3df3ece 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"]["#"];
22c5d527 2801 //Only if we've selected to restore it
2802 if ($this->preferences->mods[$mod_type]->restore) {
22c5d527 2803 //Save to db
13e1a20f 2804 $status = backup_putid($this->preferences->backup_unique_code,$mod_type,$mod_id,
af9cd955 2805 null,$data);
13e1a20f 2806 //echo "<p>id: ".$mod_id."-".$mod_type." len.: ".strlen($sla_mod_temp)." to_db: ".$status."<p>"; //Debug
04b353e4 2807 //Create returning info
5146bf9f 2808 $ret_info->id = $mod_id;
2809 $ret_info->modtype = $mod_type;
2810 $this->info[] = $ret_info;
22c5d527 2811 }
af9cd955 2812 //Reset temp
2813 unset($this->temp);
e3df3ece 2814 }
e3df3ece 2815 }
2816
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 }
2822
2823 //Clear things
2824 $this->tree[$this->level] = "";
2825 $this->level--;
2826 $this->content = "";
2827 }
2828
2ecad742 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"]["#"];
2856 $log_module = $data["LOG"]["#"]["MODULE"]["0"]["#"];
2857 //We only save log entries from backup file if they are:
2858 // - Course logs
2859 // - User logs
2860 // - Module logs about one restored module
2861 if ($log_module == "course" or
2862 $log_module == "user" or
2863 $this->preferences->mods[$log_module]->restore) {
2864 //Increment counter
2865 $this->counter++;
2866 //Save to db
2867 $status = backup_putid($this->preferences->backup_unique_code,"log",$log_id,
2868 null,$data);
2869 //echo "<p>id: ".$mod_id."-".$mod_type." len.: ".strlen($sla_mod_temp)." to_db: ".$status."<p>"; //Debug
2870 //Create returning info
2871 $this->info = $this->counter;
2872 }
2873 //Reset temp
2874 unset($this->temp);
2875 }
2876 }
2877
2878 //Stop parsing if todo = LOGS and tagName = LOGS (en of the tag, of course)
2879 //Speed up a lot (avoid parse all)
2880 if ($tagName == "LOGS" and $this->level == 3) {
2881 $this->finished = true;
2882 $this->counter = 0;
2883
2884 }
2885
2886 //Clear things
2887 $this->tree[$this->level] = "";
2888 $this->level--;
2889 $this->content = "";
2890 }
2891
ca212942 2892 //This is the endTag default handler we use when todo is undefined
785ae439 2893 function endElement($parser, $tagName) {
a4ad03f1 2894 if (trim($this->content)) //Debug
fd43f7d0 2895 echo "C".str_repeat("&nbsp;",($this->level+2)*2).$this->getContents()."<br>\n"; //Debug
a4ad03f1 2896 echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;/".$tagName."&gt;<br>\n"; //Debug
ca212942 2897
2898 //Clear things
785ae439 2899 $this->tree[$this->level] = "";
ca212942 2900 $this->level--;
785ae439 2901 $this->content = "";
785ae439 2902 }
2903
ca212942 2904 //This is the handler to read data contents (simple accumule it)
785ae439 2905 function characterData($parser, $data) {
2906 $this->content .= $data;
2907 }
2908 }
2909
2910 //This function executes the MoodleParser
2911 function restore_read_xml ($xml_file,$todo,$preferences) {
ca212942 2912
785ae439 2913 $status = true;
2914
2915 $xml_parser = xml_parser_create();
2916 $moodle_parser = new MoodleParser();
2917 $moodle_parser->todo = $todo;
2918 $moodle_parser->preferences = $preferences;
2b968407 2919 xml_set_object($xml_parser,$moodle_parser);
ca212942 2920 //Depending of the todo we use some element_handler or another
2921 if ($todo == "INFO") {
2922 //Define handlers to that zone
2923 xml_set_element_handler($xml_parser, "startElementInfo", "endElementInfo");
fd43f7d0 2924 } else if ($todo == "COURSE_HEADER") {
2925 //Define handlers to that zone
2926 xml_set_element_handler($xml_parser, "startElementCourseHeader", "endElementCourseHeader");
7ba74615 2927 } else if ($todo == "SECTIONS") {
2928 //Define handlers to that zone
2929 xml_set_element_handler($xml_parser, "startElementSections", "endElementSections");
a2c7397c 2930 } else if ($todo == "USERS") {
2931 //Define handlers to that zone
2932 xml_set_element_handler($xml_parser, "startElementUsers", "endElementUsers");
56f56ca0 2933 } else if ($todo == "QUESTIONS") {
2934 //Define handlers to that zone
2935 xml_set_element_handler($xml_parser, "startElementQuestions", "endElementQuestions");
42f1ff47 2936 } else if ($todo == "SCALES") {
2937 //Define handlers to that zone
2938 xml_set_element_handler($xml_parser, "startElementScales", "endElementScales");
dfa14bc9 2939 } else if ($todo == "GROUPS") {
2940 //Define handlers to that zone
2941 xml_set_element_handler($xml_parser, "startElementGroups", "endElementGroups");
cd44fdcb 2942 } else if ($todo == "EVENTS") {
2943 //Define handlers to that zone
2944 xml_set_element_handler($xml_parser, "startElementEvents", "endElementEvents");
e3df3ece 2945 } else if ($todo == "MODULES") {
2946 //Define handlers to that zone
2947 xml_set_element_handler($xml_parser, "startElementModules", "endElementModules");
2ecad742 2948 } else if ($todo == "LOGS") {
2949 //Define handlers to that zone
2950 xml_set_element_handler($xml_parser, "startElementLogs", "endElementLogs");
ca212942 2951 } else {
2952 //Define default handlers (must no be invoked when everything become finished)
2953 xml_set_element_handler($xml_parser, "startElementInfo", "endElementInfo");
2954 }
785ae439 2955 xml_set_character_data_handler($xml_parser, "characterData");
2956 $fp = fopen($xml_file,"r")
2957 or $status = false;
2958 if ($status) {
2959 while ($data = fread($fp, 4096) and !$moodle_parser->finished)
2960 xml_parse($xml_parser, $data, feof($fp))
2961 or die(sprintf("XML error: %s at line %d",
2962 xml_error_string(xml_get_error_code($xml_parser)),
2963 xml_get_current_line_number($xml_parser)));
2964 fclose($fp);
2965 }
a4ad03f1 2966 //Get info from parser
2967 $info = $moodle_parser->info;
2968
2969 //Clear parser mem
785ae439 2970 xml_parser_free($xml_parser);
2971
af9cd955 2972 if ($status && $info) {
785ae439 2973 return $info;
2974 } else {
2975 return $status;
2976 }
2977 }
52376d94 2978?>