Slightly more helpful message if no courses can be shown.
[moodle-linuxchix.git] / backup / backuplib.php
blob42da4b0811e558380816d78706ae2c774682dad9
1 <?php //$Id$
2 //This file contains all the function needed in the backup utility
3 //except the mod-related funtions that are into every backuplib.php inside
4 //every mod directory
6 //Calculate the number of users to backup and put their ids in backup_ids
7 //Return an array of info (name,value)
8 function user_check_backup($course,$backup_unique_code,$backup_users,$backup_messages) {
9 //$backup_users=0-->all
10 // 1-->course (needed + enrolled)
11 // 2-->none
13 global $CFG;
14 global $db;
16 $context = get_context_instance(CONTEXT_COURSE, $course);
17 $count_users = 0;
19 //If we've selected none, simply return 0
20 if ($backup_users == 0 or $backup_users == 1) {
22 //Calculate needed users (calling every xxxx_get_participants function + scales users)
23 $needed_users = backup_get_needed_users($course, $backup_messages);
25 //Calculate enrolled users (students + teachers)
26 $enrolled_users = backup_get_enrolled_users($course);
28 //Calculate all users (every record in users table)
29 $all_users = backup_get_all_users();
31 //Calculate course users (needed + enrolled)
32 //First, needed
33 $course_users = $needed_users;
35 //Now, enrolled
36 if ($enrolled_users) {
37 foreach ($enrolled_users as $enrolled_user) {
38 $course_users[$enrolled_user->id]->id = $enrolled_user->id;
42 //Now, depending of parameters, create $backupable_users
43 if ($backup_users == 0) {
44 $backupable_users = $all_users;
45 } else {
46 $backupable_users = $course_users;
49 //If we have backupable users
50 if ($backupable_users) {
51 //Iterate over users putting their roles
52 foreach ($backupable_users as $backupable_user) {
53 $backupable_user->info = "";
55 //Is needed user (exists in needed_users)
56 if (isset($needed_users[$backupable_user->id])) {
57 $backupable_user->info .= "needed";
58 } else if (isset($course_users[$backupable_user->id])) {
59 $backupable_user->info .= "needed";
60 } // Yu: also needed because they can view course
61 // might need another variable
63 //Now create the backup_id record
64 $backupids_rec->backup_code = $backup_unique_code;
65 $backupids_rec->table_name = "user";
66 $backupids_rec->old_id = $backupable_user->id;
67 $backupids_rec->info = $backupable_user->info;
69 //Insert the record id. backup_users decide it.
70 //When all users
71 $status = insert_record('backup_ids', $backupids_rec, false);
72 $count_users++;
74 //Do some output
75 backup_flush(30);
79 //Prepare Info
80 //Gets the user data
81 $info[0][0] = get_string("users");
82 $info[0][1] = $count_users;
84 return $info;
87 //Returns every needed user (participant) in a course
88 //It uses the xxxx_get_participants() function
89 //plus users needed to backup scales.
90 //WARNING: It returns only NEEDED users, not every
91 // every student and teacher in the course, so it
92 //must be merged with backup_get_enrrolled_users !!
94 function backup_get_needed_users ($courseid, $includemessages=false) {
96 global $CFG;
98 $result = false;
100 $course_modules = get_records_sql ("SELECT cm.id, m.name, cm.instance
101 FROM {$CFG->prefix}modules m,
102 {$CFG->prefix}course_modules cm
103 WHERE m.id = cm.module and
104 cm.course = '$courseid'");
106 if ($course_modules) {
107 //Iterate over each module
108 foreach ($course_modules as $course_module) {
109 $modlib = "$CFG->dirroot/mod/$course_module->name/lib.php";
110 $modgetparticipants = $course_module->name."_get_participants";
111 if (file_exists($modlib)) {
112 include_once($modlib);
113 if (function_exists($modgetparticipants)) {
114 $module_participants = $modgetparticipants($course_module->instance);
115 //Add them to result
116 if ($module_participants) {
117 foreach ($module_participants as $module_participant) {
118 $result[$module_participant->id]->id = $module_participant->id;
126 //Now, add scale users (from site and course scales)
127 //Get users
128 $scaleusers = get_records_sql("SELECT DISTINCT userid,userid
129 FROM {$CFG->prefix}scale
130 WHERE courseid = '0' or courseid = '$courseid'");
131 //Add scale users to results
132 if ($scaleusers) {
133 foreach ($scaleusers as $scaleuser) {
134 //If userid != 0
135 if ($scaleuser->userid != 0) {
136 $result[$scaleuser->userid]->id = $scaleuser->userid;
141 //Now, add message users if necessary
142 if ($includemessages) {
143 include_once("$CFG->dirroot/message/lib.php");
144 //Get users
145 $messageusers = message_get_participants();
146 //Add message users to results
147 if ($messageusers) {
148 foreach ($messageusers as $messageuser) {
149 //If id != 0
150 if ($messageuser->id !=0) {
151 $result[$messageuser->id]->id = $messageuser->id;
157 return $result;
161 //Returns every enrolled user (student and teacher) in a course
163 function backup_get_enrolled_users ($courseid) {
165 global $CFG;
167 // get all users with moodle/course:view capability, this will include people
168 // assigned at cat level, or site level
169 // but it should be ok if they have no direct assignment at course, mod, block level
170 return get_users_by_capability(get_context_instance(CONTEXT_COURSE, $courseid), 'moodle/course:view');
173 //Returns all users ids (every record in users table)
174 function backup_get_all_users() {
176 return get_records('user', '', '', '', 'id, id');
179 //Calculate the number of log entries to backup
180 //Return an array of info (name,value)
181 function log_check_backup($course) {
183 global $CFG;
185 //Now execute the count
186 $ids = count_records("log","course",$course);
188 //Gets the user data
189 $info[0][0] = get_string("logs");
190 if ($ids) {
191 $info[0][1] = $ids;
192 } else {
193 $info[0][1] = 0;
196 return $info;
199 //Calculate the number of user files to backup
200 //Under $CFG->dataroot/users
201 //and put them (their path) in backup_ids
202 //Return an array of info (name,value)
203 function user_files_check_backup($course,$backup_unique_code) {
205 global $CFG;
207 $rootdir = $CFG->dataroot."/users";
208 //Check if directory exists
209 if (is_dir($rootdir)) {
210 //Get directories without descend
211 $userdirs = get_directory_list($rootdir,"",false,true,false);
212 foreach ($userdirs as $dir) {
213 //Extracts user id from file path
214 $tok = strtok($dir,"/");
215 if ($tok) {
216 $userid = $tok;
217 } else {
218 //We were getting $dir='0', so continue (WAS: $tok = "";)
219 continue;
221 //Look it is a backupable user
222 $data = get_record ("backup_ids","backup_code","$backup_unique_code",
223 "table_name","user",
224 "old_id",$userid);
225 if ($data) {
226 //Insert them into backup_files
227 $status = execute_sql("INSERT INTO {$CFG->prefix}backup_files
228 (backup_code, file_type, path, old_id)
229 VALUES
230 ('$backup_unique_code','user','".addslashes($dir)."','$userid')",false);
232 //Do some output
233 backup_flush(30);
237 //Now execute the select
238 $ids = get_records_sql("SELECT DISTINCT b.path, b.old_id
239 FROM {$CFG->prefix}backup_files b
240 WHERE backup_code = '$backup_unique_code' AND
241 file_type = 'user'");
242 //Gets the user data
243 $info[0][0] = get_string("files");
244 if ($ids) {
245 $info[0][1] = count($ids);
246 } else {
247 $info[0][1] = 0;
250 return $info;
253 //Calculate the number of course files to backup
254 //under $CFG->dataroot/$course, except $CFG->moddata, and backupdata
255 //and put them (their path) in backup_ids
256 //Return an array of info (name,value)
257 function course_files_check_backup($course,$backup_unique_code) {
259 global $CFG;
261 $rootdir = $CFG->dataroot."/$course";
262 //Check if directory exists
263 if (is_dir($rootdir)) {
264 //Get files and directories without descend
265 $coursedirs = get_directory_list($rootdir,$CFG->moddata,false,true,true);
266 $backupdata_dir = "backupdata";
267 foreach ($coursedirs as $dir) {
268 //Check it isn't backupdata_dir
269 if (strpos($dir,$backupdata_dir)!==0) {
270 //Insert them into backup_files
271 $status = execute_sql("INSERT INTO {$CFG->prefix}backup_files
272 (backup_code, file_type, path)
273 VALUES
274 ('$backup_unique_code','course','".addslashes($dir)."')",false);
276 //Do some output
277 backup_flush(30);
281 //Now execute the select
282 $ids = get_records_sql("SELECT DISTINCT b.path, b.old_id
283 FROM {$CFG->prefix}backup_files b
284 WHERE backup_code = '$backup_unique_code' AND
285 file_type = 'course'");
286 //Gets the user data
287 $info[0][0] = get_string("files");
288 if ($ids) {
289 $info[0][1] = count($ids);
290 } else {
291 $info[0][1] = 0;
294 return $info;
297 //Function to check and create the needed moddata dir to
298 //save all the mod backup files. We always name it moddata
299 //to be able to restore it, but in restore we check for
300 //$CFG->moddata !!
301 function check_and_create_moddata_dir($backup_unique_code) {
303 global $CFG;
305 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/moddata",true);
307 return $status;
310 //Function to check and create the "user_files" dir to
311 //save all the user files we need from "users" dir
312 function check_and_create_user_files_dir($backup_unique_code) {
314 global $CFG;
316 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/user_files",true);
318 return $status;
321 //Function to check and create the "group_files" dir to
322 //save all the user files we need from "groups" dir
323 function check_and_create_group_files_dir($backup_unique_code) {
325 global $CFG;
327 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/group_files",true);
329 return $status;
332 //Function to check and create the "course_files" dir to
333 //save all the course files we need from "CFG->datadir/course" dir
334 function check_and_create_course_files_dir($backup_unique_code) {
336 global $CFG;
338 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/course_files",true);
340 return $status;
343 //Function to create, open and write header of the xml file
344 function backup_open_xml($backup_unique_code) {
346 global $CFG;
348 $status = true;
350 //Open for writing
352 $file = $CFG->dataroot."/temp/backup/".$backup_unique_code."/moodle.xml";
353 $backup_file = fopen($file,"w");
354 //Writes the header
355 $status = fwrite ($backup_file,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
356 if ($status) {
357 $status = fwrite ($backup_file,start_tag("MOODLE_BACKUP",0,true));
359 if ($status) {
360 return $backup_file;
361 } else {
362 return false;
366 //Close the file
367 function backup_close_xml($backup_file) {
368 $status = fwrite ($backup_file,end_tag("MOODLE_BACKUP",0,true));
369 return fclose($backup_file);
372 //Return the xml start tag
373 function start_tag($tag,$level=0,$endline=false,$attributes=null) {
374 if ($endline) {
375 $endchar = "\n";
376 } else {
377 $endchar = "";
379 $attrstring = '';
380 if (!empty($attributes) && is_array($attributes)) {
381 foreach ($attributes as $key => $value) {
382 $attrstring .= " ".xml_tag_safe_content($key)."=\"".
383 xml_tag_safe_content($value)."\"";
386 return str_repeat(" ",$level*2)."<".strtoupper($tag).$attrstring.">".$endchar;
389 //Return the xml end tag
390 function end_tag($tag,$level=0,$endline=true) {
391 if ($endline) {
392 $endchar = "\n";
393 } else {
394 $endchar = "";
396 return str_repeat(" ",$level*2)."</".strtoupper($tag).">".$endchar;
399 //Return the start tag, the contents and the end tag
400 function full_tag($tag,$level=0,$endline=true,$content,$attributes=null) {
402 global $CFG;
404 //Here we encode absolute links
405 $content = backup_encode_absolute_links($content);
407 $st = start_tag($tag,$level,$endline,$attributes);
409 $co = xml_tag_safe_content($content);
411 $et = end_tag($tag,0,true);
413 return $st.$co.$et;
417 function xml_tag_safe_content($content) {
418 global $CFG;
419 //If enabled, we strip all the control chars (\x0-\x1f) from the text but tabs (\x9),
420 //newlines (\xa) and returns (\xd). The delete control char (\x7f) is also included.
421 //because they are forbiden in XML 1.0 specs. The expression below seems to be
422 //UTF-8 safe too because it simply ignores the rest of characters.
423 $content = preg_replace("/[\x-\x8\xb-\xc\xe-\x1f\x7f]/is","",$content);
424 $content = preg_replace("/\r\n|\r/", "\n", htmlspecialchars($content));
425 return $content;
428 //Prints General info about the course
429 //name, moodle_version (internal and release), backup_version, date, info in file...
430 function backup_general_info ($bf,$preferences) {
432 global $CFG;
434 fwrite ($bf,start_tag("INFO",1,true));
436 //The name of the backup
437 fwrite ($bf,full_tag("NAME",2,false,$preferences->backup_name));
438 //The moodle_version
439 fwrite ($bf,full_tag("MOODLE_VERSION",2,false,$preferences->moodle_version));
440 fwrite ($bf,full_tag("MOODLE_RELEASE",2,false,$preferences->moodle_release));
441 //The backup_version
442 fwrite ($bf,full_tag("BACKUP_VERSION",2,false,$preferences->backup_version));
443 fwrite ($bf,full_tag("BACKUP_RELEASE",2,false,$preferences->backup_release));
444 //The date
445 fwrite ($bf,full_tag("DATE",2,false,$preferences->backup_unique_code));
446 //The original site wwwroot
447 fwrite ($bf,full_tag("ORIGINAL_WWWROOT",2,false,$CFG->wwwroot));
448 //The zip method used
449 if (!empty($CFG->zip)) {
450 $zipmethod = 'external';
451 } else {
452 $zipmethod = 'internal';
454 //Indicate if it includes external MNET users
455 $sql = "SELECT b.old_id
456 FROM {$CFG->prefix}backup_ids b
457 JOIN {$CFG->prefix}user u ON b.old_id=u.id
458 WHERE b.backup_code = '$preferences->backup_unique_code'
459 AND b.table_name = 'user' AND u.mnethostid != '{$CFG->mnet_localhost_id}'";
460 if (record_exists_sql($sql)) {
461 fwrite ($bf,full_tag("MNET_REMOTEUSERS",2,false,'true'));
463 fwrite ($bf,full_tag("ZIP_METHOD",2,false,$zipmethod));
464 //Te includes tag
465 fwrite ($bf,start_tag("DETAILS",2,true));
466 //Now, go to mod element of preferences to print its status
467 foreach ($preferences->mods as $element) {
468 //Calculate info
469 $included = "false";
470 $userinfo = "false";
471 if ($element->backup) {
472 $included = "true";
473 if ($element->userinfo) {
474 $userinfo = "true";
477 //Prints the mod start
478 fwrite ($bf,start_tag("MOD",3,true));
479 fwrite ($bf,full_tag("NAME",4,false,$element->name));
480 fwrite ($bf,full_tag("INCLUDED",4,false,$included));
481 fwrite ($bf,full_tag("USERINFO",4,false,$userinfo));
483 if (isset($preferences->mods[$element->name]->instances)
484 && is_array($preferences->mods[$element->name]->instances)
485 && count($preferences->mods[$element->name]->instances)) {
486 fwrite ($bf, start_tag("INSTANCES",4,true));
487 foreach ($preferences->mods[$element->name]->instances as $id => $object) {
488 if (!empty($object->backup)) {
489 //Calculate info
490 $included = "false";
491 $userinfo = "false";
492 if ($object->backup) {
493 $included = "true";
494 if ($object->userinfo) {
495 $userinfo = "true";
498 fwrite ($bf, start_tag("INSTANCE",5,true));
499 fwrite ($bf, full_tag("ID",5,false,$id));
500 fwrite ($bf, full_tag("NAME",5,false,$object->name));
501 fwrite ($bf, full_tag("INCLUDED",5,false,$included)) ;
502 fwrite ($bf, full_tag("USERINFO",5,false,$userinfo));
503 fwrite ($bf, end_tag("INSTANCE",5,true));
506 fwrite ($bf, end_tag("INSTANCES",4,true));
510 //Print the end
511 fwrite ($bf,end_tag("MOD",3,true));
513 //The metacourse in backup
514 if ($preferences->backup_metacourse == 1) {
515 fwrite ($bf,full_tag("METACOURSE",3,false,"true"));
516 } else {
517 fwrite ($bf,full_tag("METACOURSE",3,false,"false"));
519 //The user in backup
520 if ($preferences->backup_users == 1) {
521 fwrite ($bf,full_tag("USERS",3,false,"course"));
522 } else if ($preferences->backup_users == 0) {
523 fwrite ($bf,full_tag("USERS",3,false,"all"));
524 } else {
525 fwrite ($bf,full_tag("USERS",3,false,"none"));
527 //The logs in backup
528 if ($preferences->backup_logs == 1) {
529 fwrite ($bf,full_tag("LOGS",3,false,"true"));
530 } else {
531 fwrite ($bf,full_tag("LOGS",3,false,"false"));
533 //The user files
534 if ($preferences->backup_user_files == 1) {
535 fwrite ($bf,full_tag("USERFILES",3,false,"true"));
536 } else {
537 fwrite ($bf,full_tag("USERFILES",3,false,"false"));
539 //The course files
540 if ($preferences->backup_course_files == 1) {
541 fwrite ($bf,full_tag("COURSEFILES",3,false,"true"));
542 } else {
543 fwrite ($bf,full_tag("COURSEFILES",3,false,"false"));
545 //The messages in backup
546 if ($preferences->backup_messages == 1 && $preferences->backup_course == SITEID) {
547 fwrite ($bf,full_tag("MESSAGES",3,false,"true"));
548 } else {
549 fwrite ($bf,full_tag("MESSAGES",3,false,"false"));
551 //The mode of writing the block data
552 fwrite ($bf,full_tag('BLOCKFORMAT',3,false,'instances'));
553 fwrite ($bf,end_tag("DETAILS",2,true));
555 $status = fwrite ($bf,end_tag("INFO",1,true));
557 ///Roles stuff goes in here
559 fwrite ($bf, start_tag('ROLES', 1, true));
560 $roles = backup_fetch_roles($preferences);
562 $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
564 foreach ($roles as $role) {
565 fwrite ($bf,start_tag('ROLE',2,true));
566 fwrite ($bf,full_tag('ID', 3, false, $role->id));
567 fwrite ($bf,full_tag('NAME',3,false,$role->name));
568 fwrite ($bf,full_tag('SHORTNAME',3,false,$role->shortname));
569 // find and write all default capabilities
570 fwrite ($bf,start_tag('CAPABILITIES',3,true));
571 // pull out all default (site context) capabilities
572 if ($capabilities = role_context_capabilities($role->id, $sitecontext)) {
573 foreach ($capabilities as $capability=>$value) {
574 fwrite ($bf,start_tag('CAPABILITY',4,true));
575 fwrite ($bf,full_tag('NAME', 5, false, $capability));
576 fwrite ($bf,full_tag('PERMISSION', 5, false, $value));
577 // use this to pull out the other info (timemodified and modifierid)
578 $cap = get_record_sql("SELECT *
579 FROM {$CFG->prefix}role_capabilities
580 WHERE capability = '$capability'
581 AND contextid = $sitecontext->id
582 AND roleid = $role->id");
583 fwrite ($bf, full_tag("TIMEMODIFIED", 5, false, $cap->timemodified));
584 fwrite ($bf, full_tag("MODIFIERID", 5, false, $cap->modifierid));
585 fwrite ($bf,end_tag('CAPABILITY',4,true));
588 fwrite ($bf,end_tag('CAPABILITIES',3,true));
589 fwrite ($bf,end_tag('ROLE',2,true));
591 fwrite ($bf,end_tag('ROLES', 1, true));
592 return $status;
595 //Prints course's general info (table course)
596 function backup_course_start ($bf,$preferences) {
598 global $CFG;
600 $status = true;
602 //Course open tag
603 fwrite ($bf,start_tag("COURSE",1,true));
604 //Header open tag
605 fwrite ($bf,start_tag("HEADER",2,true));
607 //Get info from course
608 $course = get_record("course","id",$preferences->backup_course);
609 $context = get_context_instance(CONTEXT_COURSE, $course->id);
610 if ($course) {
611 //Prints course info
612 fwrite ($bf,full_tag("ID",3,false,$course->id));
613 //Obtain the category
614 $category = get_record("course_categories","id","$course->category");
615 if ($category) {
616 //Prints category info
617 fwrite ($bf,start_tag("CATEGORY",3,true));
618 fwrite ($bf,full_tag("ID",4,false,$course->category));
619 fwrite ($bf,full_tag("NAME",4,false,$category->name));
620 fwrite ($bf,end_tag("CATEGORY",3,true));
622 //Continues with the course
623 fwrite ($bf,full_tag("PASSWORD",3,false,$course->password));
624 fwrite ($bf,full_tag("FULLNAME",3,false,$course->fullname));
625 fwrite ($bf,full_tag("SHORTNAME",3,false,$course->shortname));
626 fwrite ($bf,full_tag("IDNUMBER",3,false,$course->idnumber));
627 fwrite ($bf,full_tag("SUMMARY",3,false,$course->summary));
628 fwrite ($bf,full_tag("FORMAT",3,false,$course->format));
629 fwrite ($bf,full_tag("SHOWGRADES",3,false,$course->showgrades));
630 fwrite ($bf,full_tag("NEWSITEMS",3,false,$course->newsitems));
631 fwrite ($bf,full_tag("TEACHER",3,false,$course->teacher));
632 fwrite ($bf,full_tag("TEACHERS",3,false,$course->teachers));
633 fwrite ($bf,full_tag("STUDENT",3,false,$course->student));
634 fwrite ($bf,full_tag("STUDENTS",3,false,$course->students));
635 fwrite ($bf,full_tag("GUEST",3,false,$course->guest));
636 fwrite ($bf,full_tag("STARTDATE",3,false,$course->startdate));
637 fwrite ($bf,full_tag("ENROLPERIOD",3,false,$course->enrolperiod));
638 fwrite ($bf,full_tag("NUMSECTIONS",3,false,$course->numsections));
639 //fwrite ($bf,full_tag("SHOWRECENT",3,false,$course->showrecent)); INFO: This is out in 1.3
640 fwrite ($bf,full_tag("MAXBYTES",3,false,$course->maxbytes));
641 fwrite ($bf,full_tag("SHOWREPORTS",3,false,$course->showreports));
642 fwrite ($bf,full_tag("GROUPMODE",3,false,$course->groupmode));
643 fwrite ($bf,full_tag("GROUPMODEFORCE",3,false,$course->groupmodeforce));
644 fwrite ($bf,full_tag("LANG",3,false,$course->lang));
645 fwrite ($bf,full_tag("THEME",3,false,$course->theme));
646 fwrite ($bf,full_tag("COST",3,false,$course->cost));
647 fwrite ($bf,full_tag("CURRENCY",3,false,$course->currency));
648 fwrite ($bf,full_tag("MARKER",3,false,$course->marker));
649 fwrite ($bf,full_tag("VISIBLE",3,false,$course->visible));
650 fwrite ($bf,full_tag("HIDDENSECTIONS",3,false,$course->hiddensections));
651 fwrite ($bf,full_tag("TIMECREATED",3,false,$course->timecreated));
652 fwrite ($bf,full_tag("TIMEMODIFIED",3,false,$course->timemodified));
653 //If not selected, force metacourse to 0
654 if (!$preferences->backup_metacourse) {
655 $status = fwrite ($bf,full_tag("METACOURSE",3,false,'0'));
656 //else, export the field as is in DB
657 } else {
658 $status = fwrite ($bf,full_tag("METACOURSE",3,false,$course->metacourse));
661 /// write local course overrides here?
662 write_role_overrides_xml($bf, $context, 3);
663 /// write role_assign code here
664 write_role_assignments_xml($bf, $context, 3);
665 //Print header end
666 fwrite ($bf,end_tag("HEADER",2,true));
667 } else {
668 $status = false;
671 return $status;
674 //Prints course's end tag
675 function backup_course_end ($bf,$preferences) {
677 //Course end tag
678 $status = fwrite ($bf,end_tag("COURSE",1,true));
680 return $status;
684 //Prints course's metacourse info (table course_meta)
685 function backup_course_metacourse ($bf,$preferences) {
687 global $CFG;
689 $status = true;
691 //Get info from meta
692 $parents = get_records_sql ("SELECT m.*, c.idnumber, c.shortname
693 FROM {$CFG->prefix}course_meta m,
694 {$CFG->prefix}course c
695 WHERE m.child_course = '$preferences->backup_course' AND
696 m.parent_course = c.id");
697 $childs = get_records_sql ("SELECT m.*, c.idnumber, c.shortname
698 FROM {$CFG->prefix}course_meta m,
699 {$CFG->prefix}course c
700 WHERE m.parent_course = '$preferences->backup_course' AND
701 m.child_course = c.id");
703 if ($parents || $childs) {
704 //metacourse open tag
705 fwrite ($bf,start_tag("METACOURSE",2,true));
706 if ($parents) {
707 fwrite($bf, start_tag("PARENTS",3,true));
708 //Iterate over every parent
709 foreach ($parents as $parent) {
710 //Begin parent
711 fwrite ($bf,start_tag("PARENT",4,true));
712 fwrite ($bf,full_tag("ID",5,false,$parent->parent_course));
713 fwrite ($bf,full_tag("IDNUMBER",5,false,$parent->idnumber));
714 fwrite ($bf,full_tag("SHORTNAME",5,false,$parent->shortname));
715 //End parent
716 fwrite ($bf,end_tag("PARENT",4,true));
718 fwrite ($bf,end_tag("PARENTS",3,true));
720 if ($childs) {
721 fwrite($bf, start_tag("CHILDS",3,true));
722 //Iterate over every child
723 foreach ($childs as $child) {
724 //Begin parent
725 fwrite ($bf,start_tag("CHILD",4,true));
726 fwrite ($bf,full_tag("ID",5,false,$child->child_course));
727 fwrite ($bf,full_tag("IDNUMBER",5,false,$child->idnumber));
728 fwrite ($bf,full_tag("SHORTNAME",5,false,$child->shortname));
729 //End parent
730 fwrite ($bf,end_tag("CHILD",4,true));
732 fwrite ($bf,end_tag("CHILDS",3,true));
734 //metacourse close tag
735 $status = fwrite ($bf,end_tag("METACOURSE",3,true));
738 return $status;
742 //Prints course's messages info (tables message, message_read and message_contacts)
743 function backup_messages ($bf,$preferences) {
745 global $CFG;
747 $status = true;
749 //Get info from messages
750 $unreads = get_records ('message');
751 $reads = get_records ('message_read');
752 $contacts= get_records ('message_contacts');
754 if ($unreads || $reads || $contacts) {
755 $counter = 0;
756 //message open tag
757 fwrite ($bf,start_tag("MESSAGES",2,true));
758 if ($unreads) {
759 //Iterate over every unread
760 foreach ($unreads as $unread) {
761 //start message
762 fwrite($bf, start_tag("MESSAGE",3,true));
763 fwrite ($bf,full_tag("ID",4,false,$unread->id));
764 fwrite ($bf,full_tag("STATUS",4,false,"UNREAD"));
765 fwrite ($bf,full_tag("USERIDFROM",4,false,$unread->useridfrom));
766 fwrite ($bf,full_tag("USERIDTO",4,false,$unread->useridto));
767 fwrite ($bf,full_tag("MESSAGE",4,false,$unread->message));
768 fwrite ($bf,full_tag("FORMAT",4,false,$unread->format));
769 fwrite ($bf,full_tag("TIMECREATED",4,false,$unread->timecreated));
770 fwrite ($bf,full_tag("MESSAGETYPE",4,false,$unread->messagetype));
771 //end message
772 fwrite ($bf,end_tag("MESSAGE",3,true));
774 //Do some output
775 $counter++;
776 if ($counter % 20 == 0) {
777 echo ".";
778 if ($counter % 400 == 0) {
779 echo "<br />";
781 backup_flush(300);
786 if ($reads) {
787 //Iterate over every read
788 foreach ($reads as $read) {
789 //start message
790 fwrite($bf, start_tag("MESSAGE",3,true));
791 fwrite ($bf,full_tag("ID",4,false,$read->id));
792 fwrite ($bf,full_tag("STATUS",4,false,"READ"));
793 fwrite ($bf,full_tag("USERIDFROM",4,false,$read->useridfrom));
794 fwrite ($bf,full_tag("USERIDTO",4,false,$read->useridto));
795 fwrite ($bf,full_tag("MESSAGE",4,false,$read->message));
796 fwrite ($bf,full_tag("FORMAT",4,false,$read->format));
797 fwrite ($bf,full_tag("TIMECREATED",4,false,$read->timecreated));
798 fwrite ($bf,full_tag("MESSAGETYPE",4,false,$read->messagetype));
799 fwrite ($bf,full_tag("TIMEREAD",4,false,$read->timeread));
800 fwrite ($bf,full_tag("MAILED",4,false,$read->mailed));
801 //end message
802 fwrite ($bf,end_tag("MESSAGE",3,true));
804 //Do some output
805 $counter++;
806 if ($counter % 20 == 0) {
807 echo ".";
808 if ($counter % 400 == 0) {
809 echo "<br />";
811 backup_flush(300);
816 if ($contacts) {
817 fwrite($bf, start_tag("CONTACTS",3,true));
818 //Iterate over every contact
819 foreach ($contacts as $contact) {
820 //start contact
821 fwrite($bf, start_tag("CONTACT",4,true));
822 fwrite ($bf,full_tag("ID",5,false,$contact->id));
823 fwrite ($bf,full_tag("USERID",5,false,$contact->userid));
824 fwrite ($bf,full_tag("CONTACTID",5,false,$contact->contactid));
825 fwrite ($bf,full_tag("BLOCKED",5,false,$contact->blocked));
826 //end contact
827 fwrite ($bf,end_tag("CONTACT",4,true));
829 //Do some output
830 $counter++;
831 if ($counter % 20 == 0) {
832 echo ".";
833 if ($counter % 400 == 0) {
834 echo "<br />";
836 backup_flush(300);
839 fwrite($bf, end_tag("CONTACTS",3,true));
841 //messages close tag
842 $status = fwrite ($bf,end_tag("MESSAGES",2,true));
845 return $status;
849 //Prints course's blocks info (table block_instance)
850 function backup_course_blocks ($bf,$preferences) {
852 global $CFG;
854 $status = true;
856 // Read all of the block table
857 $blocks = blocks_get_record();
859 $pages = array();
860 $pages[] = page_create_object(PAGE_COURSE_VIEW, $preferences->backup_course);
862 // Let's see if we have to backup blocks from modules
863 $modulerecords = get_records_sql('SELECT name, id FROM '.$CFG->prefix.'modules');
865 foreach($preferences->mods as $module) {
866 if(!$module->backup) {
867 continue;
870 $cmods = get_records_select('course_modules', 'course = '.$preferences->backup_course.' AND module = '.$modulerecords[$module->name]->id);
871 if(empty($cmods)) {
872 continue;
875 $pagetypes = page_import_types('mod/'.$module->name.'/');
876 if(empty($pagetypes)) {
877 continue;
880 foreach($pagetypes as $pagetype) {
881 foreach($cmods as $cmod) {
882 $pages[] = page_create_object($pagetype, $cmod->instance);
887 //Blocks open tag
888 fwrite ($bf,start_tag('BLOCKS',2,true));
890 while($page = array_pop($pages)) {
891 if ($instances = blocks_get_by_page($page)) {
892 //Iterate over every block
893 foreach ($instances as $position) {
894 foreach ($position as $instance) {
896 //If we somehow have a block with an invalid id, skip it
897 if(empty($blocks[$instance->blockid]->name)) {
898 continue;
900 //Begin Block
902 fwrite ($bf,start_tag('BLOCK',3,true));
903 fwrite ($bf,full_tag('ID', 4, false,$instance->id));
904 fwrite ($bf,full_tag('NAME',4,false,$blocks[$instance->blockid]->name));
905 fwrite ($bf,full_tag('PAGEID',4,false,$instance->pageid));
906 fwrite ($bf,full_tag('PAGETYPE',4,false,$instance->pagetype));
907 fwrite ($bf,full_tag('POSITION',4,false,$instance->position));
908 fwrite ($bf,full_tag('WEIGHT',4,false,$instance->weight));
909 fwrite ($bf,full_tag('VISIBLE',4,false,$instance->visible));
910 fwrite ($bf,full_tag('CONFIGDATA',4,false,$instance->configdata));
912 $context = get_context_instance(CONTEXT_BLOCK, $instance->id);
913 write_role_overrides_xml($bf, $context, 4);
914 /// write role_assign code here
915 write_role_assignments_xml($bf, $context, 4);
916 //End Block
917 fwrite ($bf,end_tag('BLOCK',3,true));
923 //Blocks close tag
924 $status = fwrite ($bf,end_tag('BLOCKS',2,true));
926 return $status;
930 //Prints course's sections info (table course_sections)
931 function backup_course_sections ($bf,$preferences) {
933 global $CFG;
935 $status = true;
938 //Get info from sections
939 $section=false;
940 if ($sections = get_records("course_sections","course",$preferences->backup_course,"section")) {
941 //Section open tag
942 fwrite ($bf,start_tag("SECTIONS",2,true));
943 //Iterate over every section (ordered by section)
944 foreach ($sections as $section) {
945 //Begin Section
946 fwrite ($bf,start_tag("SECTION",3,true));
947 fwrite ($bf,full_tag("ID",4,false,$section->id));
948 fwrite ($bf,full_tag("NUMBER",4,false,$section->section));
949 fwrite ($bf,full_tag("SUMMARY",4,false,$section->summary));
950 fwrite ($bf,full_tag("VISIBLE",4,false,$section->visible));
951 //Now print the mods in section
952 backup_course_modules ($bf,$preferences,$section);
953 //End section
954 fwrite ($bf,end_tag("SECTION",3,true));
956 //Section close tag
957 $status = fwrite ($bf,end_tag("SECTIONS",2,true));
960 return $status;
964 //Prints course's format data (any data the format might want to save).
965 function backup_format_data ($bf,$preferences) {
966 global $CFG;
968 // Check course format
969 if(!($format=get_field('course','format','id',$preferences->backup_course))) {
970 return false;
972 // Write appropriate tag. Note that we always put this tag there even if
973 // blank, it makes parsing easier
974 fwrite ($bf,start_tag("FORMATDATA",2,true));
976 $file=$CFG->dirroot."/course/format/$format/backuplib.php";
977 if(file_exists($file)) {
978 // If the file is there, the function must be or it's an error.
979 require_once($file);
980 $function=$format.'_backup_format_data';
981 if(!function_exists($function)) {
982 return false;
984 if(!$function($bf,$preferences)) {
985 return false;
989 // This last return just checks the file writing has been ok (ish)
990 return fwrite ($bf,end_tag("FORMATDATA",2,true));
993 //Prints course's modules info (table course_modules)
994 //Only for selected mods in preferences
995 function backup_course_modules ($bf,$preferences,$section) {
997 global $CFG;
999 $status = true;
1001 $first_record = true;
1003 //Now print the mods in section
1004 //Extracts mod id from sequence
1005 $tok = strtok($section->sequence,",");
1006 while ($tok) {
1007 //Get module's type
1008 $moduletype = get_module_type ($preferences->backup_course,$tok);
1009 //Check if we've selected to backup that type
1010 if ($moduletype and $preferences->mods[$moduletype]->backup) {
1011 $selected = true;
1012 } else {
1013 $selected = false;
1016 if ($selected) {
1017 $context = get_context_instance(CONTEXT_MODULE, $tok);
1018 //Gets course_module data from db
1019 $course_module = get_records ("course_modules","id",$tok);
1020 //If it's the first, pring MODS tag
1021 if ($first_record) {
1022 fwrite ($bf,start_tag("MODS",4,true));
1023 $first_record = false;
1025 // if we're doing selected instances, check that too.
1026 if (is_array($preferences->mods[$moduletype]->instances)
1027 && count($preferences->mods[$moduletype]->instances)
1028 && (!array_key_exists($course_module[$tok]->instance,$preferences->mods[$moduletype]->instances)
1029 || empty($preferences->mods[$moduletype]->instances[$course_module[$tok]->instance]->backup))) {
1030 $tok = strtok(",");
1031 continue;
1034 // find all role values that has an override in this context
1035 $roles = get_records('role_capabilities', 'contextid', $context->id);
1037 //Print mod info from course_modules
1038 fwrite ($bf,start_tag("MOD",5,true));
1039 //Save neccesary info to backup_ids
1040 fwrite ($bf,full_tag("ID",6,false,$tok));
1041 fwrite ($bf,full_tag("TYPE",6,false,$moduletype));
1042 fwrite ($bf,full_tag("INSTANCE",6,false,$course_module[$tok]->instance));
1043 fwrite ($bf,full_tag("ADDED",6,false,$course_module[$tok]->added));
1044 fwrite ($bf,full_tag("SCORE",6,false,$course_module[$tok]->score));
1045 fwrite ($bf,full_tag("INDENT",6,false,$course_module[$tok]->indent));
1046 fwrite ($bf,full_tag("VISIBLE",6,false,$course_module[$tok]->visible));
1047 fwrite ($bf,full_tag("GROUPMODE",6,false,$course_module[$tok]->groupmode));
1048 // get all the role_capabilities overrides in this mod
1049 write_role_overrides_xml($bf, $context, 6);
1050 /// write role_assign code here
1051 write_role_assignments_xml($bf, $context, 6);
1052 /// write role_assign code here
1054 fwrite ($bf,end_tag("MOD",5,true));
1056 //check for next
1057 $tok = strtok(",");
1060 //Si ha habido modulos, final de MODS
1061 if (!$first_record) {
1062 $status =fwrite ($bf,end_tag("MODS",4,true));
1065 return $status;
1068 //Print users to xml
1069 //Only users previously calculated in backup_ids will output
1071 function backup_user_info ($bf,$preferences) {
1073 global $CFG;
1075 $status = true;
1077 // Use a recordset to for the memory handling on to
1078 // the DB and run faster
1079 $users = get_recordset_sql("SELECT b.old_id, b.table_name, b.info,
1080 u.*, m.wwwroot
1081 FROM {$CFG->prefix}backup_ids b
1082 JOIN {$CFG->prefix}user u ON b.old_id=u.id
1083 JOIN {$CFG->prefix}mnet_host m ON u.mnethostid=m.id
1084 WHERE b.backup_code = '$preferences->backup_unique_code' AND
1085 b.table_name = 'user'");
1087 //If we have users to backup
1088 if ($users && $users->RecordCount()) {
1089 //Begin Users tag
1090 fwrite ($bf,start_tag("USERS",2,true));
1091 $counter = 0;
1092 //With every user
1093 while ($user = $users->FetchNextObj()) {
1094 //Begin User tag
1095 fwrite ($bf,start_tag("USER",3,true));
1096 //Output all user data
1097 fwrite ($bf,full_tag("ID",4,false,$user->id));
1098 fwrite ($bf,full_tag("AUTH",4,false,$user->auth));
1099 fwrite ($bf,full_tag("CONFIRMED",4,false,$user->confirmed));
1100 fwrite ($bf,full_tag("POLICYAGREED",4,false,$user->policyagreed));
1101 fwrite ($bf,full_tag("DELETED",4,false,$user->deleted));
1102 fwrite ($bf,full_tag("USERNAME",4,false,$user->username));
1103 fwrite ($bf,full_tag("PASSWORD",4,false,$user->password));
1104 fwrite ($bf,full_tag("IDNUMBER",4,false,$user->idnumber));
1105 fwrite ($bf,full_tag("FIRSTNAME",4,false,$user->firstname));
1106 fwrite ($bf,full_tag("LASTNAME",4,false,$user->lastname));
1107 fwrite ($bf,full_tag("EMAIL",4,false,$user->email));
1108 fwrite ($bf,full_tag("EMAILSTOP",4,false,$user->emailstop));
1109 fwrite ($bf,full_tag("ICQ",4,false,$user->icq));
1110 fwrite ($bf,full_tag("SKYPE",4,false,$user->skype));
1111 fwrite ($bf,full_tag("YAHOO",4,false,$user->yahoo));
1112 fwrite ($bf,full_tag("AIM",4,false,$user->aim));
1113 fwrite ($bf,full_tag("MSN",4,false,$user->msn));
1114 fwrite ($bf,full_tag("PHONE1",4,false,$user->phone1));
1115 fwrite ($bf,full_tag("PHONE2",4,false,$user->phone2));
1116 fwrite ($bf,full_tag("INSTITUTION",4,false,$user->institution));
1117 fwrite ($bf,full_tag("DEPARTMENT",4,false,$user->department));
1118 fwrite ($bf,full_tag("ADDRESS",4,false,$user->address));
1119 fwrite ($bf,full_tag("CITY",4,false,$user->city));
1120 fwrite ($bf,full_tag("COUNTRY",4,false,$user->country));
1121 fwrite ($bf,full_tag("LANG",4,false,$user->lang));
1122 fwrite ($bf,full_tag("THEME",4,false,$user->theme));
1123 fwrite ($bf,full_tag("TIMEZONE",4,false,$user->timezone));
1124 fwrite ($bf,full_tag("FIRSTACCESS",4,false,$user->firstaccess));
1125 fwrite ($bf,full_tag("LASTACCESS",4,false,$user->lastaccess));
1126 fwrite ($bf,full_tag("LASTLOGIN",4,false,$user->lastlogin));
1127 fwrite ($bf,full_tag("CURRENTLOGIN",4,false,$user->currentlogin));
1128 fwrite ($bf,full_tag("LASTIP",4,false,$user->lastip));
1129 fwrite ($bf,full_tag("SECRET",4,false,$user->secret));
1130 fwrite ($bf,full_tag("PICTURE",4,false,$user->picture));
1131 fwrite ($bf,full_tag("URL",4,false,$user->url));
1132 fwrite ($bf,full_tag("DESCRIPTION",4,false,$user->description));
1133 fwrite ($bf,full_tag("MAILFORMAT",4,false,$user->mailformat));
1134 fwrite ($bf,full_tag("MAILDIGEST",4,false,$user->maildigest));
1135 fwrite ($bf,full_tag("MAILDISPLAY",4,false,$user->maildisplay));
1136 fwrite ($bf,full_tag("HTMLEDITOR",4,false,$user->htmleditor));
1137 fwrite ($bf,full_tag("AJAX",4,false,$user->ajax));
1138 fwrite ($bf,full_tag("AUTOSUBSCRIBE",4,false,$user->autosubscribe));
1139 fwrite ($bf,full_tag("TRACKFORUMS",4,false,$user->trackforums));
1140 if ($user->mnethostid != $CFG->mnet_localhost_id) {
1141 fwrite ($bf,full_tag("MNETHOSTURL",4,false,$user->wwwroot));
1143 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$user->timemodified));
1145 /// write assign/override code for context_userid
1147 $user->isneeded = strpos($user->info,"needed");
1148 //Output every user role (with its associated info)
1150 $user->isadmin = strpos($user->info,"admin");
1151 $user->iscoursecreator = strpos($user->info,"coursecreator");
1152 $user->isteacher = strpos($user->info,"teacher");
1153 $user->isstudent = strpos($user->info,"student");
1156 if ($user->isadmin!==false or
1157 $user->iscoursecreator!==false or
1158 $user->isteacher!==false or
1159 $user->isstudent!==false or
1160 $user->isneeded!==false) {
1162 fwrite ($bf,start_tag("ROLES",4,true));
1163 if ($user->info != "needed" && $user->info!="") {
1164 //Begin ROLES tag
1166 //PRINT ROLE INFO
1167 //Admins
1168 $roles = explode(",", $user->info);
1169 foreach ($roles as $role) {
1170 if ($role!="" && $role!="needed") {
1171 fwrite ($bf,start_tag("ROLE",5,true));
1172 //Print Role info
1173 fwrite ($bf,full_tag("TYPE",6,false,$role));
1174 //Print ROLE end
1175 fwrite ($bf,end_tag("ROLE",5,true));
1180 if ($user->isadmin!==false) {
1181 //Print ROLE start
1182 fwrite ($bf,start_tag("ROLE",5,true));
1183 //Print Role info
1184 fwrite ($bf,full_tag("TYPE",6,false,"admin"));
1185 //Print ROLE end
1186 fwrite ($bf,end_tag("ROLE",5,true));
1188 //CourseCreator
1189 if ($user->iscoursecreator!==false) {
1190 //Print ROLE start
1191 fwrite ($bf,start_tag("ROLE",5,true));
1192 //Print Role info
1193 fwrite ($bf,full_tag("TYPE",6,false,"coursecreator"));
1194 //Print ROLE end
1195 fwrite ($bf,end_tag("ROLE",5,true));
1197 //Teacher
1198 if ($user->isteacher!==false) {
1199 //Print ROLE start
1200 fwrite ($bf,start_tag("ROLE",5,true));
1201 //Print Role info
1202 fwrite ($bf,full_tag("TYPE",6,false,"teacher"));
1203 //Get specific info for teachers
1204 $tea = get_record("user_teachers","userid",$user->old_id,"course",$preferences->backup_course);
1205 fwrite ($bf,full_tag("AUTHORITY",6,false,$tea->authority));
1206 fwrite ($bf,full_tag("TEA_ROLE",6,false,$tea->role));
1207 fwrite ($bf,full_tag("EDITALL",6,false,$tea->editall));
1208 fwrite ($bf,full_tag("TIMESTART",6,false,$tea->timestart));
1209 fwrite ($bf,full_tag("TIMEEND",6,false,$tea->timeend));
1210 fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$tea->timemodified));
1211 fwrite ($bf,full_tag("TIMEACCESS",6,false,$tea->timeaccess));
1212 fwrite ($bf,full_tag("ENROL",6,false,$tea->enrol));
1213 //Print ROLE end
1214 fwrite ($bf,end_tag("ROLE",5,true));
1216 //Student
1217 if ($user->isstudent!==false) {
1218 //Print ROLE start
1219 fwrite ($bf,start_tag("ROLE",5,true));
1220 //Print Role info
1221 fwrite ($bf,full_tag("TYPE",6,false,"student"));
1222 //Get specific info for students
1223 $stu = get_record("user_students","userid",$user->old_id,"course",$preferences->backup_course);
1224 fwrite ($bf,full_tag("TIMESTART",6,false,$stu->timestart));
1225 fwrite ($bf,full_tag("TIMEEND",6,false,$stu->timeend));
1226 fwrite ($bf,full_tag("TIME",6,false,$stu->time));
1227 fwrite ($bf,full_tag("TIMEACCESS",6,false,$stu->timeaccess));
1228 fwrite ($bf,full_tag("ENROL",6,false,$stu->enrol));
1229 //Print ROLE end
1230 fwrite ($bf,end_tag("ROLE",5,true));
1235 //Needed
1236 if ($user->isneeded!==false) {
1237 //Print ROLE start
1238 fwrite ($bf,start_tag("ROLE",5,true));
1239 //Print Role info
1240 fwrite ($bf,full_tag("TYPE",6,false,"needed"));
1241 //Print ROLE end
1242 fwrite ($bf,end_tag("ROLE",5,true));
1245 //End ROLES tag
1246 fwrite ($bf,end_tag("ROLES",4,true));
1248 //Check if we have user_preferences to backup
1249 if ($preferences_data = get_records("user_preferences","userid",$user->old_id)) {
1250 //Start USER_PREFERENCES tag
1251 fwrite ($bf,start_tag("USER_PREFERENCES",4,true));
1252 //Write each user_preference
1253 foreach ($preferences_data as $user_preference) {
1254 fwrite ($bf,start_tag("USER_PREFERENCE",5,true));
1255 fwrite ($bf,full_tag("NAME",6,false,$user_preference->name));
1256 fwrite ($bf,full_tag("VALUE",6,false,$user_preference->value));
1257 fwrite ($bf,end_tag("USER_PREFERENCE",5,true));
1259 //End USER_PREFERENCES tag
1260 fwrite ($bf,end_tag("USER_PREFERENCES",4,true));
1263 $context = get_context_instance(CONTEXT_USER, $user->old_id);
1265 write_role_overrides_xml($bf, $context, 4);
1266 /// write role_assign code here
1267 write_role_assignments_xml($bf, $context, 4);
1268 //End User tag
1269 fwrite ($bf,end_tag("USER",3,true));
1270 //Do some output
1271 $counter++;
1272 if ($counter % 10 == 0) {
1273 echo ".";
1274 if ($counter % 200 == 0) {
1275 echo "<br />";
1277 backup_flush(300);
1280 //End Users tag
1281 fwrite ($bf,end_tag("USERS",2,true));
1282 } else {
1283 // There aren't any users.
1284 $status = true;
1287 return $status;
1290 //Backup log info (time ordered)
1291 function backup_log_info($bf,$preferences) {
1293 global $CFG;
1295 //Number of records to get in every chunk
1296 $recordset_size = 1000;
1298 $status = true;
1300 //Counter, points to current record
1301 $counter = 0;
1303 //Count records
1304 $count_logs = count_records("log","course",$preferences->backup_course);
1306 //Pring logs header
1307 if ($count_logs > 0 ) {
1308 fwrite ($bf,start_tag("LOGS",2,true));
1310 while ($counter < $count_logs) {
1311 //Get a chunk of records
1312 $logs = get_records ("log","course",$preferences->backup_course,"time","*",$counter,$recordset_size);
1314 //We have logs
1315 if ($logs) {
1316 //Iterate
1317 foreach ($logs as $log) {
1318 //See if it is a valid module to backup
1319 if ($log->module == "course" or
1320 $log->module == "user" or
1321 (array_key_exists($log->module, $preferences->mods) and $preferences->mods[$log->module]->backup == 1)) {
1322 // logs with 'upload' in module field are ignored, there is no restore code anyway
1323 //Begin log tag
1324 fwrite ($bf,start_tag("LOG",3,true));
1326 //Output log tag
1327 fwrite ($bf,full_tag("ID",4,false,$log->id));
1328 fwrite ($bf,full_tag("TIME",4,false,$log->time));
1329 fwrite ($bf,full_tag("USERID",4,false,$log->userid));
1330 fwrite ($bf,full_tag("IP",4,false,$log->ip));
1331 fwrite ($bf,full_tag("MODULE",4,false,$log->module));
1332 fwrite ($bf,full_tag("CMID",4,false,$log->cmid));
1333 fwrite ($bf,full_tag("ACTION",4,false,$log->action));
1334 fwrite ($bf,full_tag("URL",4,false,$log->url));
1335 fwrite ($bf,full_tag("INFO",4,false,$log->info));
1337 //End log tag
1338 fwrite ($bf,end_tag("LOG",3,true));
1340 //Do some output
1341 $counter++;
1342 if ($counter % 20 == 0) {
1343 echo ".";
1344 if ($counter % 400 == 0) {
1345 echo "<br />";
1347 backup_flush(300);
1352 //End logs tag
1353 if ($count_logs > 0 ) {
1354 $status = fwrite ($bf,end_tag("LOGS",2,true));
1356 return $status;
1359 //Backup gradebook info
1360 function backup_gradebook_info($bf,$preferences) {
1362 global $CFG;
1364 $status = true;
1366 //Gradebook header
1367 fwrite ($bf,start_tag("GRADEBOOK",2,true));
1369 //Output grade_preferences
1370 $grade_preferences = get_records("grade_preferences", "courseid", $preferences->backup_course);
1371 if ($grade_preferences) {
1372 //Begin grade_preferences tag
1373 fwrite ($bf,start_tag("GRADE_PREFERENCES",3,true));
1374 //Iterate for each preference
1375 foreach ($grade_preferences as $grade_preference) {
1376 //Begin grade_preference
1377 fwrite ($bf,start_tag("GRADE_PREFERENCE",4,true));
1378 //Output individual fields
1379 fwrite ($bf,full_tag("ID",5,false,$grade_preference->id));
1380 fwrite ($bf,full_tag("PREFERENCE",5,false,$grade_preference->preference));
1381 fwrite ($bf,full_tag("VALUE",5,false,$grade_preference->value));
1382 //End grade_preference
1383 fwrite ($bf,end_tag("GRADE_PREFERENCE",4,true));
1385 //End grade_preferences tag
1386 $status = fwrite ($bf,end_tag("GRADE_PREFERENCES",3,true));
1389 //Output grade_letter
1390 $grade_letters = get_records("grade_letter", "courseid", $preferences->backup_course);
1391 if ($grade_letters) {
1392 //Begin grade_letters tag
1393 fwrite ($bf,start_tag("GRADE_LETTERS",3,true));
1394 //Iterate for each letter
1395 foreach ($grade_letters as $grade_letter) {
1396 //Begin grade_letter
1397 fwrite ($bf,start_tag("GRADE_LETTER",4,true));
1398 //Output individual fields
1399 fwrite ($bf,full_tag("ID",5,false,$grade_letter->id));
1400 fwrite ($bf,full_tag("LETTER",5,false,$grade_letter->letter));
1401 fwrite ($bf,full_tag("GRADE_HIGH",5,false,$grade_letter->grade_high));
1402 fwrite ($bf,full_tag("GRADE_LOW",5,false,$grade_letter->grade_low));
1403 //End grade_letter
1404 fwrite ($bf,end_tag("GRADE_LETTER",4,true));
1406 //End grade_letters tag
1407 $status = fwrite ($bf,end_tag("GRADE_LETTERS",3,true));
1410 //Output grade_category
1411 $grade_categories = get_records("grade_category", "courseid", $preferences->backup_course);
1412 if ($grade_categories) {
1413 //Begin grade_categories tag
1414 fwrite ($bf,start_tag("GRADE_CATEGORIES",3,true));
1415 //Iterate for each category
1416 foreach ($grade_categories as $grade_category) {
1417 //Begin grade_category
1418 fwrite ($bf,start_tag("GRADE_CATEGORY",4,true));
1419 //Output individual fields
1420 fwrite ($bf,full_tag("ID",5,false,$grade_category->id));
1421 fwrite ($bf,full_tag("NAME",5,false,$grade_category->name));
1422 fwrite ($bf,full_tag("DROP_X_LOWEST",5,false,$grade_category->drop_x_lowest));
1423 fwrite ($bf,full_tag("BONUS_POINTS",5,false,$grade_category->bonus_points));
1424 fwrite ($bf,full_tag("HIDDEN",5,false,$grade_category->hidden));
1425 fwrite ($bf,full_tag("WEIGHT",5,false,$grade_category->weight));
1427 //Now backup grade_item (inside grade_category)
1428 $status = backup_gradebook_item_info($bf,$preferences,$grade_category->id);
1430 //End grade_category
1431 fwrite ($bf,end_tag("GRADE_CATEGORY",4,true));
1433 //End grade_categories tag
1434 $status = fwrite ($bf,end_tag("GRADE_CATEGORIES",3,true));
1436 //Gradebook footer
1437 $status = fwrite ($bf,end_tag("GRADEBOOK",2,true));
1438 return $status;
1441 //Backup gradebook_item (called from backup_gradebook_info
1442 function backup_gradebook_item_info($bf,$preferences,$gradecategoryid) {
1444 global $CFG;
1446 $status = true;
1448 //Output grade_item (only for modules included in backup)
1449 $grade_items = get_records_sql("SELECT *
1450 FROM {$CFG->prefix}grade_item
1451 WHERE courseid = $preferences->backup_course AND
1452 category = $gradecategoryid");
1453 //Filter items about modules not included in backup
1454 $inc_grade_items = array();
1455 if ($grade_items) {
1456 foreach ($grade_items as $grade_item) {
1457 //Get modulename
1458 $rec_module = get_record("modules", "id", $grade_item->modid);
1459 //If it exists and it's included in backup
1460 if ($rec_module && $preferences->mods[$rec_module->name]->backup == 1) {
1461 //Set the name and add it
1462 $grade_item->module_name = $rec_module->name;
1463 $inc_grade_items[] = $grade_item;
1464 } else {
1465 debugging("skipping $grade_item->modid"."-"."$rec_module->name<br />");
1469 if ($inc_grade_items) {
1470 //Begin grade_items tag
1471 fwrite ($bf,start_tag("GRADE_ITEMS",5,true));
1472 //Iterate for each item
1473 foreach ($inc_grade_items as $grade_item) {
1474 //Begin grade_item
1475 fwrite ($bf,start_tag("GRADE_ITEM",6,true));
1476 //Output individual fields
1477 fwrite ($bf,full_tag("MODULE_NAME",7,false,$grade_item->module_name));
1478 fwrite ($bf,full_tag("CMINSTANCE",7,false,$grade_item->cminstance));
1479 fwrite ($bf,full_tag("SCALE_GRADE",7,false,$grade_item->scale_grade));
1480 fwrite ($bf,full_tag("EXTRA_CREDIT",7,false,$grade_item->extra_credit));
1481 fwrite ($bf,full_tag("SORT_ORDER",7,false,$grade_item->sort_order));
1483 //Now backup grade_exceptions (inside grade_item)
1484 $status = backup_gradebook_exceptions_info($bf,$preferences,$grade_item->id);
1486 //End grade_item
1487 fwrite ($bf,end_tag("GRADE_ITEM",6,true));
1489 //End grade_items tag
1490 $status = fwrite ($bf,end_tag("GRADE_ITEMS",5,true));
1493 return $status;
1496 //Backup gradebook_exceptions (called from backup_gradebook_item_info
1497 function backup_gradebook_exceptions_info($bf,$preferences,$gradeitemid) {
1499 global $CFG;
1501 $status = true;
1503 //Output grade_exceptions (only for users included in backup)
1504 $grade_exceptions = get_records_sql("SELECT *
1505 FROM {$CFG->prefix}grade_exceptions
1506 WHERE courseid = $preferences->backup_course AND
1507 grade_itemid = $gradeitemid");
1508 //Filter exceptions about users not included in backup
1509 $inc_grade_exceptions = array();
1510 if ($grade_exceptions) {
1511 foreach ($grade_exceptions as $grade_exception) {
1512 //Check if user has been included in backup
1513 $rec_user = get_record ("backup_ids","backup_code",$preferences->backup_unique_code,
1514 "table_name","user",
1515 "old_id",$grade_exception->userid);
1516 //If it's included in backup
1517 if ($rec_user) {
1518 //Add it
1519 $inc_grade_exceptions[] = $grade_exception;
1520 } else {
1521 debugging("skipping $grade_exception->userid"."-user<br />");
1525 if ($inc_grade_exceptions) {
1526 //Begin grade_exceptions tag
1527 fwrite ($bf,start_tag("GRADE_EXCEPTIONS",7,true));
1528 //Iterate for each exception
1529 foreach ($inc_grade_exceptions as $grade_exception) {
1530 //Begin grade_exception
1531 fwrite ($bf,start_tag("GRADE_EXCEPTION",8,true));
1532 //Output individual fields
1533 fwrite ($bf,full_tag("USERID",9,false,$grade_exception->userid));
1534 //End grade_exception
1535 fwrite ($bf,end_tag("GRADE_EXCEPTION",8,true));
1537 //End grade_exceptions tag
1538 $status = fwrite ($bf,end_tag("GRADE_EXCEPTIONS",7,true));
1541 return $status;
1544 //Backup scales info (common and course scales)
1545 function backup_scales_info($bf,$preferences) {
1547 global $CFG;
1549 $status = true;
1551 //Counter, points to current record
1552 $counter = 0;
1554 //Get scales (common and course scales)
1555 $scales = get_records_sql("SELECT id, courseid, userid, name, scale, description, timemodified
1556 FROM {$CFG->prefix}scale
1557 WHERE courseid = '0' or courseid = $preferences->backup_course");
1559 //Copy only used scales to $backupscales. They will be in backup (unused no). See Bug 1223.
1560 $backupscales = array();
1561 if ($scales) {
1562 foreach ($scales as $scale) {
1563 if (course_scale_used($preferences->backup_course, $scale->id)) {
1564 $backupscales[] = $scale;
1569 //Pring scales header
1570 if ($backupscales) {
1571 //Pring scales header
1572 fwrite ($bf,start_tag("SCALES",2,true));
1573 //Iterate
1574 foreach ($backupscales as $scale) {
1575 //Begin scale tag
1576 fwrite ($bf,start_tag("SCALE",3,true));
1577 //Output scale tag
1578 fwrite ($bf,full_tag("ID",4,false,$scale->id));
1579 fwrite ($bf,full_tag("COURSEID",4,false,$scale->courseid));
1580 fwrite ($bf,full_tag("USERID",4,false,$scale->userid));
1581 fwrite ($bf,full_tag("NAME",4,false,$scale->name));
1582 fwrite ($bf,full_tag("SCALETEXT",4,false,$scale->scale));
1583 fwrite ($bf,full_tag("DESCRIPTION",4,false,$scale->description));
1584 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$scale->timemodified));
1585 //End scale tag
1586 fwrite ($bf,end_tag("SCALE",3,true));
1588 //End scales tag
1589 $status = fwrite ($bf,end_tag("SCALES",2,true));
1591 return $status;
1594 //Backup events info (course events)
1595 function backup_events_info($bf,$preferences) {
1597 global $CFG;
1599 $status = true;
1601 //Counter, points to current record
1602 $counter = 0;
1604 //Get events (course events)
1605 $events = get_records_select("event","courseid='$preferences->backup_course' AND instance='0'","id");
1607 //Pring events header
1608 if ($events) {
1609 //Pring events header
1610 fwrite ($bf,start_tag("EVENTS",2,true));
1611 //Iterate
1612 foreach ($events as $event) {
1613 //Begin event tag
1614 fwrite ($bf,start_tag("EVENT",3,true));
1615 //Output event tag
1616 fwrite ($bf,full_tag("ID",4,false,$event->id));
1617 fwrite ($bf,full_tag("NAME",4,false,$event->name));
1618 fwrite ($bf,full_tag("DESCRIPTION",4,false,$event->description));
1619 fwrite ($bf,full_tag("FORMAT",4,false,$event->format));
1620 fwrite ($bf,full_tag("GROUPID",4,false,$event->groupid));
1621 fwrite ($bf,full_tag("USERID",4,false,$event->userid));
1622 fwrite ($bf,full_tag("REPEATID",4,false,$event->repeatid));
1623 fwrite ($bf,full_tag("EVENTTYPE",4,false,$event->eventtype));
1624 fwrite ($bf,full_tag("TIMESTART",4,false,$event->timestart));
1625 fwrite ($bf,full_tag("TIMEDURATION",4,false,$event->timeduration));
1626 fwrite ($bf,full_tag("VISIBLE",4,false,$event->visible));
1627 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$event->timemodified));
1628 //End event tag
1629 fwrite ($bf,end_tag("EVENT",3,true));
1631 //End events tag
1632 $status = fwrite ($bf,end_tag("EVENTS",2,true));
1634 return $status;
1637 //Backup groups info
1638 function backup_groups_info($bf,$preferences) {
1640 global $CFG;
1642 $status = true;
1643 $status2 = true;
1645 //Get groups
1646 $groups = get_groups($preferences->backup_course); //TODO:check.
1648 //Pring groups header
1649 if ($groups) {
1650 //Pring groups header
1651 fwrite ($bf,start_tag("GROUPS",2,true));
1652 //Iterate
1653 foreach ($groups as $group) {
1654 //Begin group tag
1655 fwrite ($bf,start_tag("GROUP",3,true));
1656 //Output group contents
1657 fwrite ($bf,full_tag("ID",4,false,$group->id));
1658 ///fwrite ($bf,full_tag("COURSEID",4,false,$group->courseid));
1659 fwrite ($bf,full_tag("NAME",4,false,$group->name));
1660 fwrite ($bf,full_tag("DESCRIPTION",4,false,$group->description));
1661 fwrite ($bf,full_tag("ENROLMENTKEY",4,false,$group->enrolmentkey)); //TODO:
1662 fwrite ($bf,full_tag("LANG",4,false,$group->lang));
1663 fwrite ($bf,full_tag("THEME",4,false,$group->theme));
1664 fwrite ($bf,full_tag("PICTURE",4,false,$group->picture));
1665 fwrite ($bf,full_tag("HIDEPICTURE",4,false,$group->hidepicture));
1666 fwrite ($bf,full_tag("TIMECREATED",4,false,$group->timecreated));
1667 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$group->timemodified));
1669 //Now, backup groups_members, only if users are included
1670 if ($preferences->backup_users != 2) {
1671 $status2 = backup_groups_members_info($bf,$preferences,$group->id);
1674 //End group tag
1675 fwrite ($bf,end_tag("GROUP",3,true));
1677 //End groups tag
1678 $status = fwrite ($bf,end_tag("GROUPS",2,true));
1680 //Now save group_files
1681 if ($status && $status2) {
1682 $status2 = backup_copy_group_files($preferences);
1685 return ($status && $status2);
1688 //Backup groups_members info
1689 function backup_groups_members_info($bf,$preferences,$groupid) {
1691 global $CFG;
1693 $status = true;
1695 //Get groups_members
1696 $groups_members = groups_get_member_records($groupid);
1698 //Pring groups_members header
1699 if ($groups_members) {
1700 //Pring groups_members header
1701 fwrite ($bf,start_tag("MEMBERS",4,true));
1702 //Iterate
1703 foreach ($groups_members as $group_member) {
1704 //Begin group_member tag
1705 fwrite ($bf,start_tag("MEMBER",5,true));
1706 //Output group_member contents
1707 fwrite ($bf,full_tag("USERID",6,false,$group_member->userid));
1708 fwrite ($bf,full_tag("TIMEADDED",6,false,$group_member->timeadded));
1709 //End group_member tag
1710 fwrite ($bf,end_tag("MEMBER",5,true));
1712 //End groups_members tag
1713 $status = fwrite ($bf,end_tag("MEMBERS",4,true));
1715 return $status;
1718 //Backup groupings info
1719 function backup_groupings_info($bf,$preferences) {
1721 global $CFG;
1723 $status = true;
1724 $status2 = true;
1726 //Get groups
1727 $groupings = groups_get_grouping_records($preferences->backup_course);
1729 //Pring groups header
1730 if ($groupings) {
1731 //Pring groups header
1732 fwrite ($bf,start_tag("GROUPINGS",2,true));
1733 //Iterate
1734 foreach ($groupings as $grouping) {
1735 //Begin group tag
1736 fwrite ($bf,start_tag("GROUPING",3,true));
1737 //Output group contents
1738 fwrite ($bf,full_tag("ID",4,false,$grouping->id));
1739 fwrite ($bf,full_tag("NAME",4,false,$grouping->name));
1740 fwrite ($bf,full_tag("DESCRIPTION",4,false,$grouping->description));
1741 fwrite ($bf,full_tag("TIMECREATED",4,false,$grouping->timecreated));
1743 $status2 = backup_groupids_info($bf,$preferences,$grouping->id);
1745 //End group tag
1746 fwrite ($bf,end_tag("GROUPING",3,true));
1748 //End groups tag
1749 $status = fwrite ($bf,end_tag("GROUPINGS",2,true));
1751 //(Now save grouping_files)
1753 return ($status && $status2);
1756 //Backup groupings-groups info
1757 function backup_groupids_info($bf,$preferences,$groupingid) {
1759 global $CFG;
1761 $status = true;
1763 //Get groups_members
1764 $grouping_groups = groups_get_groups_in_grouping_records($groupingid) ;
1766 //Pring groups_members header
1767 if ($grouping_groups) {
1768 //Pring groups_members header
1769 fwrite ($bf,start_tag("GROUPS",4,true));
1770 //Iterate
1771 foreach ($grouping_groups as $group2) {
1772 //Begin group tag
1773 fwrite ($bf,start_tag("GROUP",5,true));
1774 //Output group_member contents
1775 fwrite ($bf,full_tag("GROUPID",6,false,$group2->groupid));
1776 fwrite ($bf,full_tag("TIMEADDED",6,false,$group2->timeadded)); //TODO:
1777 //End group tag
1778 fwrite ($bf,end_tag("GROUP",5,true));
1780 //End groups_members tag
1781 $status = fwrite ($bf,end_tag("GROUPS",4,true));
1783 return $status;
1786 //Start the modules tag
1787 function backup_modules_start ($bf,$preferences) {
1789 return fwrite ($bf,start_tag("MODULES",2,true));
1792 //End the modules tag
1793 function backup_modules_end ($bf,$preferences) {
1795 return fwrite ($bf,end_tag("MODULES",2,true));
1798 //This function makes all the necesary calls to every mod
1799 //to export itself and its files !!!
1800 function backup_module($bf,$preferences,$module) {
1802 global $CFG;
1804 $status = true;
1806 require_once($CFG->dirroot.'/mod/'.$module.'/backuplib.php');
1808 if (isset($preferences->mods[$module]->instances)
1809 && is_array($preferences->mods[$module]->instances)) {
1810 $onemodbackup = $module.'_backup_one_mod';
1811 if (function_exists($onemodbackup)) {
1812 foreach ($preferences->mods[$module]->instances as $instance => $object) {
1813 if (!empty($object->backup)) {
1814 $status = $onemodbackup($bf,$preferences,$instance);
1817 } else {
1818 $status = false;
1820 } else { // whole module.
1821 //First, re-check if necessary functions exists
1822 $modbackup = $module."_backup_mods";
1823 if (function_exists($modbackup)) {
1824 //Call the function
1825 $status = $modbackup($bf,$preferences);
1826 } else {
1827 //Something was wrong. Function should exist.
1828 $status = false;
1832 return $status;
1836 //This function encode things to make backup multi-site fully functional
1837 //It does this conversions:
1838 // - $CFG->wwwroot/file.php/courseid ------------------> $@FILEPHP@$ (slasharguments links)
1839 // - $CFG->wwwroot/file.php?file=/courseid ------------> $@FILEPHP@$ (non-slasharguments links)
1840 // - Every module xxxx_encode_content_links() is executed too
1842 function backup_encode_absolute_links($content) {
1844 global $CFG,$preferences;
1846 //Check if preferences is ok. If it isn't set, we are
1847 //in a scheduled_backup to we are able to get a copy
1848 //from CFG->backup_preferences
1849 if (!isset($preferences)) {
1850 $mypreferences = $CFG->backup_preferences;
1851 } else {
1852 //We are in manual backups so global preferences must exist!!
1853 $mypreferences = $preferences;
1856 //First, we check for every call to file.php inside the course
1857 $search = array($CFG->wwwroot.'/file.php/'.$mypreferences->backup_course,
1858 $CFG->wwwroot.'/file.php?file=/'.$mypreferences->backup_course);
1860 $replace = array('$@FILEPHP@$','$@FILEPHP@$');
1862 $result = str_replace($search,$replace,$content);
1864 foreach ($mypreferences->mods as $name => $info) {
1865 //Check if the xxxx_encode_content_links exists
1866 include_once("$CFG->dirroot/mod/$name/backuplib.php");
1867 $function_name = $name."_encode_content_links";
1868 if (function_exists($function_name)) {
1869 $result = $function_name($result,$mypreferences);
1873 if ($result != $content) {
1874 debugging('<br /><hr />'.s($content).'<br />changed to<br />'.s($result).'<hr /><br />');
1877 return $result;
1880 //This function copies all the needed files under the "users" directory to the "user_files"
1881 //directory under temp/backup
1882 function backup_copy_user_files ($preferences) {
1884 global $CFG;
1886 $status = true;
1888 //First we check to "user_files" exists and create it as necessary
1889 //in temp/backup/$backup_code dir
1890 $status = check_and_create_user_files_dir($preferences->backup_unique_code);
1892 //Now iterate over directories under "users" to check if that user must be
1893 //copied to backup
1895 $rootdir = $CFG->dataroot."/users";
1896 //Check if directory exists
1897 if (is_dir($rootdir)) {
1898 $list = list_directories ($rootdir);
1899 if ($list) {
1900 //Iterate
1901 foreach ($list as $dir) {
1902 //Look for dir like username in backup_ids
1903 $data = get_record ("backup_ids","backup_code",$preferences->backup_unique_code,
1904 "table_name","user",
1905 "old_id",$dir);
1906 //If exists, copy it
1907 if ($data) {
1908 $status = backup_copy_file($rootdir."/".$dir,
1909 $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/user_files/".$dir);
1915 return $status;
1918 //This function copies all the needed files under the "groups" directory to the "group_files"
1919 //directory under temp/backup
1920 function backup_copy_group_files ($preferences) {
1922 global $CFG;
1924 $status = true;
1926 //First we check if "group_files" exists and create it as necessary
1927 //in temp/backup/$backup_code dir
1928 $status = check_and_create_group_files_dir($preferences->backup_unique_code);
1930 //Now iterate over directories under "groups" to check if that user must be
1931 //copied to backup
1933 $rootdir = $CFG->dataroot.'/groups';
1934 //Check if directory exists
1935 if (is_dir($rootdir)) {
1936 $list = list_directories ($rootdir);
1937 if ($list) {
1938 //Iterate
1939 foreach ($list as $dir) {
1940 //Look for dir like group in groups table
1941 $data = groups_group_belongs_to_course($dir, $preferences->backup_course);
1942 //TODO:check. get_record ('groups', 'courseid', $preferences->backup_course,'id',$dir);
1943 //If exists, copy it
1944 if ($data) {
1945 $status = backup_copy_file($rootdir."/".$dir,
1946 $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/group_files/".$dir);
1951 return $status;
1954 //This function copies all the course files under the course directory (except the moddata
1955 //directory to the "course_files" directory under temp/backup
1956 function backup_copy_course_files ($preferences) {
1958 global $CFG;
1960 $status = true;
1962 //First we check to "course_files" exists and create it as necessary
1963 //in temp/backup/$backup_code dir
1964 $status = check_and_create_course_files_dir($preferences->backup_unique_code);
1966 //Now iterate over files and directories except $CFG->moddata and backupdata to be
1967 //copied to backup
1969 $rootdir = $CFG->dataroot."/".$preferences->backup_course;
1971 $name_moddata = $CFG->moddata;
1972 $name_backupdata = "backupdata";
1973 //Check if directory exists
1974 if (is_dir($rootdir)) {
1975 $list = list_directories_and_files ($rootdir);
1976 if ($list) {
1977 //Iterate
1978 foreach ($list as $dir) {
1979 if ($dir !== $name_moddata and $dir !== $name_backupdata) {
1980 $status = backup_copy_file($rootdir."/".$dir,
1981 $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/course_files/".$dir);
1986 return $status;
1989 //This function creates the zip file containing all the backup info
1990 //moodle.xml, moddata, user_files, course_files.
1991 //The zipped file is created in the backup directory and named with
1992 //the "oficial" name of the backup
1993 //It uses "pclzip" if available or system "zip" (unix only)
1994 function backup_zip ($preferences) {
1996 global $CFG;
1998 $status = true;
2000 //Base dir where everything happens
2001 $basedir = cleardoubleslashes($CFG->dataroot."/temp/backup/".$preferences->backup_unique_code);
2002 //Backup zip file name
2003 $name = $preferences->backup_name;
2004 //List of files and directories
2005 $filelist = list_directories_and_files ($basedir);
2007 //Convert them to full paths
2008 $files = array();
2009 foreach ($filelist as $file) {
2010 $files[] = "$basedir/$file";
2013 $status = zip_files($files, "$basedir/$name");
2015 //echo "<br/>Status: ".$status; //Debug
2016 return $status;
2020 //This function copies the final zip to the course dir
2021 function copy_zip_to_course_dir ($preferences) {
2023 global $CFG;
2025 $status = true;
2027 //Define zip location (from)
2028 $from_zip_file = $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/".$preferences->backup_name;
2030 //Initialise $to_zip_file
2031 $to_zip_file="";
2033 //If $preferences->backup_destination isn't empty, then copy to custom directory
2034 if (!empty($preferences->backup_destination)) {
2035 $to_zip_file = $preferences->backup_destination."/".$preferences->backup_name;
2036 } else {
2037 //Define zip destination (course dir)
2038 $to_zip_file = $CFG->dataroot."/".$preferences->backup_course;
2040 //echo "<p>From: ".$from_zip_file."<br />"; //Debug
2042 //echo "<p>Checking: ".$to_zip_file."<br />"; //Debug
2044 //Checks course dir exists
2045 $status = check_dir_exists($to_zip_file,true);
2047 //Define zip destination (backup dir)
2048 $to_zip_file = $to_zip_file."/backupdata";
2050 //echo "<p>Checking: ".$to_zip_file."<br />"; //Debug
2052 //Checks backup dir exists
2053 $status = check_dir_exists($to_zip_file,true);
2055 //Define zip destination (zip file)
2056 $to_zip_file = $to_zip_file."/".$preferences->backup_name;
2059 //echo "<p>To: ".$to_zip_file."<br />"; //Debug
2061 //Copy zip file
2062 if ($status) {
2063 $status = backup_copy_file ($from_zip_file,$to_zip_file);
2066 return $status;
2069 /**
2070 * compatibility function
2071 * with new granular backup
2072 * we need to know
2074 function backup_userdata_selected($preferences,$modname,$modid) {
2075 return ((empty($preferences->mods[$modname]->instances)
2076 && !empty($preferences->mods[$modname]->userinfo))
2077 || (is_array($preferences->mods[$modname]->instances)
2078 && array_key_exists($modid,$preferences->mods[$modname]->instances)
2079 && !empty($preferences->mods[$modname]->instances[$modid]->userinfo)));
2083 function backup_mod_selected($preferences,$modname,$modid) {
2084 return ((empty($preferences->mods[$modname]->instances)
2085 && !empty($preferences->mods[$modname]->backup))
2086 || (is_array($preferences->mods[$modname]->instances)
2087 && array_key_exists($modid,$preferences->mods[$modname]->instances)
2088 && !empty($preferences->mods[$modname]->instances[$modid]->backup)));
2092 * Checks for the required files/functions to backup every mod
2093 * And check if there is data about it
2095 function backup_fetch_prefs_from_request(&$preferences,&$count,$course) {
2096 global $CFG,$SESSION;
2098 // check to see if it's in the session already
2099 if (!empty($SESSION->backupprefs) && array_key_exists($course->id,$SESSION->backupprefs) && !empty($SESSION->backupprefs[$course->id])) {
2100 $sprefs = $SESSION->backupprefs[$course->id];
2101 $preferences = $sprefs;
2102 // refetch backup_name just in case.
2103 $bn = optional_param('backup_name','',PARAM_FILE);
2104 if (!empty($bn)) {
2105 $preferences->backup_name = $bn;
2107 $count = 1;
2108 return true;
2111 if ($allmods = get_records("modules") ) {
2112 foreach ($allmods as $mod) {
2113 $modname = $mod->name;
2114 $modfile = "$CFG->dirroot/mod/$modname/backuplib.php";
2115 $modbackup = $modname."_backup_mods";
2116 $modbackupone = $modname."_backup_one_mod";
2117 $modcheckbackup = $modname."_check_backup_mods";
2118 if (!file_exists($modfile)) {
2119 continue;
2121 include_once($modfile);
2122 if (!function_exists($modbackup) || !function_exists($modcheckbackup)) {
2123 continue;
2125 $var = "exists_".$modname;
2126 $preferences->$var = true;
2127 $count++;
2128 // check that there are instances and we can back them up individually
2129 if (!count_records('course_modules','course',$course->id,'module',$mod->id) || !function_exists($modbackupone)) {
2130 continue;
2132 $var = 'exists_one_'.$modname;
2133 $preferences->$var = true;
2134 $varname = $modname.'_instances';
2135 $preferences->$varname = get_all_instances_in_course($modname,$course);
2136 foreach ($preferences->$varname as $instance) {
2137 $preferences->mods[$modname]->instances[$instance->id]->name = $instance->name;
2138 $var = 'backup_'.$modname.'_instance_'.$instance->id;
2139 $$var = optional_param($var,0);
2140 $preferences->$var = $$var;
2141 $preferences->mods[$modname]->instances[$instance->id]->backup = $$var;
2142 $var = 'backup_user_info_'.$modname.'_instance_'.$instance->id;
2143 $$var = optional_param($var,0);
2144 $preferences->$var = $$var;
2145 $preferences->mods[$modname]->instances[$instance->id]->userinfo = $$var;
2146 $var = 'backup_'.$modname.'_instances';
2147 $preferences->$var = 1; // we need this later to determine what to display in modcheckbackup.
2150 //Check data
2151 //Check module info
2152 $preferences->mods[$modname]->name = $modname;
2154 $var = "backup_".$modname;
2155 $$var = optional_param( $var,0);
2156 $preferences->$var = $$var;
2157 $preferences->mods[$modname]->backup = $$var;
2159 //Check include user info
2160 $var = "backup_user_info_".$modname;
2161 $$var = optional_param( $var,0);
2162 $preferences->$var = $$var;
2163 $preferences->mods[$modname]->userinfo = $$var;
2168 //Check other parameters
2169 $preferences->backup_metacourse = optional_param('backup_metacourse',1,PARAM_INT);
2170 $preferences->backup_users = optional_param('backup_users',1,PARAM_INT);
2171 $preferences->backup_logs = optional_param('backup_logs',0,PARAM_INT);
2172 $preferences->backup_user_files = optional_param('backup_user_files',1,PARAM_INT);
2173 $preferences->backup_course_files = optional_param('backup_course_files',1,PARAM_INT);
2174 $preferences->backup_messages = optional_param('backup_messages',1,PARAM_INT);
2175 $preferences->backup_course = $course->id;
2176 $preferences->backup_name = required_param('backup_name',PARAM_FILE);
2177 $preferences->backup_unique_code = required_param('backup_unique_code');
2179 // put it (back) in the session
2180 $SESSION->backupprefs[$course->id] = $preferences;
2183 /* Finds all related roles used in course, mod and blocks context
2184 * @param object $preferences
2185 * @param object $course
2186 * @return array of role objects
2188 function backup_fetch_roles($preferences) {
2190 global $CFG;
2191 $contexts = array();
2192 $roles = array();
2194 /// adding course context
2195 $coursecontext = get_context_instance(CONTEXT_COURSE, $preferences->backup_course);
2196 $contexts[$coursecontext->id] = $coursecontext;
2198 /// adding mod contexts
2199 $mods = $preferences->mods;
2200 foreach ($mods as $modname => $mod) {
2201 $instances = $mod->instances;
2202 foreach ($instances as $id => $instance) {
2203 // if this type of mod is to be backed up
2204 if ($instance->backup) {
2205 $cm = get_coursemodule_from_instance($modname, $id);
2206 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
2207 // put context in array keys
2208 $contexts[$context->id] = $context;
2213 // add all roles assigned at user context
2214 if ($preferences->backup_users) {
2215 if ($users = get_records_sql("SELECT u.old_id, u.table_name,u.info
2216 FROM {$CFG->prefix}backup_ids u
2217 WHERE u.backup_code = '$preferences->backup_unique_code' AND
2218 u.table_name = 'user'")) {
2219 foreach ($users as $user) {
2220 $context = get_context_instance(CONTEXT_USER, $user->old_id);
2221 $contexts[$context->id] = $context;
2227 // add all roles assigned at block context
2228 if ($courseblocks = get_records_sql("SELECT *
2229 FROM {$CFG->prefix}block_instance
2230 WHERE pagetype = '".PAGE_COURSE_VIEW."'
2231 AND pageid = {$preferences->backup_course}")) {
2233 foreach ($courseblocks as $courseblock) {
2235 $context = get_context_instance(CONTEXT_BLOCK, $courseblock->id);
2236 $contexts[$context->id] = $context;
2240 // foreach context, call get_roles_on_exact_context insert into array
2241 foreach ($contexts as $context) {
2242 if ($proles = get_roles_on_exact_context($context)) {
2243 foreach ($proles as $prole) {
2244 $roles[$prole->id] = $prole;
2249 return $roles;
2252 /* function to print xml for overrides */
2253 function write_role_overrides_xml($bf, $context, $startlevel) {
2254 fwrite ($bf, start_tag("ROLES_OVERRIDES", $startlevel, true));
2255 if ($roles = get_roles_with_override_on_context($context)) {
2256 foreach ($roles as $role) {
2257 fwrite ($bf, start_tag("ROLE", $startlevel+1, true));
2258 fwrite ($bf, full_tag("ID", $startlevel+2, false, $role->id));
2259 fwrite ($bf, full_tag("NAME", $startlevel+2, false, $role->name));
2260 fwrite ($bf, full_tag("SHORTNAME", $startlevel+2, false, $role->shortname));
2261 fwrite ($bf, start_tag("CAPABILITIES", $startlevel+2, true));
2262 if ($capabilities = get_capabilities_from_role_on_context($role, $context)) {
2263 foreach ($capabilities as $capability) {
2264 fwrite ($bf, start_tag("CAPABILITY", $startlevel+3, true));
2265 fwrite ($bf, full_tag("NAME", $startlevel+4, false, $capability->capability));
2266 fwrite ($bf, full_tag("PERMISSION", $startlevel+4, false, $capability->permission));
2267 fwrite ($bf, full_tag("TIMEMODIFIED", $startlevel+4, false, $capability->timemodified));
2268 if (!isset($capability->modifierid)) {
2269 $capability->modifierid = 0;
2271 fwrite ($bf, full_tag("MODIFIERID", $startlevel+4, false, $capability->modifierid));
2272 fwrite ($bf, end_tag("CAPABILITY", $startlevel+3, true));
2275 fwrite ($bf, end_tag("CAPABILITIES", $startlevel+2, true));
2276 fwrite ($bf, end_tag("ROLE", $startlevel+1, true));
2279 fwrite ($bf, end_tag("ROLES_OVERRIDES", $startlevel, true));
2282 /* function to print xml for assignment */
2283 function write_role_assignments_xml($bf, $context, $startlevel) {
2284 /// write role_assign code here
2285 fwrite ($bf, start_tag("ROLES_ASSIGNMENTS", $startlevel, true));
2287 if ($roles = get_roles_with_assignment_on_context($context)) {
2288 foreach ($roles as $role) {
2289 fwrite ($bf, start_tag("ROLE", $startlevel+1, true));
2290 fwrite ($bf, full_tag("ID", $startlevel+2, false, $role->id));
2291 fwrite ($bf, full_tag("NAME", $startlevel+2, false, $role->name));
2292 fwrite ($bf, full_tag("SHORTNAME", $startlevel+2, false, $role->shortname));
2293 fwrite ($bf, start_tag("ASSIGNMENTS", $startlevel+2, true));
2294 if ($assignments = get_users_from_role_on_context($role, $context)) {
2295 foreach ($assignments as $assignment) {
2296 fwrite ($bf, start_tag("ASSIGNMENT", $startlevel+3, true));
2297 fwrite ($bf, full_tag("USERID", $startlevel+4, false, $assignment->userid));
2298 fwrite ($bf, full_tag("HIDDEN", $startlevel+4, false, $assignment->hidden));
2299 fwrite ($bf, full_tag("TIMESTART", $startlevel+4, false, $assignment->timestart));
2300 fwrite ($bf, full_tag("TIMEEND", $startlevel+4, false, $assignment->timeend));
2301 fwrite ($bf, full_tag("TIMEMODIFIED", $startlevel+4, false, $assignment->timemodified));
2302 if (!isset($assignment->modifierid)) {
2303 $assignment->modifierid = 0;
2305 fwrite ($bf, full_tag("MODIFIERID", $startlevel+4, false, $assignment->modifierid));
2306 fwrite ($bf, full_tag("ENROL", $startlevel+4, false, $assignment->enrol));
2307 fwrite ($bf, full_tag("SORTORDER", $startlevel+4, false, $assignment->sortorder));
2308 fwrite ($bf, end_tag("ASSIGNMENT", $startlevel+3, true));
2311 fwrite ($bf, end_tag("ASSIGNMENTS", $startlevel+2, true));
2312 fwrite ($bf, end_tag("ROLE", $startlevel+1, true));
2315 fwrite ($bf, end_tag("ROLES_ASSIGNMENTS", $startlevel, true));