Typo: should be $COURSE not $course it seems
[moodle-linuxchix.git] / backup / backuplib.php
blob7f77ac4c7eb8e745a5cf60f7fbb9d7f1d08db27f
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 $db, $CFG;
15 $context = get_context_instance(CONTEXT_COURSE, $course);
16 $count_users = 0;
18 //If we've selected none, simply return 0
19 if ($backup_users == 0 or $backup_users == 1) {
21 //Calculate needed users (calling every xxxx_get_participants function + scales users)
22 $needed_users = backup_get_needed_users($course, $backup_messages);
24 //Calculate enrolled users (students + teachers)
25 $enrolled_users = backup_get_enrolled_users($course);
27 //Calculate all users (every record in users table)
28 $all_users = backup_get_all_users();
30 //Calculate course users (needed + enrolled)
31 //First, needed
32 $course_users = $needed_users;
34 //Now, enrolled
35 if ($enrolled_users) {
36 foreach ($enrolled_users as $enrolled_user) {
37 $course_users[$enrolled_user->id]->id = $enrolled_user->id;
41 //Now, depending of parameters, create $backupable_users
42 if ($backup_users == 0) {
43 $backupable_users = $all_users;
44 } else {
45 $backupable_users = $course_users;
48 //If we have backupable users
49 if ($backupable_users) {
50 //Iterate over users putting their roles
51 foreach ($backupable_users as $backupable_user) {
52 $backupable_user->info = "";
54 //Is needed user (exists in needed_users)
55 if (isset($needed_users[$backupable_user->id])) {
56 $backupable_user->info .= "needed";
57 } else if (isset($course_users[$backupable_user->id])) {
58 $backupable_user->info .= "needed";
59 } // Yu: also needed because they can view course
60 // might need another variable
62 //Now create the backup_id record
63 $backupids_rec->backup_code = $backup_unique_code;
64 $backupids_rec->table_name = "user";
65 $backupids_rec->old_id = $backupable_user->id;
66 $backupids_rec->info = $backupable_user->info;
68 //Insert the record id. backup_users decide it.
69 //When all users
70 $status = insert_record('backup_ids', $backupids_rec, false);
71 $count_users++;
73 //Do some output
74 backup_flush(30);
78 //Prepare Info
79 //Gets the user data
80 $info[0][0] = get_string("users");
81 $info[0][1] = $count_users;
83 return $info;
86 //Returns every needed user (participant) in a course
87 //It uses the xxxx_get_participants() function
88 //plus users needed to backup scales.
89 //WARNING: It returns only NEEDED users, not every
90 // every student and teacher in the course, so it
91 //must be merged with backup_get_enrrolled_users !!
93 function backup_get_needed_users ($courseid, $includemessages=false) {
95 global $CFG;
97 $result = false;
99 $course_modules = get_records_sql ("SELECT cm.id, m.name, cm.instance
100 FROM {$CFG->prefix}modules m,
101 {$CFG->prefix}course_modules cm
102 WHERE m.id = cm.module and
103 cm.course = '$courseid'");
105 if ($course_modules) {
106 //Iterate over each module
107 foreach ($course_modules as $course_module) {
108 $modlib = "$CFG->dirroot/mod/$course_module->name/lib.php";
109 $modgetparticipants = $course_module->name."_get_participants";
110 if (file_exists($modlib)) {
111 include_once($modlib);
112 if (function_exists($modgetparticipants)) {
113 $module_participants = $modgetparticipants($course_module->instance);
114 //Add them to result
115 if ($module_participants) {
116 foreach ($module_participants as $module_participant) {
117 $result[$module_participant->id]->id = $module_participant->id;
125 //Now, add scale users (from site and course scales)
126 //Get users
127 $scaleusers = get_records_sql("SELECT DISTINCT userid,userid
128 FROM {$CFG->prefix}scale
129 WHERE courseid = '0' or courseid = '$courseid'");
130 //Add scale users to results
131 if ($scaleusers) {
132 foreach ($scaleusers as $scaleuser) {
133 //If userid != 0
134 if ($scaleuser->userid != 0) {
135 $result[$scaleuser->userid]->id = $scaleuser->userid;
140 //Now, add message users if necessary
141 if ($includemessages) {
142 include_once("$CFG->dirroot/message/lib.php");
143 //Get users
144 $messageusers = message_get_participants();
145 //Add message users to results
146 if ($messageusers) {
147 foreach ($messageusers as $messageuser) {
148 //If id != 0
149 if ($messageuser->id !=0) {
150 $result[$messageuser->id]->id = $messageuser->id;
156 return $result;
160 //Returns every enrolled user (student and teacher) in a course
162 function backup_get_enrolled_users ($courseid) {
164 global $CFG;
166 // get all users with moodle/course:view capability, this will include people
167 // assigned at cat level, or site level
168 // but it should be ok if they have no direct assignment at course, mod, block level
169 return get_users_by_capability(get_context_instance(CONTEXT_COURSE, $courseid), 'moodle/course:view');
172 //Returns all users ids (every record in users table)
173 function backup_get_all_users() {
175 return get_records('user', '', '', '', 'id, id');
178 //Calculate the number of log entries to backup
179 //Return an array of info (name,value)
180 function log_check_backup($course) {
182 global $CFG;
184 //Now execute the count
185 $ids = count_records("log","course",$course);
187 //Gets the user data
188 $info[0][0] = get_string("logs");
189 if ($ids) {
190 $info[0][1] = $ids;
191 } else {
192 $info[0][1] = 0;
195 return $info;
198 //Calculate the number of user files to backup
199 //Under $CFG->dataroot/users
200 //and put them (their path) in backup_ids
201 //Return an array of info (name,value)
202 function user_files_check_backup($course,$backup_unique_code) {
204 global $CFG;
206 $rootdir = $CFG->dataroot."/users";
207 //Check if directory exists
208 if (is_dir($rootdir)) {
209 //Get directories without descend
210 $userdirs = get_directory_list($rootdir,"",false,true,false);
211 foreach ($userdirs as $dir) {
212 //Extracts user id from file path
213 $tok = strtok($dir,"/");
214 if ($tok) {
215 $userid = $tok;
216 } else {
217 //We were getting $dir='0', so continue (WAS: $tok = "";)
218 continue;
220 //Look it is a backupable user
221 $data = get_record ("backup_ids","backup_code","$backup_unique_code",
222 "table_name","user",
223 "old_id",$userid);
224 if ($data) {
225 //Insert them into backup_files
226 $status = execute_sql("INSERT INTO {$CFG->prefix}backup_files
227 (backup_code, file_type, path, old_id)
228 VALUES
229 ('$backup_unique_code','user','".addslashes($dir)."','$userid')",false);
231 //Do some output
232 backup_flush(30);
236 //Now execute the select
237 $ids = get_records_sql("SELECT DISTINCT b.path, b.old_id
238 FROM {$CFG->prefix}backup_files b
239 WHERE backup_code = '$backup_unique_code' AND
240 file_type = 'user'");
241 //Gets the user data
242 $info[0][0] = get_string("files");
243 if ($ids) {
244 $info[0][1] = count($ids);
245 } else {
246 $info[0][1] = 0;
249 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)
258 function course_files_check_backup($course, $backup_unique_code) {
260 global $CFG;
262 $rootdir = $CFG->dataroot."/$course";
263 //Check if directory exists
264 if (is_dir($rootdir)) {
265 //Get files and directories without descend
266 $coursedirs = get_directory_list($rootdir,$CFG->moddata,false,true,true);
267 $backupdata_dir = "backupdata";
268 foreach ($coursedirs as $dir) {
269 //Check it isn't backupdata_dir
270 if (strpos($dir,$backupdata_dir)!==0) {
271 //Insert them into backup_files
272 $status = execute_sql("INSERT INTO {$CFG->prefix}backup_files
273 (backup_code, file_type, path)
274 VALUES
275 ('$backup_unique_code','course','".addslashes($dir)."')",false);
277 //Do some output
278 backup_flush(30);
282 //Now execute the select
283 $ids = get_records_sql("SELECT DISTINCT b.path, b.old_id
284 FROM {$CFG->prefix}backup_files b
285 WHERE backup_code = '$backup_unique_code' AND
286 file_type = 'course'");
287 //Gets the user data
288 $info = array();
289 $info[0] = array();
290 $info[0][0] = get_string("files");
291 if ($ids) {
292 $info[0][1] = count($ids);
293 } else {
294 $info[0][1] = 0;
297 return $info;
301 * Calculate the number of site files to backup
302 * under $CFG->dataroot/SITEID
303 * Their path is already in backup_ids, put there by modules check_backup functions.
304 * Modules only put in paths of files that are used.
306 * Return an array of info (name,value)
308 function site_files_check_backup($course, $backup_unique_code) {
309 global $CFG;
311 //execute the select, records have been inserted by modules during their ****_check_backup_mods function.
312 $ids = get_records_sql("SELECT DISTINCT b.path
313 FROM {$CFG->prefix}backup_files b
314 WHERE backup_code = '$backup_unique_code' AND
315 file_type = 'site'");
316 //Gets the user data
317 $info = array();
318 $info[0] = array();
319 $info[0][0] = get_string('files');
320 if ($ids) {
321 $info[0][1] = count($ids);
322 } else {
323 $info[0][1] = 0;
326 return $info;
329 //Function to check and create the needed moddata dir to
330 //save all the mod backup files. We always name it moddata
331 //to be able to restore it, but in restore we check for
332 //$CFG->moddata !!
333 function check_and_create_moddata_dir($backup_unique_code) {
335 global $CFG;
337 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/moddata",true);
339 return $status;
342 //Function to check and create the "user_files" dir to
343 //save all the user files we need from "users" dir
344 function check_and_create_user_files_dir($backup_unique_code) {
346 global $CFG;
348 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/user_files",true);
350 return $status;
353 //Function to check and create the "group_files" dir to
354 //save all the user files we need from "groups" dir
355 function check_and_create_group_files_dir($backup_unique_code) {
357 global $CFG;
359 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/group_files",true);
361 return $status;
364 //Function to check and create the "course_files" dir to
365 //save all the course files we need from "CFG->datadir/course" dir
366 function check_and_create_course_files_dir($backup_unique_code) {
368 global $CFG;
370 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/course_files",true);
372 return $status;
375 //Function to check and create the "site_files" dir to
376 //save all the course files we need from "CFG->datadir/SITEID" dir
377 function check_and_create_site_files_dir($backup_unique_code) {
379 global $CFG;
381 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/site_files",true);
383 return $status;
386 //Function to create, open and write header of the xml file
387 function backup_open_xml($backup_unique_code) {
389 global $CFG;
391 $status = true;
393 //Open for writing
395 $file = $CFG->dataroot."/temp/backup/".$backup_unique_code."/moodle.xml";
396 $backup_file = fopen($file,"w");
397 //Writes the header
398 $status = fwrite ($backup_file,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
399 if ($status) {
400 $status = fwrite ($backup_file,start_tag("MOODLE_BACKUP",0,true));
402 if ($status) {
403 return $backup_file;
404 } else {
405 return false;
409 //Close the file
410 function backup_close_xml($backup_file) {
411 $status = fwrite ($backup_file,end_tag("MOODLE_BACKUP",0,true));
412 return fclose($backup_file);
415 //Return the xml start tag
416 function start_tag($tag,$level=0,$endline=false,$attributes=null) {
417 if ($endline) {
418 $endchar = "\n";
419 } else {
420 $endchar = "";
422 $attrstring = '';
423 if (!empty($attributes) && is_array($attributes)) {
424 foreach ($attributes as $key => $value) {
425 $attrstring .= " ".xml_tag_safe_content($key)."=\"".
426 xml_tag_safe_content($value)."\"";
429 return str_repeat(" ",$level*2)."<".strtoupper($tag).$attrstring.">".$endchar;
432 //Return the xml end tag
433 function end_tag($tag,$level=0,$endline=true) {
434 if ($endline) {
435 $endchar = "\n";
436 } else {
437 $endchar = "";
439 return str_repeat(" ",$level*2)."</".strtoupper($tag).">".$endchar;
442 //Return the start tag, the contents and the end tag
443 function full_tag($tag,$level=0,$endline=true,$content,$attributes=null) {
445 global $CFG;
446 //Here we encode absolute links
447 // MDL-10770
448 if (is_null($content)) {
449 $content = '$@NULL@$';
450 } else {
451 $content = backup_encode_absolute_links($content);
453 $st = start_tag($tag,$level,$endline,$attributes);
455 $co = xml_tag_safe_content($content);
457 $et = end_tag($tag,0,true);
459 return $st.$co.$et;
463 function xml_tag_safe_content($content) {
464 global $CFG;
465 //If enabled, we strip all the control chars (\x0-\x1f) from the text but tabs (\x9),
466 //newlines (\xa) and returns (\xd). The delete control char (\x7f) is also included.
467 //because they are forbiden in XML 1.0 specs. The expression below seems to be
468 //UTF-8 safe too because it simply ignores the rest of characters.
469 $content = preg_replace("/[\x-\x8\xb-\xc\xe-\x1f\x7f]/is","",$content);
470 $content = preg_replace("/\r\n|\r/", "\n", htmlspecialchars($content));
471 return $content;
474 //Prints General info about the course
475 //name, moodle_version (internal and release), backup_version, date, info in file...
476 function backup_general_info ($bf,$preferences) {
478 global $CFG;
480 fwrite ($bf,start_tag("INFO",1,true));
482 //The name of the backup
483 fwrite ($bf,full_tag("NAME",2,false,$preferences->backup_name));
484 //The moodle_version
485 fwrite ($bf,full_tag("MOODLE_VERSION",2,false,$preferences->moodle_version));
486 fwrite ($bf,full_tag("MOODLE_RELEASE",2,false,$preferences->moodle_release));
487 //The backup_version
488 fwrite ($bf,full_tag("BACKUP_VERSION",2,false,$preferences->backup_version));
489 fwrite ($bf,full_tag("BACKUP_RELEASE",2,false,$preferences->backup_release));
490 //The date
491 fwrite ($bf,full_tag("DATE",2,false,$preferences->backup_unique_code));
492 //The original site wwwroot
493 fwrite ($bf,full_tag("ORIGINAL_WWWROOT",2,false,$CFG->wwwroot));
494 //The zip method used
495 if (!empty($CFG->zip)) {
496 $zipmethod = 'external';
497 } else {
498 $zipmethod = 'internal';
500 //Indicate if it includes external MNET users
501 $sql = "SELECT b.old_id
502 FROM {$CFG->prefix}backup_ids b
503 JOIN {$CFG->prefix}user u ON b.old_id=u.id
504 WHERE b.backup_code = '$preferences->backup_unique_code'
505 AND b.table_name = 'user' AND u.mnethostid != '{$CFG->mnet_localhost_id}'";
506 if (record_exists_sql($sql)) {
507 fwrite ($bf,full_tag("MNET_REMOTEUSERS",2,false,'true'));
509 fwrite ($bf,full_tag("ZIP_METHOD",2,false,$zipmethod));
510 //Te includes tag
511 fwrite ($bf,start_tag("DETAILS",2,true));
512 //Now, go to mod element of preferences to print its status
513 foreach ($preferences->mods as $element) {
514 //Calculate info
515 $included = "false";
516 $userinfo = "false";
517 if ($element->backup) {
518 $included = "true";
519 if ($element->userinfo) {
520 $userinfo = "true";
523 //Prints the mod start
524 fwrite ($bf,start_tag("MOD",3,true));
525 fwrite ($bf,full_tag("NAME",4,false,$element->name));
526 fwrite ($bf,full_tag("INCLUDED",4,false,$included));
527 fwrite ($bf,full_tag("USERINFO",4,false,$userinfo));
529 if (isset($preferences->mods[$element->name]->instances)
530 && is_array($preferences->mods[$element->name]->instances)
531 && count($preferences->mods[$element->name]->instances)) {
532 fwrite ($bf, start_tag("INSTANCES",4,true));
533 foreach ($preferences->mods[$element->name]->instances as $id => $object) {
534 if (!empty($object->backup)) {
535 //Calculate info
536 $included = "false";
537 $userinfo = "false";
538 if ($object->backup) {
539 $included = "true";
540 if ($object->userinfo) {
541 $userinfo = "true";
544 fwrite ($bf, start_tag("INSTANCE",5,true));
545 fwrite ($bf, full_tag("ID",5,false,$id));
546 fwrite ($bf, full_tag("NAME",5,false,$object->name));
547 fwrite ($bf, full_tag("INCLUDED",5,false,$included)) ;
548 fwrite ($bf, full_tag("USERINFO",5,false,$userinfo));
549 fwrite ($bf, end_tag("INSTANCE",5,true));
552 fwrite ($bf, end_tag("INSTANCES",4,true));
556 //Print the end
557 fwrite ($bf,end_tag("MOD",3,true));
559 //The metacourse in backup
560 if ($preferences->backup_metacourse == 1) {
561 fwrite ($bf,full_tag("METACOURSE",3,false,"true"));
562 } else {
563 fwrite ($bf,full_tag("METACOURSE",3,false,"false"));
565 //The user in backup
566 if ($preferences->backup_users == 1) {
567 fwrite ($bf,full_tag("USERS",3,false,"course"));
568 } else if ($preferences->backup_users == 0) {
569 fwrite ($bf,full_tag("USERS",3,false,"all"));
570 } else {
571 fwrite ($bf,full_tag("USERS",3,false,"none"));
573 //The logs in backup
574 if ($preferences->backup_logs == 1) {
575 fwrite ($bf,full_tag("LOGS",3,false,"true"));
576 } else {
577 fwrite ($bf,full_tag("LOGS",3,false,"false"));
579 //The user files
580 if ($preferences->backup_user_files == 1) {
581 fwrite ($bf,full_tag("USERFILES",3,false,"true"));
582 } else {
583 fwrite ($bf,full_tag("USERFILES",3,false,"false"));
585 //The course files
586 if ($preferences->backup_course_files == 1) {
587 fwrite ($bf,full_tag("COURSEFILES",3,false,"true"));
588 } else {
589 fwrite ($bf,full_tag("COURSEFILES",3,false,"false"));
591 //The course files
592 if ($preferences->backup_site_files == 1) {
593 fwrite ($bf,full_tag("SITEFILES",3,false,"true"));
594 } else {
595 fwrite ($bf,full_tag("SITEFILES",3,false,"false"));
597 //The messages in backup
598 if ($preferences->backup_messages == 1 && $preferences->backup_course == SITEID) {
599 fwrite ($bf,full_tag("MESSAGES",3,false,"true"));
600 } else {
601 fwrite ($bf,full_tag("MESSAGES",3,false,"false"));
603 //The mode of writing the block data
604 fwrite ($bf,full_tag('BLOCKFORMAT',3,false,'instances'));
605 fwrite ($bf,end_tag("DETAILS",2,true));
607 $status = fwrite ($bf,end_tag("INFO",1,true));
609 ///Roles stuff goes in here
611 fwrite ($bf, start_tag('ROLES', 1, true));
612 $roles = backup_fetch_roles($preferences);
614 $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
616 foreach ($roles as $role) {
617 fwrite ($bf,start_tag('ROLE',2,true));
618 fwrite ($bf,full_tag('ID', 3, false, $role->id));
619 fwrite ($bf,full_tag('NAME',3,false,$role->name));
620 fwrite ($bf,full_tag('SHORTNAME',3,false,$role->shortname));
621 // find and write all default capabilities
622 fwrite ($bf,start_tag('CAPABILITIES',3,true));
623 // pull out all default (site context) capabilities
624 if ($capabilities = role_context_capabilities($role->id, $sitecontext)) {
625 foreach ($capabilities as $capability=>$value) {
626 fwrite ($bf,start_tag('CAPABILITY',4,true));
627 fwrite ($bf,full_tag('NAME', 5, false, $capability));
628 fwrite ($bf,full_tag('PERMISSION', 5, false, $value));
629 // use this to pull out the other info (timemodified and modifierid)
630 $cap = get_record_sql("SELECT *
631 FROM {$CFG->prefix}role_capabilities
632 WHERE capability = '$capability'
633 AND contextid = $sitecontext->id
634 AND roleid = $role->id");
635 fwrite ($bf, full_tag("TIMEMODIFIED", 5, false, $cap->timemodified));
636 fwrite ($bf, full_tag("MODIFIERID", 5, false, $cap->modifierid));
637 fwrite ($bf,end_tag('CAPABILITY',4,true));
640 fwrite ($bf,end_tag('CAPABILITIES',3,true));
641 fwrite ($bf,end_tag('ROLE',2,true));
643 fwrite ($bf,end_tag('ROLES', 1, true));
644 return $status;
647 //Prints course's general info (table course)
648 function backup_course_start ($bf,$preferences) {
650 global $CFG;
652 $status = true;
654 //Course open tag
655 fwrite ($bf,start_tag("COURSE",1,true));
656 //Header open tag
657 fwrite ($bf,start_tag("HEADER",2,true));
659 //Get info from course
660 $course = get_record("course","id",$preferences->backup_course);
661 $context = get_context_instance(CONTEXT_COURSE, $course->id);
662 if ($course) {
663 //Prints course info
664 fwrite ($bf,full_tag("ID",3,false,$course->id));
665 //Obtain the category
666 $category = get_record("course_categories","id","$course->category");
667 if ($category) {
668 //Prints category info
669 fwrite ($bf,start_tag("CATEGORY",3,true));
670 fwrite ($bf,full_tag("ID",4,false,$course->category));
671 fwrite ($bf,full_tag("NAME",4,false,$category->name));
672 fwrite ($bf,end_tag("CATEGORY",3,true));
674 //Continues with the course
675 fwrite ($bf,full_tag("PASSWORD",3,false,$course->password));
676 fwrite ($bf,full_tag("FULLNAME",3,false,$course->fullname));
677 fwrite ($bf,full_tag("SHORTNAME",3,false,$course->shortname));
678 fwrite ($bf,full_tag("IDNUMBER",3,false,$course->idnumber));
679 fwrite ($bf,full_tag("SUMMARY",3,false,$course->summary));
680 fwrite ($bf,full_tag("FORMAT",3,false,$course->format));
681 fwrite ($bf,full_tag("SHOWGRADES",3,false,$course->showgrades));
682 fwrite ($bf,full_tag("NEWSITEMS",3,false,$course->newsitems));
683 fwrite ($bf,full_tag("TEACHER",3,false,$course->teacher));
684 fwrite ($bf,full_tag("TEACHERS",3,false,$course->teachers));
685 fwrite ($bf,full_tag("STUDENT",3,false,$course->student));
686 fwrite ($bf,full_tag("STUDENTS",3,false,$course->students));
687 fwrite ($bf,full_tag("GUEST",3,false,$course->guest));
688 fwrite ($bf,full_tag("STARTDATE",3,false,$course->startdate));
689 fwrite ($bf,full_tag("NUMSECTIONS",3,false,$course->numsections));
690 //fwrite ($bf,full_tag("SHOWRECENT",3,false,$course->showrecent)); INFO: This is out in 1.3
691 fwrite ($bf,full_tag("MAXBYTES",3,false,$course->maxbytes));
692 fwrite ($bf,full_tag("SHOWREPORTS",3,false,$course->showreports));
693 fwrite ($bf,full_tag("GROUPMODE",3,false,$course->groupmode));
694 fwrite ($bf,full_tag("GROUPMODEFORCE",3,false,$course->groupmodeforce));
695 fwrite ($bf,full_tag("LANG",3,false,$course->lang));
696 fwrite ($bf,full_tag("THEME",3,false,$course->theme));
697 fwrite ($bf,full_tag("COST",3,false,$course->cost));
698 fwrite ($bf,full_tag("CURRENCY",3,false,$course->currency));
699 fwrite ($bf,full_tag("MARKER",3,false,$course->marker));
700 fwrite ($bf,full_tag("VISIBLE",3,false,$course->visible));
701 fwrite ($bf,full_tag("HIDDENSECTIONS",3,false,$course->hiddensections));
702 fwrite ($bf,full_tag("TIMECREATED",3,false,$course->timecreated));
703 fwrite ($bf,full_tag("TIMEMODIFIED",3,false,$course->timemodified));
704 //If not selected, force metacourse to 0
705 if (!$preferences->backup_metacourse) {
706 $status = fwrite ($bf,full_tag("METACOURSE",3,false,'0'));
707 //else, export the field as is in DB
708 } else {
709 $status = fwrite ($bf,full_tag("METACOURSE",3,false,$course->metacourse));
711 fwrite ($bf,full_tag("EXPIRENOTIFY",3,false,$course->expirynotify));
712 fwrite ($bf,full_tag("NOTIFYSTUDENTS",3,false,$course->notifystudents));
713 fwrite ($bf,full_tag("EXPIRYTHRESHOLD",3,false,$course->expirythreshold));
714 fwrite ($bf,full_tag("ENROLLABLE",3,false,$course->enrollable));
715 fwrite ($bf,full_tag("ENROLSTARTDATE",3,false,$course->enrolstartdate));
716 fwrite ($bf,full_tag("ENROLENDDATE",3,false,$course->enrolenddate));
717 fwrite ($bf,full_tag("ENROLPERIOD",3,false,$course->enrolperiod));
719 /// write local course overrides here?
720 write_role_overrides_xml($bf, $context, 3);
721 /// write role_assign code here
722 write_role_assignments_xml($bf, $context, 3);
723 //Print header end
724 fwrite ($bf,end_tag("HEADER",2,true));
725 } else {
726 $status = false;
729 return $status;
732 //Prints course's end tag
733 function backup_course_end ($bf,$preferences) {
735 //Course end tag
736 $status = fwrite ($bf,end_tag("COURSE",1,true));
738 return $status;
742 //Prints course's metacourse info (table course_meta)
743 function backup_course_metacourse ($bf,$preferences) {
745 global $CFG;
747 $status = true;
749 //Get info from meta
750 $parents = get_records_sql ("SELECT m.*, c.idnumber, c.shortname
751 FROM {$CFG->prefix}course_meta m,
752 {$CFG->prefix}course c
753 WHERE m.child_course = '$preferences->backup_course' AND
754 m.parent_course = c.id");
755 $childs = get_records_sql ("SELECT m.*, c.idnumber, c.shortname
756 FROM {$CFG->prefix}course_meta m,
757 {$CFG->prefix}course c
758 WHERE m.parent_course = '$preferences->backup_course' AND
759 m.child_course = c.id");
761 if ($parents || $childs) {
762 //metacourse open tag
763 fwrite ($bf,start_tag("METACOURSE",2,true));
764 if ($parents) {
765 fwrite($bf, start_tag("PARENTS",3,true));
766 //Iterate over every parent
767 foreach ($parents as $parent) {
768 //Begin parent
769 fwrite ($bf,start_tag("PARENT",4,true));
770 fwrite ($bf,full_tag("ID",5,false,$parent->parent_course));
771 fwrite ($bf,full_tag("IDNUMBER",5,false,$parent->idnumber));
772 fwrite ($bf,full_tag("SHORTNAME",5,false,$parent->shortname));
773 //End parent
774 fwrite ($bf,end_tag("PARENT",4,true));
776 fwrite ($bf,end_tag("PARENTS",3,true));
778 if ($childs) {
779 fwrite($bf, start_tag("CHILDS",3,true));
780 //Iterate over every child
781 foreach ($childs as $child) {
782 //Begin parent
783 fwrite ($bf,start_tag("CHILD",4,true));
784 fwrite ($bf,full_tag("ID",5,false,$child->child_course));
785 fwrite ($bf,full_tag("IDNUMBER",5,false,$child->idnumber));
786 fwrite ($bf,full_tag("SHORTNAME",5,false,$child->shortname));
787 //End parent
788 fwrite ($bf,end_tag("CHILD",4,true));
790 fwrite ($bf,end_tag("CHILDS",3,true));
792 //metacourse close tag
793 $status = fwrite ($bf,end_tag("METACOURSE",3,true));
796 return $status;
800 //Prints course's messages info (tables message, message_read and message_contacts)
801 function backup_messages ($bf,$preferences) {
803 global $CFG;
805 $status = true;
807 //Get info from messages
808 $unreads = get_records ('message');
809 $reads = get_records ('message_read');
810 $contacts= get_records ('message_contacts');
812 if ($unreads || $reads || $contacts) {
813 $counter = 0;
814 //message open tag
815 fwrite ($bf,start_tag("MESSAGES",2,true));
816 if ($unreads) {
817 //Iterate over every unread
818 foreach ($unreads as $unread) {
819 //start message
820 fwrite($bf, start_tag("MESSAGE",3,true));
821 fwrite ($bf,full_tag("ID",4,false,$unread->id));
822 fwrite ($bf,full_tag("STATUS",4,false,"UNREAD"));
823 fwrite ($bf,full_tag("USERIDFROM",4,false,$unread->useridfrom));
824 fwrite ($bf,full_tag("USERIDTO",4,false,$unread->useridto));
825 fwrite ($bf,full_tag("MESSAGE",4,false,$unread->message));
826 fwrite ($bf,full_tag("FORMAT",4,false,$unread->format));
827 fwrite ($bf,full_tag("TIMECREATED",4,false,$unread->timecreated));
828 fwrite ($bf,full_tag("MESSAGETYPE",4,false,$unread->messagetype));
829 //end message
830 fwrite ($bf,end_tag("MESSAGE",3,true));
832 //Do some output
833 $counter++;
834 if ($counter % 20 == 0) {
835 echo ".";
836 if ($counter % 400 == 0) {
837 echo "<br />";
839 backup_flush(300);
844 if ($reads) {
845 //Iterate over every read
846 foreach ($reads as $read) {
847 //start message
848 fwrite($bf, start_tag("MESSAGE",3,true));
849 fwrite ($bf,full_tag("ID",4,false,$read->id));
850 fwrite ($bf,full_tag("STATUS",4,false,"READ"));
851 fwrite ($bf,full_tag("USERIDFROM",4,false,$read->useridfrom));
852 fwrite ($bf,full_tag("USERIDTO",4,false,$read->useridto));
853 fwrite ($bf,full_tag("MESSAGE",4,false,$read->message));
854 fwrite ($bf,full_tag("FORMAT",4,false,$read->format));
855 fwrite ($bf,full_tag("TIMECREATED",4,false,$read->timecreated));
856 fwrite ($bf,full_tag("MESSAGETYPE",4,false,$read->messagetype));
857 fwrite ($bf,full_tag("TIMEREAD",4,false,$read->timeread));
858 fwrite ($bf,full_tag("MAILED",4,false,$read->mailed));
859 //end message
860 fwrite ($bf,end_tag("MESSAGE",3,true));
862 //Do some output
863 $counter++;
864 if ($counter % 20 == 0) {
865 echo ".";
866 if ($counter % 400 == 0) {
867 echo "<br />";
869 backup_flush(300);
874 if ($contacts) {
875 fwrite($bf, start_tag("CONTACTS",3,true));
876 //Iterate over every contact
877 foreach ($contacts as $contact) {
878 //start contact
879 fwrite($bf, start_tag("CONTACT",4,true));
880 fwrite ($bf,full_tag("ID",5,false,$contact->id));
881 fwrite ($bf,full_tag("USERID",5,false,$contact->userid));
882 fwrite ($bf,full_tag("CONTACTID",5,false,$contact->contactid));
883 fwrite ($bf,full_tag("BLOCKED",5,false,$contact->blocked));
884 //end contact
885 fwrite ($bf,end_tag("CONTACT",4,true));
887 //Do some output
888 $counter++;
889 if ($counter % 20 == 0) {
890 echo ".";
891 if ($counter % 400 == 0) {
892 echo "<br />";
894 backup_flush(300);
897 fwrite($bf, end_tag("CONTACTS",3,true));
899 //messages close tag
900 $status = fwrite ($bf,end_tag("MESSAGES",2,true));
903 return $status;
907 //Prints course's blocks info (table block_instance)
908 function backup_course_blocks ($bf,$preferences) {
910 global $CFG;
912 $status = true;
914 // Read all of the block table
915 $blocks = blocks_get_record();
917 $pages = array();
918 $pages[] = page_create_object(PAGE_COURSE_VIEW, $preferences->backup_course);
920 // Let's see if we have to backup blocks from modules
921 $modulerecords = get_records_sql('SELECT name, id FROM '.$CFG->prefix.'modules');
923 foreach($preferences->mods as $module) {
924 if(!$module->backup) {
925 continue;
928 $cmods = get_records_select('course_modules', 'course = '.$preferences->backup_course.' AND module = '.$modulerecords[$module->name]->id);
929 if(empty($cmods)) {
930 continue;
933 $pagetypes = page_import_types('mod/'.$module->name.'/');
934 if(empty($pagetypes)) {
935 continue;
938 foreach($pagetypes as $pagetype) {
939 foreach($cmods as $cmod) {
940 $pages[] = page_create_object($pagetype, $cmod->instance);
945 //Blocks open tag
946 fwrite ($bf,start_tag('BLOCKS',2,true));
948 while($page = array_pop($pages)) {
949 if ($instances = blocks_get_by_page($page)) {
950 //Iterate over every block
951 foreach ($instances as $position) {
952 foreach ($position as $instance) {
954 //If we somehow have a block with an invalid id, skip it
955 if(empty($blocks[$instance->blockid]->name)) {
956 continue;
958 //Begin Block
960 fwrite ($bf,start_tag('BLOCK',3,true));
961 fwrite ($bf,full_tag('ID', 4, false,$instance->id));
962 fwrite ($bf,full_tag('NAME',4,false,$blocks[$instance->blockid]->name));
963 fwrite ($bf,full_tag('PAGEID',4,false,$instance->pageid));
964 fwrite ($bf,full_tag('PAGETYPE',4,false,$instance->pagetype));
965 fwrite ($bf,full_tag('POSITION',4,false,$instance->position));
966 fwrite ($bf,full_tag('WEIGHT',4,false,$instance->weight));
967 fwrite ($bf,full_tag('VISIBLE',4,false,$instance->visible));
968 fwrite ($bf,full_tag('CONFIGDATA',4,false,$instance->configdata));
970 $context = get_context_instance(CONTEXT_BLOCK, $instance->id);
971 write_role_overrides_xml($bf, $context, 4);
972 /// write role_assign code here
973 write_role_assignments_xml($bf, $context, 4);
974 //End Block
975 fwrite ($bf,end_tag('BLOCK',3,true));
981 //Blocks close tag
982 $status = fwrite ($bf,end_tag('BLOCKS',2,true));
984 return $status;
988 //Prints course's sections info (table course_sections)
989 function backup_course_sections ($bf,$preferences) {
991 global $CFG;
993 $status = true;
996 //Get info from sections
997 $section=false;
998 if ($sections = get_records("course_sections","course",$preferences->backup_course,"section")) {
999 //Section open tag
1000 fwrite ($bf,start_tag("SECTIONS",2,true));
1001 //Iterate over every section (ordered by section)
1002 foreach ($sections as $section) {
1003 //Begin Section
1004 fwrite ($bf,start_tag("SECTION",3,true));
1005 fwrite ($bf,full_tag("ID",4,false,$section->id));
1006 fwrite ($bf,full_tag("NUMBER",4,false,$section->section));
1007 fwrite ($bf,full_tag("SUMMARY",4,false,$section->summary));
1008 fwrite ($bf,full_tag("VISIBLE",4,false,$section->visible));
1009 //Now print the mods in section
1010 backup_course_modules ($bf,$preferences,$section);
1011 //End section
1012 fwrite ($bf,end_tag("SECTION",3,true));
1014 //Section close tag
1015 $status = fwrite ($bf,end_tag("SECTIONS",2,true));
1018 return $status;
1022 //Prints course's format data (any data the format might want to save).
1023 function backup_format_data ($bf,$preferences) {
1024 global $CFG;
1026 // Check course format
1027 if(!($format=get_field('course','format','id',$preferences->backup_course))) {
1028 return false;
1030 // Write appropriate tag. Note that we always put this tag there even if
1031 // blank, it makes parsing easier
1032 fwrite ($bf,start_tag("FORMATDATA",2,true));
1034 $file=$CFG->dirroot."/course/format/$format/backuplib.php";
1035 if(file_exists($file)) {
1036 // If the file is there, the function must be or it's an error.
1037 require_once($file);
1038 $function=$format.'_backup_format_data';
1039 if(!function_exists($function)) {
1040 return false;
1042 if(!$function($bf,$preferences)) {
1043 return false;
1047 // This last return just checks the file writing has been ok (ish)
1048 return fwrite ($bf,end_tag("FORMATDATA",2,true));
1051 //Prints course's modules info (table course_modules)
1052 //Only for selected mods in preferences
1053 function backup_course_modules ($bf,$preferences,$section) {
1055 global $CFG;
1057 $status = true;
1059 $first_record = true;
1061 //Now print the mods in section
1062 //Extracts mod id from sequence
1063 $tok = strtok($section->sequence,",");
1064 while ($tok) {
1065 //Get module's type
1066 $moduletype = get_module_type ($preferences->backup_course,$tok);
1067 //Check if we've selected to backup that type
1068 if ($moduletype and $preferences->mods[$moduletype]->backup) {
1069 $selected = true;
1070 } else {
1071 $selected = false;
1074 if ($selected) {
1075 $context = get_context_instance(CONTEXT_MODULE, $tok);
1076 //Gets course_module data from db
1077 $course_module = get_records ("course_modules","id",$tok);
1078 //If it's the first, pring MODS tag
1079 if ($first_record) {
1080 fwrite ($bf,start_tag("MODS",4,true));
1081 $first_record = false;
1083 // if we're doing selected instances, check that too.
1084 if (is_array($preferences->mods[$moduletype]->instances)
1085 && count($preferences->mods[$moduletype]->instances)
1086 && (!array_key_exists($course_module[$tok]->instance,$preferences->mods[$moduletype]->instances)
1087 || empty($preferences->mods[$moduletype]->instances[$course_module[$tok]->instance]->backup))) {
1088 $tok = strtok(",");
1089 continue;
1092 // find all role values that has an override in this context
1093 $roles = get_records('role_capabilities', 'contextid', $context->id);
1095 //Print mod info from course_modules
1096 fwrite ($bf,start_tag("MOD",5,true));
1097 //Save neccesary info to backup_ids
1098 fwrite ($bf,full_tag("ID",6,false,$tok));
1099 fwrite ($bf,full_tag("TYPE",6,false,$moduletype));
1100 fwrite ($bf,full_tag("INSTANCE",6,false,$course_module[$tok]->instance));
1101 fwrite ($bf,full_tag("ADDED",6,false,$course_module[$tok]->added));
1102 fwrite ($bf,full_tag("SCORE",6,false,$course_module[$tok]->score));
1103 fwrite ($bf,full_tag("INDENT",6,false,$course_module[$tok]->indent));
1104 fwrite ($bf,full_tag("VISIBLE",6,false,$course_module[$tok]->visible));
1105 fwrite ($bf,full_tag("GROUPMODE",6,false,$course_module[$tok]->groupmode));
1106 // get all the role_capabilities overrides in this mod
1107 write_role_overrides_xml($bf, $context, 6);
1108 /// write role_assign code here
1109 write_role_assignments_xml($bf, $context, 6);
1110 /// write role_assign code here
1112 fwrite ($bf,end_tag("MOD",5,true));
1114 //check for next
1115 $tok = strtok(",");
1118 //Si ha habido modulos, final de MODS
1119 if (!$first_record) {
1120 $status =fwrite ($bf,end_tag("MODS",4,true));
1123 return $status;
1126 //Print users to xml
1127 //Only users previously calculated in backup_ids will output
1129 function backup_user_info ($bf,$preferences) {
1131 global $CFG;
1133 $status = true;
1135 // Use a recordset to for the memory handling on to
1136 // the DB and run faster
1137 $users = get_recordset_sql("SELECT b.old_id, b.table_name, b.info,
1138 u.*, m.wwwroot
1139 FROM {$CFG->prefix}backup_ids b
1140 JOIN {$CFG->prefix}user u ON b.old_id=u.id
1141 JOIN {$CFG->prefix}mnet_host m ON u.mnethostid=m.id
1142 WHERE b.backup_code = '$preferences->backup_unique_code' AND
1143 b.table_name = 'user'");
1145 //If we have users to backup
1146 if ($users && $users->RecordCount()) {
1147 //Begin Users tag
1148 fwrite ($bf,start_tag("USERS",2,true));
1149 $counter = 0;
1150 //With every user
1151 while ($user = $users->FetchNextObj()) {
1152 //Begin User tag
1153 fwrite ($bf,start_tag("USER",3,true));
1154 //Output all user data
1155 fwrite ($bf,full_tag("ID",4,false,$user->id));
1156 fwrite ($bf,full_tag("AUTH",4,false,$user->auth));
1157 fwrite ($bf,full_tag("CONFIRMED",4,false,$user->confirmed));
1158 fwrite ($bf,full_tag("POLICYAGREED",4,false,$user->policyagreed));
1159 fwrite ($bf,full_tag("DELETED",4,false,$user->deleted));
1160 fwrite ($bf,full_tag("USERNAME",4,false,$user->username));
1161 fwrite ($bf,full_tag("PASSWORD",4,false,$user->password));
1162 fwrite ($bf,full_tag("IDNUMBER",4,false,$user->idnumber));
1163 fwrite ($bf,full_tag("FIRSTNAME",4,false,$user->firstname));
1164 fwrite ($bf,full_tag("LASTNAME",4,false,$user->lastname));
1165 fwrite ($bf,full_tag("EMAIL",4,false,$user->email));
1166 fwrite ($bf,full_tag("EMAILSTOP",4,false,$user->emailstop));
1167 fwrite ($bf,full_tag("ICQ",4,false,$user->icq));
1168 fwrite ($bf,full_tag("SKYPE",4,false,$user->skype));
1169 fwrite ($bf,full_tag("YAHOO",4,false,$user->yahoo));
1170 fwrite ($bf,full_tag("AIM",4,false,$user->aim));
1171 fwrite ($bf,full_tag("MSN",4,false,$user->msn));
1172 fwrite ($bf,full_tag("PHONE1",4,false,$user->phone1));
1173 fwrite ($bf,full_tag("PHONE2",4,false,$user->phone2));
1174 fwrite ($bf,full_tag("INSTITUTION",4,false,$user->institution));
1175 fwrite ($bf,full_tag("DEPARTMENT",4,false,$user->department));
1176 fwrite ($bf,full_tag("ADDRESS",4,false,$user->address));
1177 fwrite ($bf,full_tag("CITY",4,false,$user->city));
1178 fwrite ($bf,full_tag("COUNTRY",4,false,$user->country));
1179 fwrite ($bf,full_tag("LANG",4,false,$user->lang));
1180 fwrite ($bf,full_tag("THEME",4,false,$user->theme));
1181 fwrite ($bf,full_tag("TIMEZONE",4,false,$user->timezone));
1182 fwrite ($bf,full_tag("FIRSTACCESS",4,false,$user->firstaccess));
1183 fwrite ($bf,full_tag("LASTACCESS",4,false,$user->lastaccess));
1184 fwrite ($bf,full_tag("LASTLOGIN",4,false,$user->lastlogin));
1185 fwrite ($bf,full_tag("CURRENTLOGIN",4,false,$user->currentlogin));
1186 fwrite ($bf,full_tag("LASTIP",4,false,$user->lastip));
1187 fwrite ($bf,full_tag("SECRET",4,false,$user->secret));
1188 fwrite ($bf,full_tag("PICTURE",4,false,$user->picture));
1189 fwrite ($bf,full_tag("URL",4,false,$user->url));
1190 fwrite ($bf,full_tag("DESCRIPTION",4,false,$user->description));
1191 fwrite ($bf,full_tag("MAILFORMAT",4,false,$user->mailformat));
1192 fwrite ($bf,full_tag("MAILDIGEST",4,false,$user->maildigest));
1193 fwrite ($bf,full_tag("MAILDISPLAY",4,false,$user->maildisplay));
1194 fwrite ($bf,full_tag("HTMLEDITOR",4,false,$user->htmleditor));
1195 fwrite ($bf,full_tag("AJAX",4,false,$user->ajax));
1196 fwrite ($bf,full_tag("AUTOSUBSCRIBE",4,false,$user->autosubscribe));
1197 fwrite ($bf,full_tag("TRACKFORUMS",4,false,$user->trackforums));
1198 if ($user->mnethostid != $CFG->mnet_localhost_id) {
1199 fwrite ($bf,full_tag("MNETHOSTURL",4,false,$user->wwwroot));
1201 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$user->timemodified));
1203 /// write assign/override code for context_userid
1205 $user->isneeded = strpos($user->info,"needed");
1206 //Output every user role (with its associated info)
1208 $user->isadmin = strpos($user->info,"admin");
1209 $user->iscoursecreator = strpos($user->info,"coursecreator");
1210 $user->isteacher = strpos($user->info,"teacher");
1211 $user->isstudent = strpos($user->info,"student");
1214 if ($user->isadmin!==false or
1215 $user->iscoursecreator!==false or
1216 $user->isteacher!==false or
1217 $user->isstudent!==false or
1218 $user->isneeded!==false) {
1220 fwrite ($bf,start_tag("ROLES",4,true));
1221 if ($user->info != "needed" && $user->info!="") {
1222 //Begin ROLES tag
1224 //PRINT ROLE INFO
1225 //Admins
1226 $roles = explode(",", $user->info);
1227 foreach ($roles as $role) {
1228 if ($role!="" && $role!="needed") {
1229 fwrite ($bf,start_tag("ROLE",5,true));
1230 //Print Role info
1231 fwrite ($bf,full_tag("TYPE",6,false,$role));
1232 //Print ROLE end
1233 fwrite ($bf,end_tag("ROLE",5,true));
1237 //Needed
1238 if ($user->isneeded!==false) {
1239 //Print ROLE start
1240 fwrite ($bf,start_tag("ROLE",5,true));
1241 //Print Role info
1242 fwrite ($bf,full_tag("TYPE",6,false,"needed"));
1243 //Print ROLE end
1244 fwrite ($bf,end_tag("ROLE",5,true));
1247 //End ROLES tag
1248 fwrite ($bf,end_tag("ROLES",4,true));
1250 //Check if we have user_preferences to backup
1251 if ($preferences_data = get_records("user_preferences","userid",$user->old_id)) {
1252 //Start USER_PREFERENCES tag
1253 fwrite ($bf,start_tag("USER_PREFERENCES",4,true));
1254 //Write each user_preference
1255 foreach ($preferences_data as $user_preference) {
1256 fwrite ($bf,start_tag("USER_PREFERENCE",5,true));
1257 fwrite ($bf,full_tag("NAME",6,false,$user_preference->name));
1258 fwrite ($bf,full_tag("VALUE",6,false,$user_preference->value));
1259 fwrite ($bf,end_tag("USER_PREFERENCE",5,true));
1261 //End USER_PREFERENCES tag
1262 fwrite ($bf,end_tag("USER_PREFERENCES",4,true));
1265 $context = get_context_instance(CONTEXT_USER, $user->old_id);
1267 write_role_overrides_xml($bf, $context, 4);
1268 /// write role_assign code here
1269 write_role_assignments_xml($bf, $context, 4);
1270 //End User tag
1271 fwrite ($bf,end_tag("USER",3,true));
1272 //Do some output
1273 $counter++;
1274 if ($counter % 10 == 0) {
1275 echo ".";
1276 if ($counter % 200 == 0) {
1277 echo "<br />";
1279 backup_flush(300);
1282 //End Users tag
1283 fwrite ($bf,end_tag("USERS",2,true));
1284 } else {
1285 // There aren't any users.
1286 $status = true;
1289 return $status;
1292 //Backup log info (time ordered)
1293 function backup_log_info($bf,$preferences) {
1295 global $CFG;
1297 //Number of records to get in every chunk
1298 $recordset_size = 1000;
1300 $status = true;
1302 //Counter, points to current record
1303 $counter = 0;
1305 //Count records
1306 $count_logs = count_records("log","course",$preferences->backup_course);
1308 //Pring logs header
1309 if ($count_logs > 0 ) {
1310 fwrite ($bf,start_tag("LOGS",2,true));
1312 while ($counter < $count_logs) {
1313 //Get a chunk of records
1314 $logs = get_records ("log","course",$preferences->backup_course,"time","*",$counter,$recordset_size);
1316 //We have logs
1317 if ($logs) {
1318 //Iterate
1319 foreach ($logs as $log) {
1320 //See if it is a valid module to backup
1321 if ($log->module == "course" or
1322 $log->module == "user" or
1323 (array_key_exists($log->module, $preferences->mods) and $preferences->mods[$log->module]->backup == 1)) {
1324 // logs with 'upload' in module field are ignored, there is no restore code anyway
1325 //Begin log tag
1326 fwrite ($bf,start_tag("LOG",3,true));
1328 //Output log tag
1329 fwrite ($bf,full_tag("ID",4,false,$log->id));
1330 fwrite ($bf,full_tag("TIME",4,false,$log->time));
1331 fwrite ($bf,full_tag("USERID",4,false,$log->userid));
1332 fwrite ($bf,full_tag("IP",4,false,$log->ip));
1333 fwrite ($bf,full_tag("MODULE",4,false,$log->module));
1334 fwrite ($bf,full_tag("CMID",4,false,$log->cmid));
1335 fwrite ($bf,full_tag("ACTION",4,false,$log->action));
1336 fwrite ($bf,full_tag("URL",4,false,$log->url));
1337 fwrite ($bf,full_tag("INFO",4,false,$log->info));
1339 //End log tag
1340 fwrite ($bf,end_tag("LOG",3,true));
1342 //Do some output
1343 $counter++;
1344 if ($counter % 20 == 0) {
1345 echo ".";
1346 if ($counter % 400 == 0) {
1347 echo "<br />";
1349 backup_flush(300);
1354 //End logs tag
1355 if ($count_logs > 0 ) {
1356 $status = fwrite ($bf,end_tag("LOGS",2,true));
1358 return $status;
1361 //Backup gradebook info
1362 function backup_gradebook_info($bf,$preferences) {
1364 global $CFG;
1365 $status = true;
1367 // see if ALL grade items of type mod of this course are being backed up
1368 // if not, we do not need to backup grade category and associated grade items/grades
1369 $backupall = true;
1371 if ($grade_items = get_records_sql("SELECT * FROM {$CFG->prefix}grade_items
1372 WHERE courseid = $preferences->backup_course
1373 ORDER BY sortorder ASC")) {
1374 foreach ($grade_items as $grade_item) {
1376 // do not restore if this grade_item is a mod, and
1377 if ($grade_item->itemtype == 'mod') {
1379 // get module information
1380 // if no user data selected, we skip this grade_item
1381 if (!backup_userdata_selected($preferences,$grade_item->itemmodule,$grade_item->iteminstance)) {
1382 //print_object($grade_item);
1383 $backupall = false;
1384 break;
1390 //Gradebook header
1391 fwrite ($bf,start_tag("GRADEBOOK",2,true));
1393 // Now backup grade_item (inside grade_category)
1394 if ($backupall) {
1395 $status = backup_gradebook_category_info($bf,$preferences);
1398 $status = backup_gradebook_item_info($bf,$preferences, $backupall);
1399 $status = backup_gradebook_outcomes_info($bf, $preferences);
1400 $status = backup_gradebook_outcomes_courses_info($bf, $preferences);
1402 // backup gradebook histories
1403 if ($preferences->backup_gradebook_history) {
1404 $status = backup_gradebook_categories_history_info($bf, $preferences);
1405 $status = backup_gradebook_grades_history_info($bf, $preferences);
1406 $status = backup_gradebook_grades_text_history_info($bf, $preferences);
1407 $status = backup_gradebook_items_history_info($bf, $preferences);
1408 $status = backup_gradebook_outcomes_history($bf, $preferences);
1411 //Gradebook footer
1412 $status = fwrite ($bf,end_tag("GRADEBOOK",2,true));
1413 return $status;
1416 function backup_gradebook_category_info($bf,$preferences) {
1417 global $CFG;
1418 $status = true;
1420 // getting grade categories, but make sure parents come before children
1421 // because when we do restore, we need to recover the parents first
1422 // we do this by getting the lowest depth first
1423 $grade_categories = get_records_sql("SELECT * FROM {$CFG->prefix}grade_categories
1424 WHERE courseid = $preferences->backup_course
1425 ORDER BY depth ASC");
1426 if ($grade_categories) {
1427 //Begin grade_categories tag
1428 fwrite ($bf,start_tag("GRADE_CATEGORIES",3,true));
1429 //Iterate for each category
1430 foreach ($grade_categories as $grade_category) {
1431 //Begin grade_category
1432 fwrite ($bf,start_tag("GRADE_CATEGORY",4,true));
1433 //Output individual fields
1434 fwrite ($bf,full_tag("ID",5,false,$grade_category->id));
1436 // not keeping path and depth because they can be derived
1437 fwrite ($bf,full_tag("PARENT",5,false,$grade_category->parent));
1438 fwrite ($bf,full_tag("FULLNAME",5,false,$grade_category->fullname));
1439 fwrite ($bf,full_tag("AGGREGATION",5,false,$grade_category->aggregation));
1440 fwrite ($bf,full_tag("KEEPHIGH",5,false,$grade_category->keephigh));
1441 fwrite ($bf,full_tag("DROPLOW",5,false,$grade_category->droplow));
1442 fwrite ($bf,full_tag("AGGREGATEOUTCOMES",5,false,$grade_category->aggregateoutcomes));
1444 //End grade_category
1445 fwrite ($bf,end_tag("GRADE_CATEGORY",4,true));
1447 //End grade_categories tag
1448 $status = fwrite ($bf,end_tag("GRADE_CATEGORIES",3,true));
1451 return $status;
1454 //Backup gradebook_item (called from backup_gradebook_info
1455 function backup_gradebook_item_info($bf,$preferences, $backupall) {
1457 global $CFG;
1458 require_once($CFG->libdir . '/gradelib.php');
1459 $status = true;
1460 // get all the grade_items, ordered by sort order since upon restoring, it is not always
1461 // possible to use the same sort order. We could at least preserve the sortorder by restoring
1462 // grade_items in the original sortorder
1463 if ($grade_items = get_records_sql("SELECT * FROM {$CFG->prefix}grade_items
1464 WHERE courseid = $preferences->backup_course
1465 ORDER BY sortorder ASC")) {
1467 //Begin grade_items tag
1468 fwrite ($bf,start_tag("GRADE_ITEMS",3,true));
1469 //Iterate for each item
1470 foreach ($grade_items as $grade_item) {
1471 // Instantiate a grade_item object, to access its methods
1472 $grade_item = grade_object::fetch_helper('grade_items', 'grade_item', $grade_item);
1474 // do not restore if this grade_item is a mod, and
1475 if ($grade_item->itemtype == 'mod') {
1477 // if no user data selected, we skip this grade_item
1478 if (!backup_userdata_selected($preferences,$grade_item->itemmodule,$grade_item->iteminstance)) {
1479 continue;
1481 } else if ($grade_item->itemtype == 'category') {
1482 // if not all grade items are being backed up
1483 // we ignore this type of grade_item and grades associated
1484 if (!$backupall) {
1485 continue;
1489 //Begin grade_item
1490 fwrite ($bf,start_tag("GRADE_ITEM",4,true));
1491 //Output individual fields
1493 fwrite ($bf,full_tag("ID",5,false,$grade_item->id));
1494 fwrite ($bf,full_tag("CATEGORYID",5,false,$grade_item->categoryid));
1495 fwrite ($bf,full_tag("ITEMNAME",5,false,$grade_item->itemname));
1496 fwrite ($bf,full_tag("ITEMTYPE",5,false,$grade_item->itemtype));
1497 fwrite ($bf,full_tag("ITEMMODULE",5,false,$grade_item->itemmodule));
1498 fwrite ($bf,full_tag("ITEMINSTANCE",5,false,$grade_item->iteminstance));
1499 fwrite ($bf,full_tag("ITEMNUMBER",5,false,$grade_item->itemnumber));
1500 fwrite ($bf,full_tag("ITEMINFO",5,false,$grade_item->iteminfo));
1501 fwrite ($bf,full_tag("IDNUMBER",5,false,$grade_item->idnumber));
1502 // use [idnumber] in calculation instead of [#giXXX#]
1503 fwrite ($bf,full_tag("CALCULATION",5,false,$grade_item->get_calculation()));
1504 fwrite ($bf,full_tag("GRADEMAX",5,false,$grade_item->grademax));
1505 fwrite ($bf,full_tag("GRADEMIN",5,false,$grade_item->grademin));
1506 fwrite ($bf,full_tag("SCALEID",5,false,$grade_item->scaleid));
1507 fwrite ($bf,full_tag("OUTCOMEID",5,false,$grade_item->outcomeid));
1508 fwrite ($bf,full_tag("GRADEPASS",5,false,$grade_item->gradepass));
1509 fwrite ($bf,full_tag("MULTFACTOR",5,false,$grade_item->multfactor));
1510 fwrite ($bf,full_tag("PLUSFACTOR",5,false,$grade_item->plusfactor));
1511 fwrite ($bf,full_tag("HIDDEN",5,false,$grade_item->hidden));
1512 fwrite ($bf,full_tag("LOCKED",5,false,$grade_item->locked));
1513 fwrite ($bf,full_tag("LOCKTIME",5,false,$grade_item->locktime));
1515 // back up the other stuff here
1516 $status = backup_gradebook_grades_info($bf,$preferences,$grade_item->id);
1517 $status = backup_gradebook_grades_text_info($bf,$preferences,$grade_item->id);
1519 //End grade_item
1520 fwrite ($bf,end_tag("GRADE_ITEM",4,true));
1522 //End grade_items tag
1523 $status = fwrite ($bf,end_tag("GRADE_ITEMS",3,true));
1526 return $status;
1528 //Backup gradebook_item (called from backup_gradebook_info
1530 function backup_gradebook_outcomes_info($bf,$preferences) {
1532 global $CFG;
1533 $status = true;
1534 // only back up courses already in the grade_outcomes_courses table
1535 $grade_outcomes = get_records_sql('SELECT go.*
1536 FROM '.$CFG->prefix.'grade_outcomes_courses goc,
1537 '.$CFG->prefix.'grade_outcomes go
1538 WHERE goc.courseid = '.$preferences->backup_course.'
1539 AND goc.outcomeid = go.id');
1541 if (!empty($grade_outcomes)) {
1542 //Begin grade_outcomes tag
1543 fwrite ($bf,start_tag("GRADE_OUTCOMES",3,true));
1544 //Iterate for each outcome
1545 foreach ($grade_outcomes as $grade_outcome) {
1546 //Begin grade_outcome
1547 fwrite ($bf,start_tag("GRADE_OUTCOME",4,true));
1548 //Output individual fields
1550 fwrite ($bf,full_tag("ID",5,false,$grade_outcome->id));
1551 fwrite ($bf,full_tag("COURSEID",5,false,$grade_outcome->courseid));
1552 fwrite ($bf,full_tag("SHORTNAME",5,false,$grade_outcome->shortname));
1553 fwrite ($bf,full_tag("FULLNAME",5,false,$grade_outcome->fullname));
1554 fwrite ($bf,full_tag("SCALEID",5,false,$grade_outcome->scaleid));
1555 fwrite ($bf,full_tag("USERMODIFIED",5,false,$grade_outcome->usermodified));
1557 //End grade_outcome
1558 fwrite ($bf,end_tag("GRADE_OUTCOME",4,true));
1560 //End grade_outcomes tag
1561 $status = fwrite ($bf,end_tag("GRADE_OUTCOMES",3,true));
1563 return $status;
1566 // outcomes assigned to this course
1567 function backup_gradebook_outcomes_courses_info($bf,$preferences) {
1569 global $CFG;
1571 $status = true;
1572 // get all global outcomes (used in this course)
1573 // and course specific outcomes
1574 // we don't need to backup all the outcomes in this case
1575 if ($outcomes_courses = get_records('grade_outcomes_courses', 'courseid', $preferences->backup_course)) {
1576 //Begin grade_outcomes tag
1577 fwrite ($bf,start_tag("GRADE_OUTCOMES_COURSES",3,true));
1578 //Iterate for each outcome
1579 foreach ($outcomes_courses as $outcomes_course) {
1580 //Begin grade_outcome
1581 fwrite ($bf,start_tag("GRADE_OUTCOMES_COURSE",4,true));
1582 //Output individual fields
1583 fwrite ($bf,full_tag("ID",5,false,$outcomes_course->id));
1584 fwrite ($bf,full_tag("OUTCOMEID",5,false,$outcomes_course->outcomeid));
1586 //End grade_outcome
1587 fwrite ($bf,end_tag("GRADE_OUTCOMES_COURSE",4,true));
1589 //End grade_outcomes tag
1590 $status = fwrite ($bf,end_tag("GRADE_OUTCOMES_COURSES",3,true));
1592 return $status;
1595 function backup_gradebook_grades_info($bf,$preferences, $itemid) {
1597 global $CFG;
1599 $status = true;
1601 // find all grades belonging to this item
1602 if ($grades = get_records('grade_grades', 'itemid', $itemid)) {
1603 fwrite ($bf,start_tag("GRADE_GRADES",5,true));
1604 foreach ($grades as $grade) {
1605 fwrite ($bf,start_tag("GRADE",6,true));
1606 fwrite ($bf,full_tag("ID",7,false,$grade->id));
1607 fwrite ($bf,full_tag("USERID",7,false,$grade->userid));
1608 fwrite ($bf,full_tag("RAWGRADE",7,false,$grade->rawgrade));
1609 fwrite ($bf,full_tag("RAWGRADEMAX",7,false,$grade->rawgrademax));
1610 fwrite ($bf,full_tag("RAWGRADEMIN",7,false,$grade->rawgrademin));
1611 fwrite ($bf,full_tag("RAWSCALEID",7,false,$grade->rawscaleid));
1612 fwrite ($bf,full_tag("USERMODIFIED",7,false,$grade->usermodified));
1613 fwrite ($bf,full_tag("FINALGRADE",7,false,$grade->finalgrade));
1614 fwrite ($bf,full_tag("HIDDEN",7,false,$grade->hidden));
1615 fwrite ($bf,full_tag("LOCKED",7,false,$grade->locked));
1616 fwrite ($bf,full_tag("LOCKTIME",7,false,$grade->locktime));
1617 fwrite ($bf,full_tag("EXPORTED",7,false,$grade->exported));
1618 fwrite ($bf,full_tag("OVERRIDDEN",7,false,$grade->overridden));
1619 fwrite ($bf,full_tag("EXCLUDED",7,false,$grade->excluded));
1620 fwrite ($bf,end_tag("GRADE",6,true));
1622 $status = fwrite ($bf,end_tag("GRADE_GRADES",5,true));
1624 return $status;
1627 function backup_gradebook_grades_text_info($bf, $preferences, $itemid) {
1629 global $CFG;
1631 $status = true;
1633 // find all grade texts belonging to this item
1634 if ($grades = get_records('grade_grades', 'itemid', $itemid)) {
1635 fwrite ($bf,start_tag("GRADE_GRADES_TEXT",5,true));
1636 foreach ($grades as $grade) {
1637 if ($texts = get_records('grade_grades_text', 'gradeid', $grade->id)) {
1638 foreach ($texts as $text) {
1639 fwrite ($bf,start_tag("GRADE_TEXT",6,true));
1640 fwrite ($bf,full_tag("ID",7,false,$text->id));
1641 fwrite ($bf,full_tag("GRADEID",7,false,$text->gradeid));
1642 fwrite ($bf,full_tag("INFORMATION",7,false,$text->information));
1643 fwrite ($bf,full_tag("INFORMATIONFORMAT",7,false,$text->informationformat));
1644 fwrite ($bf,full_tag("FEEDBACK",7,false,$text->feedback));
1645 fwrite ($bf,full_tag("FEEDBACKFORMAT",7,false,$text->feedbackformat));
1646 fwrite ($bf,end_tag("GRADE_TEXT",6,true));
1650 $status = fwrite ($bf,end_tag("GRADE_GRADES_TEXT",5,true));
1652 return $status;
1655 function backup_gradebook_categories_history_info($bf, $preferences) {
1657 global $CFG;
1658 $status = true;
1660 // find all grade categories history
1661 if ($chs = get_records('grade_categories_history', 'courseid', $preferences->backup_course)) {
1662 fwrite ($bf,start_tag("GRADE_CATEGORIES_HISTORIES",5,true));
1663 foreach ($chs as $ch) {
1664 fwrite ($bf,start_tag("GRADE_CATEGORIES_HISTORY",6,true));
1665 fwrite ($bf,full_tag("ID",7,false,$ch->id));
1666 fwrite ($bf,full_tag("OLDID",7,false,$ch->oldid));
1667 fwrite ($bf,full_tag("ACTION",7,false,$ch->action));
1668 fwrite ($bf,full_tag("SOURCE",7,false,$ch->source));
1669 fwrite ($bf,full_tag("TIMEMODIFIED",7,false,$ch->timemodified));
1670 fwrite ($bf,full_tag("LOGGEDUSER",7,false,$ch->loggeduser));
1671 fwrite ($bf,full_tag("PARENT",7,false,$ch->parent));
1672 fwrite ($bf,full_tag("DEPTH",7,false,$ch->depth));
1673 fwrite ($bf,full_tag("PATH",7,false,$ch->path));
1674 fwrite ($bf,full_tag("FULLNAME",7,false,$ch->fullname));
1675 fwrite ($bf,full_tag("AGGRETGATION",7,false,$ch->aggregation));
1676 fwrite ($bf,full_tag("KEEPHIGH",7,false,$ch->keephigh));
1677 fwrite ($bf,full_tag("DROPLOW",7,false,$ch->droplow));
1678 fwrite ($bf,end_tag("GRADE_CATEGORIES_HISTORY",6,true));
1680 $status = fwrite ($bf,end_tag("GRADE_CATEGORIES_HISTORIES",5,true));
1682 return $status;
1685 function backup_gradebook_grades_history_info($bf, $preferences) {
1687 global $CFG;
1688 $status = true;
1690 // find all grade categories history
1691 if ($chs = get_records_sql("SELECT ggh.* FROM {$CFG->prefix}grade_grades_history ggh,
1692 {$CFG->prefix}grade_items gi
1693 WHERE gi.courseid = $preferences->backup_course
1694 AND ggh.itemid = gi.id")) {
1695 fwrite ($bf,start_tag("GRADE_GRADES_HISTORIES",5,true));
1696 foreach ($chs as $ch) {
1697 fwrite ($bf,start_tag("GRADE_GRADES_HISTORY",6,true));
1698 fwrite ($bf,full_tag("ID",7,false,$ch->id));
1699 fwrite ($bf,full_tag("OLDID",7,false,$ch->oldid));
1700 fwrite ($bf,full_tag("ACTION",7,false,$ch->action));
1701 fwrite ($bf,full_tag("SOURCE",7,false,$ch->source));
1702 fwrite ($bf,full_tag("TIMEMODIFIED",7,false,$ch->timemodified));
1703 fwrite ($bf,full_tag("LOGGEDUSER",7,false,$ch->loggeduser));
1704 fwrite ($bf,full_tag("ITEMID",7,false,$ch->itemid));
1705 fwrite ($bf,full_tag("USERID",7,false,$ch->userid));
1706 fwrite ($bf,full_tag("RAWGRADE",7,false,$ch->rawgrade));
1707 fwrite ($bf,full_tag("RAWGRADEMAX",7,false,$ch->rawgrademax));
1708 fwrite ($bf,full_tag("RAWGRADEMIN",7,false,$ch->rawgrademin));
1709 fwrite ($bf,full_tag("USERMODIFIED",7,false,$ch->usermodified));
1710 fwrite ($bf,full_tag("FINALGRADE",7,false,$ch->finalgrade));
1711 fwrite ($bf,full_tag("HIDDEN",7,false,$ch->hidden));
1712 fwrite ($bf,full_tag("LOCKED",7,false,$ch->locked));
1713 fwrite ($bf,full_tag("LOCKTIME",7,false,$ch->locktime));
1714 fwrite ($bf,full_tag("EXPORTED",7,false,$ch->exported));
1715 fwrite ($bf,full_tag("OVERRIDDEN",7,false,$ch->overridden));
1716 fwrite ($bf,full_tag("EXCLUDED",7,false,$ch->excluded));
1717 fwrite ($bf,end_tag("GRADE_GRADES_HISTORY",6,true));
1719 $status = fwrite ($bf,end_tag("GRADE_GRADES_HISTORIES",5,true));
1721 return $status;
1724 function backup_gradebook_grades_text_history_info($bf, $preferences) {
1726 global $CFG;
1727 $status = true;
1729 // find all grade categories history
1730 if ($chs = get_records_sql("SELECT ggth.* FROM {$CFG->prefix}grade_grades_text_history ggth,
1731 {$CFG->prefix}grade_grades gg,
1732 {$CFG->prefix}grade_items gi
1733 WHERE gi.courseid = $preferences->backup_course
1734 AND ggth.gradeid = gg.id
1735 AND gg.itemid = gi.id")) {
1737 fwrite ($bf,start_tag("GRADE_TEXT_HISTORIES",5,true));
1738 foreach ($chs as $ch) {
1739 fwrite ($bf,start_tag("GRADE_TEXT_HISTORY",6,true));
1740 fwrite ($bf,full_tag("ID",7,false,$ch->id));
1741 fwrite ($bf,full_tag("OLDID",7,false,$ch->oldid));
1742 fwrite ($bf,full_tag("ACTION",7,false,$ch->action));
1743 fwrite ($bf,full_tag("SOURCE",7,false,$ch->source));
1744 fwrite ($bf,full_tag("TIMEMODIFIED",7,false,$ch->timemodified));
1745 fwrite ($bf,full_tag("LOGGEDUSER",7,false,$ch->loggeduser));
1746 fwrite ($bf,full_tag("GRADEID",7,false,$ch->gradeid));
1747 fwrite ($bf,full_tag("INFORMATION",7,false,$ch->information));
1748 fwrite ($bf,full_tag("INFORMATIONFORMAT",7,false,$ch->informationformat));
1749 fwrite ($bf,full_tag("FEEDBACK",7,false,$ch->feedback));
1750 fwrite ($bf,full_tag("FEEDBACKFORMAT",7,false,$ch->feedbackformat));
1751 fwrite ($bf,full_tag("USERMODIFIED",7,false,$ch->usermodified));
1752 fwrite ($bf,end_tag("GRADE_TEXT_HISTORY",6,true));
1754 $status = fwrite ($bf,end_tag("GRADE_TEXT_HISTORIES",5,true));
1756 return $status;
1759 function backup_gradebook_items_history_info($bf, $preferences) {
1761 global $CFG;
1762 $status = true;
1764 // find all grade categories history
1765 if ($chs = get_records('grade_items_history','courseid', $preferences->backup_course)) {
1766 fwrite ($bf,start_tag("GRADE_ITEM_HISTORIES",5,true));
1767 foreach ($chs as $ch) {
1768 fwrite ($bf,start_tag("GRADE_ITEM_HISTORY",6,true));
1769 fwrite ($bf,full_tag("ID",7,false,$ch->id));
1770 fwrite ($bf,full_tag("OLDID",7,false,$ch->oldid));
1771 fwrite ($bf,full_tag("ACTION",7,false,$ch->action));
1772 fwrite ($bf,full_tag("SOURCE",7,false,$ch->source));
1773 fwrite ($bf,full_tag("TIMEMODIFIED",7,false,$ch->timemodified));
1774 fwrite ($bf,full_tag("LOGGEDUSER",7,false,$ch->loggeduser));
1775 fwrite ($bf,full_tag("CATEGORYID",7,false,$ch->categoryid));
1776 fwrite ($bf,full_tag("ITEMNAME",7,false,$ch->itemname));
1777 fwrite ($bf,full_tag("ITEMTYPE",7,false,$ch->itemtype));
1778 fwrite ($bf,full_tag("ITEMMODULE",7,false,$ch->itemmodule));
1779 fwrite ($bf,full_tag("ITEMINSTANCE",7,false,$ch->iteminstance));
1780 fwrite ($bf,full_tag("ITEMNUMBER",7,false,$ch->itemnumber));
1781 fwrite ($bf,full_tag("ITEMINFO",7,false,$ch->iteminfo));
1782 fwrite ($bf,full_tag("IDNUMBER",7,false,$ch->idnumber));
1783 fwrite ($bf,full_tag("CALCULATION",7,false,$ch->calculation));
1784 fwrite ($bf,full_tag("GRADETYPE",7,false,$ch->gradetype));
1785 fwrite ($bf,full_tag("GRADEMAX",7,false,$ch->grademax));
1786 fwrite ($bf,full_tag("GRADEMIN",7,false,$ch->grademin));
1787 fwrite ($bf,full_tag("SCALEID",7,false,$ch->scaleid));
1788 fwrite ($bf,full_tag("OUTCOMEID",7,false,$ch->outcomeid));
1789 fwrite ($bf,full_tag("GRADEPASS",7,false,$ch->gradepass));
1790 fwrite ($bf,full_tag("MULTFACTOR",7,false,$ch->multfactor));
1791 fwrite ($bf,full_tag("PLUSFACTOR",7,false,$ch->plusfactor));
1792 fwrite ($bf,full_tag("AGGREGATIONCOEF",7,false,$ch->aggregationcoef));
1793 fwrite ($bf,full_tag("SORTORDER",7,false,$ch->sortorder));
1794 fwrite ($bf,full_tag("HIDDEN",7,false,$ch->hidden));
1795 fwrite ($bf,full_tag("LOCKED",7,false,$ch->locked));
1796 fwrite ($bf,full_tag("LOCKTIME",7,false,$ch->locktime));
1797 fwrite ($bf,full_tag("NEEDSUPDATE",7,false,$ch->needsupdate));
1798 fwrite ($bf,end_tag("GRADE_ITEM_HISTORY",6,true));
1800 $status = fwrite ($bf,end_tag("GRADE_ITEM_HISTORIES",5,true));
1803 return $status;
1806 function backup_gradebook_outcomes_history($bf, $preferences) {
1807 global $CFG;
1808 $status = true;
1810 // find all grade categories history
1811 if ($chs = get_records('grade_outcomes_history','courseid', $preferences->backup_course)) {
1812 fwrite ($bf,start_tag("GRADE_OUTCOME_HISTORIES",5,true));
1813 foreach ($chs as $ch) {
1814 fwrite ($bf,start_tag("GRADE_OUTCOME_HISTORY",6,true));
1815 fwrite ($bf,full_tag("ID",7,false,$ch->id));
1816 fwrite ($bf,full_tag("OLDID",7,false,$ch->oldid));
1817 fwrite ($bf,full_tag("ACTION",7,false,$ch->action));
1818 fwrite ($bf,full_tag("SOURCE",7,false,$ch->source));
1819 fwrite ($bf,full_tag("TIMEMODIFIED",7,false,$ch->timemodified));
1820 fwrite ($bf,full_tag("LOGGEDUSER",7,false,$ch->loggeduser));
1821 fwrite ($bf,full_tag("SHORTNAME",7,false,$ch->shortname));
1822 fwrite ($bf,full_tag("FULLNAME",7,false,$ch->fullname));
1823 fwrite ($bf,full_tag("SCALEID",7,false,$ch->scaleid));
1824 fwrite ($bf,full_tag("DESCRIPTION",7,false,$ch->description));
1825 fwrite ($bf,end_tag("GRADE_OUTCOME_HISTORY",6,true));
1827 $status = fwrite ($bf,end_tag("GRADE_OUTCOME_HISTORIES",5,true));
1829 return $status;
1832 //Backup scales info (common and course scales)
1833 function backup_scales_info($bf,$preferences) {
1835 global $CFG;
1837 $status = true;
1839 //Counter, points to current record
1840 $counter = 0;
1842 //Get scales (common and course scales)
1843 $scales = get_records_sql("SELECT id, courseid, userid, name, scale, description, timemodified
1844 FROM {$CFG->prefix}scale
1845 WHERE courseid = '0' or courseid = $preferences->backup_course");
1847 //Copy only used scales to $backupscales. They will be in backup (unused no). See Bug 1223.
1848 $backupscales = array();
1849 if ($scales) {
1850 foreach ($scales as $scale) {
1851 if (course_scale_used($preferences->backup_course, $scale->id)) {
1852 $backupscales[] = $scale;
1857 //Pring scales header
1858 if ($backupscales) {
1859 //Pring scales header
1860 fwrite ($bf,start_tag("SCALES",2,true));
1861 //Iterate
1862 foreach ($backupscales as $scale) {
1863 //Begin scale tag
1864 fwrite ($bf,start_tag("SCALE",3,true));
1865 //Output scale tag
1866 fwrite ($bf,full_tag("ID",4,false,$scale->id));
1867 fwrite ($bf,full_tag("COURSEID",4,false,$scale->courseid));
1868 fwrite ($bf,full_tag("USERID",4,false,$scale->userid));
1869 fwrite ($bf,full_tag("NAME",4,false,$scale->name));
1870 fwrite ($bf,full_tag("SCALETEXT",4,false,$scale->scale));
1871 fwrite ($bf,full_tag("DESCRIPTION",4,false,$scale->description));
1872 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$scale->timemodified));
1873 //End scale tag
1874 fwrite ($bf,end_tag("SCALE",3,true));
1876 //End scales tag
1877 $status = fwrite ($bf,end_tag("SCALES",2,true));
1879 return $status;
1882 //Backup events info (course events)
1883 function backup_events_info($bf,$preferences) {
1885 global $CFG;
1887 $status = true;
1889 //Counter, points to current record
1890 $counter = 0;
1892 //Get events (course events)
1893 $events = get_records_select("event","courseid='$preferences->backup_course' AND instance='0'","id");
1895 //Pring events header
1896 if ($events) {
1897 //Pring events header
1898 fwrite ($bf,start_tag("EVENTS",2,true));
1899 //Iterate
1900 foreach ($events as $event) {
1901 //Begin event tag
1902 fwrite ($bf,start_tag("EVENT",3,true));
1903 //Output event tag
1904 fwrite ($bf,full_tag("ID",4,false,$event->id));
1905 fwrite ($bf,full_tag("NAME",4,false,$event->name));
1906 fwrite ($bf,full_tag("DESCRIPTION",4,false,$event->description));
1907 fwrite ($bf,full_tag("FORMAT",4,false,$event->format));
1908 fwrite ($bf,full_tag("GROUPID",4,false,$event->groupid));
1909 fwrite ($bf,full_tag("USERID",4,false,$event->userid));
1910 fwrite ($bf,full_tag("REPEATID",4,false,$event->repeatid));
1911 fwrite ($bf,full_tag("EVENTTYPE",4,false,$event->eventtype));
1912 fwrite ($bf,full_tag("MODULENAME",4,false,$event->modulename));
1913 fwrite ($bf,full_tag("TIMESTART",4,false,$event->timestart));
1914 fwrite ($bf,full_tag("TIMEDURATION",4,false,$event->timeduration));
1915 fwrite ($bf,full_tag("VISIBLE",4,false,$event->visible));
1916 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$event->timemodified));
1917 //End event tag
1918 fwrite ($bf,end_tag("EVENT",3,true));
1920 //End events tag
1921 $status = fwrite ($bf,end_tag("EVENTS",2,true));
1923 return $status;
1926 //Backup groups info
1927 function backup_groups_info($bf,$preferences) {
1929 global $CFG;
1931 $status = true;
1932 $status2 = true;
1934 //Get groups
1935 $groups = get_groups($preferences->backup_course); //TODO:check.
1937 //Pring groups header
1938 if ($groups) {
1939 //Pring groups header
1940 fwrite ($bf,start_tag("GROUPS",2,true));
1941 //Iterate
1942 foreach ($groups as $group) {
1943 //Begin group tag
1944 fwrite ($bf,start_tag("GROUP",3,true));
1945 //Output group contents
1946 fwrite ($bf,full_tag("ID",4,false,$group->id));
1947 ///fwrite ($bf,full_tag("COURSEID",4,false,$group->courseid));
1948 fwrite ($bf,full_tag("NAME",4,false,$group->name));
1949 fwrite ($bf,full_tag("DESCRIPTION",4,false,$group->description));
1950 fwrite ($bf,full_tag("ENROLMENTKEY",4,false,$group->enrolmentkey)); //TODO:
1951 fwrite ($bf,full_tag("LANG",4,false,$group->lang));
1952 fwrite ($bf,full_tag("THEME",4,false,$group->theme));
1953 fwrite ($bf,full_tag("PICTURE",4,false,$group->picture));
1954 fwrite ($bf,full_tag("HIDEPICTURE",4,false,$group->hidepicture));
1955 fwrite ($bf,full_tag("TIMECREATED",4,false,$group->timecreated));
1956 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$group->timemodified));
1958 //Now, backup groups_members, only if users are included
1959 if ($preferences->backup_users != 2) {
1960 $status2 = backup_groups_members_info($bf,$preferences,$group->id);
1963 //End group tag
1964 fwrite ($bf,end_tag("GROUP",3,true));
1966 //End groups tag
1967 $status = fwrite ($bf,end_tag("GROUPS",2,true));
1969 //Now save group_files
1970 if ($status && $status2) {
1971 $status2 = backup_copy_group_files($preferences);
1974 return ($status && $status2);
1977 //Backup groups_members info
1978 function backup_groups_members_info($bf,$preferences,$groupid) {
1980 global $CFG;
1982 $status = true;
1984 //Get groups_members
1985 $groups_members = groups_get_member_records($groupid);
1987 //Pring groups_members header
1988 if ($groups_members) {
1989 //Pring groups_members header
1990 fwrite ($bf,start_tag("MEMBERS",4,true));
1991 //Iterate
1992 foreach ($groups_members as $group_member) {
1993 //Begin group_member tag
1994 fwrite ($bf,start_tag("MEMBER",5,true));
1995 //Output group_member contents
1996 fwrite ($bf,full_tag("USERID",6,false,$group_member->userid));
1997 fwrite ($bf,full_tag("TIMEADDED",6,false,$group_member->timeadded));
1998 //End group_member tag
1999 fwrite ($bf,end_tag("MEMBER",5,true));
2001 //End groups_members tag
2002 $status = fwrite ($bf,end_tag("MEMBERS",4,true));
2004 return $status;
2007 //Backup groupings info
2008 function backup_groupings_info($bf,$preferences) {
2010 global $CFG;
2012 $status = true;
2013 $status2 = true;
2015 //Get groups
2016 $groupings = groups_get_grouping_records($preferences->backup_course);
2018 //Pring groups header
2019 if ($groupings) {
2020 //Pring groups header
2021 fwrite ($bf,start_tag("GROUPINGS",2,true));
2022 //Iterate
2023 foreach ($groupings as $grouping) {
2024 //Begin group tag
2025 fwrite ($bf,start_tag("GROUPING",3,true));
2026 //Output group contents
2027 fwrite ($bf,full_tag("ID",4,false,$grouping->id));
2028 fwrite ($bf,full_tag("NAME",4,false,$grouping->name));
2029 fwrite ($bf,full_tag("DESCRIPTION",4,false,$grouping->description));
2030 fwrite ($bf,full_tag("TIMECREATED",4,false,$grouping->timecreated));
2032 $status2 = backup_groupids_info($bf,$preferences,$grouping->id);
2034 //End group tag
2035 fwrite ($bf,end_tag("GROUPING",3,true));
2037 //End groups tag
2038 $status = fwrite ($bf,end_tag("GROUPINGS",2,true));
2040 //(Now save grouping_files)
2042 return ($status && $status2);
2045 //Backup groupings-groups info
2046 function backup_groupids_info($bf,$preferences,$groupingid) {
2048 global $CFG;
2050 $status = true;
2052 //Get groups_members
2053 $grouping_groups = groups_get_groups_in_grouping_records($groupingid) ;
2055 //Pring groups_members header
2056 if ($grouping_groups) {
2057 //Pring groups_members header
2058 fwrite ($bf,start_tag("GROUPS",4,true));
2059 //Iterate
2060 foreach ($grouping_groups as $group2) {
2061 //Begin group tag
2062 fwrite ($bf,start_tag("GROUP",5,true));
2063 //Output group_member contents
2064 fwrite ($bf,full_tag("GROUPID",6,false,$group2->groupid));
2065 fwrite ($bf,full_tag("TIMEADDED",6,false,$group2->timeadded)); //TODO:
2066 //End group tag
2067 fwrite ($bf,end_tag("GROUP",5,true));
2069 //End groups_members tag
2070 $status = fwrite ($bf,end_tag("GROUPS",4,true));
2072 return $status;
2075 //Start the modules tag
2076 function backup_modules_start ($bf,$preferences) {
2078 return fwrite ($bf,start_tag("MODULES",2,true));
2081 //End the modules tag
2082 function backup_modules_end ($bf,$preferences) {
2084 return fwrite ($bf,end_tag("MODULES",2,true));
2087 //This function makes all the necesary calls to every mod
2088 //to export itself and its files !!!
2089 function backup_module($bf,$preferences,$module) {
2091 global $CFG;
2093 $status = true;
2095 require_once($CFG->dirroot.'/mod/'.$module.'/backuplib.php');
2097 if (isset($preferences->mods[$module]->instances)
2098 && is_array($preferences->mods[$module]->instances)) {
2099 $onemodbackup = $module.'_backup_one_mod';
2100 if (function_exists($onemodbackup)) {
2101 foreach ($preferences->mods[$module]->instances as $instance => $object) {
2102 if (!empty($object->backup)) {
2103 $status = $onemodbackup($bf,$preferences,$instance);
2106 } else {
2107 $status = false;
2109 } else { // whole module.
2110 //First, re-check if necessary functions exists
2111 $modbackup = $module."_backup_mods";
2112 if (function_exists($modbackup)) {
2113 //Call the function
2114 $status = $modbackup($bf,$preferences);
2115 } else {
2116 //Something was wrong. Function should exist.
2117 $status = false;
2121 return $status;
2125 //This function encode things to make backup multi-site fully functional
2126 //It does this conversions:
2127 // - $CFG->wwwroot/file.php/courseid ------------------> $@FILEPHP@$ (slasharguments links)
2128 // - $CFG->wwwroot/file.php?file=/courseid ------------> $@FILEPHP@$ (non-slasharguments links)
2129 // - Every module xxxx_encode_content_links() is executed too
2131 function backup_encode_absolute_links($content) {
2133 global $CFG,$preferences;
2135 //Use one static variable to cache all the require_once calls that,
2136 //under PHP5 seems to increase load too much, and we are requiring
2137 //them here thousands of times (one per content). MDL-8700.
2138 //Once fixed by PHP, we'll delete this hack
2140 static $includedfiles;
2141 if (!isset($includedfiles)) {
2142 $includedfiles = array();
2145 //Check if preferences is ok. If it isn't set, we are
2146 //in a scheduled_backup to we are able to get a copy
2147 //from CFG->backup_preferences
2148 if (!isset($preferences)) {
2149 $mypreferences = $CFG->backup_preferences;
2150 } else {
2151 //We are in manual backups so global preferences must exist!!
2152 $mypreferences = $preferences;
2155 //First, we check for every call to file.php inside the course
2156 $search = array($CFG->wwwroot.'/file.php/'.$mypreferences->backup_course,
2157 $CFG->wwwroot.'/file.php?file=/'.$mypreferences->backup_course);
2159 $replace = array('$@FILEPHP@$','$@FILEPHP@$');
2161 $result = str_replace($search,$replace,$content);
2163 foreach ($mypreferences->mods as $name => $info) {
2164 /// We only include the corresponding backuplib.php if it hasn't been included before
2165 /// This will save some load under PHP5. MDL-8700.
2166 /// Once fixed by PHP, we'll delete this hack
2167 if (!in_array($name, $includedfiles)) {
2168 include_once("$CFG->dirroot/mod/$name/backuplib.php");
2169 $includedfiles[] = $name;
2171 //Check if the xxxx_encode_content_links exists
2172 $function_name = $name."_encode_content_links";
2173 if (function_exists($function_name)) {
2174 $result = $function_name($result,$mypreferences);
2178 if ($result != $content) {
2179 debugging('<br /><hr />'.s($content).'<br />changed to<br />'.s($result).'<hr /><br />');
2182 return $result;
2185 //This function copies all the needed files under the "users" directory to the "user_files"
2186 //directory under temp/backup
2187 function backup_copy_user_files ($preferences) {
2189 global $CFG;
2191 $status = true;
2193 //First we check to "user_files" exists and create it as necessary
2194 //in temp/backup/$backup_code dir
2195 $status = check_and_create_user_files_dir($preferences->backup_unique_code);
2197 //Now iterate over directories under "users" to check if that user must be
2198 //copied to backup
2200 $rootdir = $CFG->dataroot."/users";
2201 //Check if directory exists
2202 if (is_dir($rootdir)) {
2203 $list = list_directories ($rootdir);
2204 if ($list) {
2205 //Iterate
2206 foreach ($list as $dir) {
2207 //Look for dir like username in backup_ids
2208 $data = get_record ("backup_ids","backup_code",$preferences->backup_unique_code,
2209 "table_name","user",
2210 "old_id",$dir);
2211 //If exists, copy it
2212 if ($data) {
2213 $status = backup_copy_file($rootdir."/".$dir,
2214 $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/user_files/".$dir);
2220 return $status;
2223 //This function copies all the needed files under the "groups" directory to the "group_files"
2224 //directory under temp/backup
2225 function backup_copy_group_files ($preferences) {
2227 global $CFG;
2229 $status = true;
2231 //First we check if "group_files" exists and create it as necessary
2232 //in temp/backup/$backup_code dir
2233 $status = check_and_create_group_files_dir($preferences->backup_unique_code);
2235 //Now iterate over directories under "groups" to check if that user must be
2236 //copied to backup
2238 $rootdir = $CFG->dataroot.'/groups';
2239 //Check if directory exists
2240 if (is_dir($rootdir)) {
2241 $list = list_directories ($rootdir);
2242 if ($list) {
2243 //Iterate
2244 foreach ($list as $dir) {
2245 //Look for dir like group in groups table
2246 $data = groups_group_belongs_to_course($dir, $preferences->backup_course);
2247 //TODO:check. get_record ('groups', 'courseid', $preferences->backup_course,'id',$dir);
2248 //If exists, copy it
2249 if ($data) {
2250 $status = backup_copy_file($rootdir."/".$dir,
2251 $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/group_files/".$dir);
2256 return $status;
2259 //This function copies all the course files under the course directory (except the moddata
2260 //directory to the "course_files" directory under temp/backup
2261 function backup_copy_course_files ($preferences) {
2263 global $CFG;
2265 $status = true;
2267 //First we check to "course_files" exists and create it as necessary
2268 //in temp/backup/$backup_code dir
2269 $status = check_and_create_course_files_dir($preferences->backup_unique_code);
2271 //Now iterate over files and directories except $CFG->moddata and backupdata to be
2272 //copied to backup
2274 $rootdir = $CFG->dataroot."/".$preferences->backup_course;
2276 $name_moddata = $CFG->moddata;
2277 $name_backupdata = "backupdata";
2278 //Check if directory exists
2279 if (is_dir($rootdir)) {
2280 $list = list_directories_and_files ($rootdir);
2281 if ($list) {
2282 //Iterate
2283 foreach ($list as $dir) {
2284 if ($dir !== $name_moddata and $dir !== $name_backupdata) {
2285 $status = backup_copy_file($rootdir."/".$dir,
2286 $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/course_files/".$dir);
2291 return $status;
2294 * This function copies all the site files under the site directory (except the moddata and backupdata
2295 * directories to the "site_files" directory under temp/backup
2297 function backup_copy_site_files ($preferences) {
2299 global $CFG;
2301 $status = true;
2303 if ($preferences->backup_course == SITEID){
2304 return $status;
2307 //First we check to "site_files" exists and create it as necessary
2308 //in temp/backup/$backup_code dir
2309 $status = $status && check_and_create_site_files_dir($preferences->backup_unique_code);
2311 $rootdir = $CFG->dataroot."/".SITEID;
2315 $files = get_records_select('backup_files',
2316 "backup_code = '$preferences->backup_unique_code' AND file_type = 'site'");
2317 if ($files) {
2318 //Iterate
2319 foreach ($files as $fileobj) {
2320 //check for dir structure and create recursively
2321 $file = $fileobj->path;
2322 $status = $status && check_dir_exists(dirname($CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/site_files/".$file), true, true);
2323 $status = $status && backup_copy_file($rootdir."/".$file,
2324 $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/site_files/".$file);
2327 return $status;
2329 //This function creates the zip file containing all the backup info
2330 //moodle.xml, moddata, user_files, course_files.
2331 //The zipped file is created in the backup directory and named with
2332 //the "oficial" name of the backup
2333 //It uses "pclzip" if available or system "zip" (unix only)
2334 function backup_zip ($preferences) {
2336 global $CFG;
2338 $status = true;
2340 //Base dir where everything happens
2341 $basedir = cleardoubleslashes($CFG->dataroot."/temp/backup/".$preferences->backup_unique_code);
2342 //Backup zip file name
2343 $name = $preferences->backup_name;
2344 //List of files and directories
2345 $filelist = list_directories_and_files ($basedir);
2347 //Convert them to full paths
2348 $files = array();
2349 foreach ($filelist as $file) {
2350 $files[] = "$basedir/$file";
2353 $status = zip_files($files, "$basedir/$name");
2355 //echo "<br/>Status: ".$status; //Debug
2356 return $status;
2360 //This function copies the final zip to the course dir
2361 function copy_zip_to_course_dir ($preferences) {
2363 global $CFG;
2365 $status = true;
2367 //Define zip location (from)
2368 $from_zip_file = $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/".$preferences->backup_name;
2370 //Initialise $to_zip_file
2371 $to_zip_file="";
2373 //If $preferences->backup_destination isn't empty, then copy to custom directory
2374 if (!empty($preferences->backup_destination)) {
2375 $to_zip_file = $preferences->backup_destination."/".$preferences->backup_name;
2376 } else {
2377 //Define zip destination (course dir)
2378 $to_zip_file = $CFG->dataroot."/".$preferences->backup_course;
2380 //echo "<p>From: ".$from_zip_file."<br />"; //Debug
2382 //echo "<p>Checking: ".$to_zip_file."<br />"; //Debug
2384 //Checks course dir exists
2385 $status = check_dir_exists($to_zip_file,true);
2387 //Define zip destination (backup dir)
2388 $to_zip_file = $to_zip_file."/backupdata";
2390 //echo "<p>Checking: ".$to_zip_file."<br />"; //Debug
2392 //Checks backup dir exists
2393 $status = check_dir_exists($to_zip_file,true);
2395 //Define zip destination (zip file)
2396 $to_zip_file = $to_zip_file."/".$preferences->backup_name;
2399 //echo "<p>To: ".$to_zip_file."<br />"; //Debug
2401 //Copy zip file
2402 if ($status) {
2403 $status = backup_copy_file ($from_zip_file,$to_zip_file);
2406 return $status;
2410 * compatibility function
2411 * with new granular backup
2412 * we need to know
2414 function backup_userdata_selected($preferences,$modname,$modid) {
2415 return ((empty($preferences->mods[$modname]->instances)
2416 && !empty($preferences->mods[$modname]->userinfo))
2417 || (is_array($preferences->mods[$modname]->instances)
2418 && array_key_exists($modid,$preferences->mods[$modname]->instances)
2419 && !empty($preferences->mods[$modname]->instances[$modid]->userinfo)));
2423 function backup_mod_selected($preferences,$modname,$modid) {
2424 return ((empty($preferences->mods[$modname]->instances)
2425 && !empty($preferences->mods[$modname]->backup))
2426 || (is_array($preferences->mods[$modname]->instances)
2427 && array_key_exists($modid,$preferences->mods[$modname]->instances)
2428 && !empty($preferences->mods[$modname]->instances[$modid]->backup)));
2432 * Checks for the required files/functions to backup every mod
2433 * And check if there is data about it
2435 function backup_fetch_prefs_from_request(&$preferences,&$count,$course) {
2436 global $CFG,$SESSION;
2438 // check to see if it's in the session already
2439 if (!empty($SESSION->backupprefs) && array_key_exists($course->id,$SESSION->backupprefs) && !empty($SESSION->backupprefs[$course->id])) {
2440 $sprefs = $SESSION->backupprefs[$course->id];
2441 $preferences = $sprefs;
2442 // refetch backup_name just in case.
2443 $bn = optional_param('backup_name','',PARAM_FILE);
2444 if (!empty($bn)) {
2445 $preferences->backup_name = $bn;
2447 $count = 1;
2448 return true;
2451 if ($allmods = get_records("modules") ) {
2452 foreach ($allmods as $mod) {
2453 $modname = $mod->name;
2454 $modfile = "$CFG->dirroot/mod/$modname/backuplib.php";
2455 $modbackup = $modname."_backup_mods";
2456 $modbackupone = $modname."_backup_one_mod";
2457 $modcheckbackup = $modname."_check_backup_mods";
2458 if (!file_exists($modfile)) {
2459 continue;
2461 include_once($modfile);
2462 if (!function_exists($modbackup) || !function_exists($modcheckbackup)) {
2463 continue;
2465 $var = "exists_".$modname;
2466 $preferences->$var = true;
2467 $count++;
2468 // check that there are instances and we can back them up individually
2469 if (!count_records('course_modules','course',$course->id,'module',$mod->id) || !function_exists($modbackupone)) {
2470 continue;
2472 $var = 'exists_one_'.$modname;
2473 $preferences->$var = true;
2474 $varname = $modname.'_instances';
2475 $preferences->$varname = get_all_instances_in_course($modname,$course);
2476 foreach ($preferences->$varname as $instance) {
2477 $preferences->mods[$modname]->instances[$instance->id]->name = $instance->name;
2478 $var = 'backup_'.$modname.'_instance_'.$instance->id;
2479 $$var = optional_param($var,0);
2480 $preferences->$var = $$var;
2481 $preferences->mods[$modname]->instances[$instance->id]->backup = $$var;
2482 $var = 'backup_user_info_'.$modname.'_instance_'.$instance->id;
2483 $$var = optional_param($var,0);
2484 $preferences->$var = $$var;
2485 $preferences->mods[$modname]->instances[$instance->id]->userinfo = $$var;
2486 $var = 'backup_'.$modname.'_instances';
2487 $preferences->$var = 1; // we need this later to determine what to display in modcheckbackup.
2490 //Check data
2491 //Check module info
2492 $preferences->mods[$modname]->name = $modname;
2494 $var = "backup_".$modname;
2495 $$var = optional_param( $var,0);
2496 $preferences->$var = $$var;
2497 $preferences->mods[$modname]->backup = $$var;
2499 //Check include user info
2500 $var = "backup_user_info_".$modname;
2501 $$var = optional_param( $var,0);
2502 $preferences->$var = $$var;
2503 $preferences->mods[$modname]->userinfo = $$var;
2508 //Check other parameters
2509 $preferences->backup_metacourse = optional_param('backup_metacourse',1,PARAM_INT);
2510 $preferences->backup_users = optional_param('backup_users',1,PARAM_INT);
2511 $preferences->backup_logs = optional_param('backup_logs',0,PARAM_INT);
2512 $preferences->backup_user_files = optional_param('backup_user_files',1,PARAM_INT);
2513 $preferences->backup_course_files = optional_param('backup_course_files',1,PARAM_INT);
2514 $preferences->backup_gradebook_history = optional_param('backup_gradebook_history', 1, PARAM_INT);
2515 $preferences->backup_site_files = optional_param('backup_site_files',1,PARAM_INT);
2516 $preferences->backup_messages = optional_param('backup_messages',1,PARAM_INT);
2517 $preferences->backup_course = $course->id;
2518 $preferences->backup_name = required_param('backup_name',PARAM_FILE);
2519 $preferences->backup_unique_code = required_param('backup_unique_code');
2521 // put it (back) in the session
2522 $SESSION->backupprefs[$course->id] = $preferences;
2525 /* Finds all related roles used in course, mod and blocks context
2526 * @param object $preferences
2527 * @param object $course
2528 * @return array of role objects
2530 function backup_fetch_roles($preferences) {
2532 global $CFG;
2533 $contexts = array();
2534 $roles = array();
2536 /// adding course context
2537 $coursecontext = get_context_instance(CONTEXT_COURSE, $preferences->backup_course);
2538 $contexts[$coursecontext->id] = $coursecontext;
2540 /// adding mod contexts
2541 $mods = $preferences->mods;
2542 foreach ($mods as $modname => $mod) {
2543 $instances = $mod->instances;
2544 foreach ($instances as $id => $instance) {
2545 // if this type of mod is to be backed up
2546 if ($instance->backup) {
2547 $cm = get_coursemodule_from_instance($modname, $id);
2548 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
2549 // put context in array keys
2550 $contexts[$context->id] = $context;
2555 // add all roles assigned at user context
2556 if ($preferences->backup_users) {
2557 if ($users = get_records_sql("SELECT u.old_id, u.table_name,u.info
2558 FROM {$CFG->prefix}backup_ids u
2559 WHERE u.backup_code = '$preferences->backup_unique_code' AND
2560 u.table_name = 'user'")) {
2561 foreach ($users as $user) {
2562 $context = get_context_instance(CONTEXT_USER, $user->old_id);
2563 $contexts[$context->id] = $context;
2569 // add all roles assigned at block context
2570 if ($courseblocks = get_records_sql("SELECT *
2571 FROM {$CFG->prefix}block_instance
2572 WHERE pagetype = '".PAGE_COURSE_VIEW."'
2573 AND pageid = {$preferences->backup_course}")) {
2575 foreach ($courseblocks as $courseblock) {
2577 $context = get_context_instance(CONTEXT_BLOCK, $courseblock->id);
2578 $contexts[$context->id] = $context;
2582 // foreach context, call get_roles_on_exact_context insert into array
2583 foreach ($contexts as $context) {
2584 if ($proles = get_roles_on_exact_context($context)) {
2585 foreach ($proles as $prole) {
2586 $roles[$prole->id] = $prole;
2591 return $roles;
2594 /* function to print xml for overrides */
2595 function write_role_overrides_xml($bf, $context, $startlevel) {
2596 fwrite ($bf, start_tag("ROLES_OVERRIDES", $startlevel, true));
2597 if ($roles = get_roles_with_override_on_context($context)) {
2598 foreach ($roles as $role) {
2599 fwrite ($bf, start_tag("ROLE", $startlevel+1, true));
2600 fwrite ($bf, full_tag("ID", $startlevel+2, false, $role->id));
2601 fwrite ($bf, full_tag("NAME", $startlevel+2, false, $role->name));
2602 fwrite ($bf, full_tag("SHORTNAME", $startlevel+2, false, $role->shortname));
2603 fwrite ($bf, start_tag("CAPABILITIES", $startlevel+2, true));
2604 if ($capabilities = get_capabilities_from_role_on_context($role, $context)) {
2605 foreach ($capabilities as $capability) {
2606 fwrite ($bf, start_tag("CAPABILITY", $startlevel+3, true));
2607 fwrite ($bf, full_tag("NAME", $startlevel+4, false, $capability->capability));
2608 fwrite ($bf, full_tag("PERMISSION", $startlevel+4, false, $capability->permission));
2609 fwrite ($bf, full_tag("TIMEMODIFIED", $startlevel+4, false, $capability->timemodified));
2610 if (!isset($capability->modifierid)) {
2611 $capability->modifierid = 0;
2613 fwrite ($bf, full_tag("MODIFIERID", $startlevel+4, false, $capability->modifierid));
2614 fwrite ($bf, end_tag("CAPABILITY", $startlevel+3, true));
2617 fwrite ($bf, end_tag("CAPABILITIES", $startlevel+2, true));
2618 fwrite ($bf, end_tag("ROLE", $startlevel+1, true));
2621 fwrite ($bf, end_tag("ROLES_OVERRIDES", $startlevel, true));
2624 /* function to print xml for assignment */
2625 function write_role_assignments_xml($bf, $context, $startlevel) {
2626 /// write role_assign code here
2627 fwrite ($bf, start_tag("ROLES_ASSIGNMENTS", $startlevel, true));
2629 if ($roles = get_roles_with_assignment_on_context($context)) {
2630 foreach ($roles as $role) {
2631 fwrite ($bf, start_tag("ROLE", $startlevel+1, true));
2632 fwrite ($bf, full_tag("ID", $startlevel+2, false, $role->id));
2633 fwrite ($bf, full_tag("NAME", $startlevel+2, false, $role->name));
2634 fwrite ($bf, full_tag("SHORTNAME", $startlevel+2, false, $role->shortname));
2635 fwrite ($bf, start_tag("ASSIGNMENTS", $startlevel+2, true));
2636 if ($assignments = get_users_from_role_on_context($role, $context)) {
2637 foreach ($assignments as $assignment) {
2638 fwrite ($bf, start_tag("ASSIGNMENT", $startlevel+3, true));
2639 fwrite ($bf, full_tag("USERID", $startlevel+4, false, $assignment->userid));
2640 fwrite ($bf, full_tag("HIDDEN", $startlevel+4, false, $assignment->hidden));
2641 fwrite ($bf, full_tag("TIMESTART", $startlevel+4, false, $assignment->timestart));
2642 fwrite ($bf, full_tag("TIMEEND", $startlevel+4, false, $assignment->timeend));
2643 fwrite ($bf, full_tag("TIMEMODIFIED", $startlevel+4, false, $assignment->timemodified));
2644 if (!isset($assignment->modifierid)) {
2645 $assignment->modifierid = 0;
2647 fwrite ($bf, full_tag("MODIFIERID", $startlevel+4, false, $assignment->modifierid));
2648 fwrite ($bf, full_tag("ENROL", $startlevel+4, false, $assignment->enrol));
2649 fwrite ($bf, full_tag("SORTORDER", $startlevel+4, false, $assignment->sortorder));
2650 fwrite ($bf, end_tag("ASSIGNMENT", $startlevel+3, true));
2653 fwrite ($bf, end_tag("ASSIGNMENTS", $startlevel+2, true));
2654 fwrite ($bf, end_tag("ROLE", $startlevel+1, true));
2657 fwrite ($bf, end_tag("ROLES_ASSIGNMENTS", $startlevel, true));
2661 function backup_execute(&$preferences, &$errorstr) {
2662 global $CFG;
2663 $status = true;
2665 //Check for temp and backup and backup_unique_code directory
2666 //Create them as needed
2667 if (!defined('BACKUP_SILENTLY')) {
2668 echo "<li>".get_string("creatingtemporarystructures").'</li>';
2671 $status = check_and_create_backup_dir($preferences->backup_unique_code);
2672 //Empty dir
2673 if ($status) {
2674 $status = clear_backup_dir($preferences->backup_unique_code);
2677 //Delete old_entries from backup tables
2678 if (!defined('BACKUP_SILENTLY')) {
2679 echo "<li>".get_string("deletingolddata").'</li>';
2681 $status = backup_delete_old_data();
2682 if (!$status) {
2683 if (!defined('BACKUP_SILENTLY')) {
2684 error ("An error occurred deleting old backup data");
2686 else {
2687 $errorstr = "An error occurred deleting old backup data";
2688 return false;
2692 //Create the moodle.xml file
2693 if ($status) {
2694 if (!defined('BACKUP_SILENTLY')) {
2695 echo "<li>".get_string("creatingxmlfile");
2696 //Begin a new list to xml contents
2697 echo "<ul>";
2698 echo "<li>".get_string("writingheader").'</li>';
2700 //Obtain the xml file (create and open) and print prolog information
2701 $backup_file = backup_open_xml($preferences->backup_unique_code);
2702 if (!defined('BACKUP_SILENTLY')) {
2703 echo "<li>".get_string("writinggeneralinfo").'</li>';
2705 //Prints general info about backup to file
2706 if ($backup_file) {
2707 if (!$status = backup_general_info($backup_file,$preferences)) {
2708 if (!defined('BACKUP_SILENTLY')) {
2709 notify("An error occurred while backing up general info");
2711 else {
2712 $errorstr = "An error occurred while backing up general info";
2713 return false;
2717 if (!defined('BACKUP_SILENTLY')) {
2718 echo "<li>".get_string("writingcoursedata");
2719 //Start new ul (for course)
2720 echo "<ul>";
2721 echo "<li>".get_string("courseinfo").'</li>';
2723 //Prints course start (tag and general info)
2724 if ($status) {
2725 if (!$status = backup_course_start($backup_file,$preferences)) {
2726 if (!defined('BACKUP_SILENTLY')) {
2727 notify("An error occurred while backing up course start");
2729 else {
2730 $errorstr = "An error occurred while backing up course start";
2731 return false;
2735 //Metacourse information
2736 if ($status && $preferences->backup_metacourse) {
2737 if (!defined('BACKUP_SILENTLY')) {
2738 echo "<li>".get_string("metacourse").'</li>';
2740 if (!$status = backup_course_metacourse($backup_file,$preferences)) {
2741 if (!defined('BACKUP_SILENTLY')) {
2742 notify("An error occurred while backing up metacourse info");
2744 else {
2745 $errorstr = "An error occurred while backing up metacourse info";
2746 return false;
2750 if (!defined('BACKUP_SILENTLY')) {
2751 echo "<li>".get_string("blocks").'</li>';
2753 //Blocks information
2754 if ($status) {
2755 if (!$status = backup_course_blocks($backup_file,$preferences)) {
2756 if (!defined('BACKUP_SILENTLY')) {
2757 notify("An error occurred while backing up course blocks");
2759 else {
2760 $errorstr = "An error occurred while backing up course blocks";
2761 return false;
2765 if (!defined('BACKUP_SILENTLY')) {
2766 echo "<li>".get_string("sections").'</li>';
2768 //Section info
2769 if ($status) {
2770 if (!$status = backup_course_sections($backup_file,$preferences)) {
2771 if (!defined('BACKUP_SILENTLY')) {
2772 notify("An error occurred while backing up course sections");
2774 else {
2775 $errorstr = "An error occurred while backing up course sections";
2776 return false;
2781 //End course contents (close ul)
2782 if (!defined('BACKUP_SILENTLY')) {
2783 echo "</ul></li>";
2786 //User info
2787 if ($status) {
2788 if (!defined('BACKUP_SILENTLY')) {
2789 echo "<li>".get_string("writinguserinfo").'</li>';
2791 if (!$status = backup_user_info($backup_file,$preferences)) {
2792 if (!defined('BACKUP_SILENTLY')) {
2793 notify("An error occurred while backing up user info");
2795 else {
2796 $errorstr = "An error occurred while backing up user info";
2797 return false;
2802 //If we have selected to backup messages and we are
2803 //doing a SITE backup, let's do it
2804 if ($status && $preferences->backup_messages && $preferences->backup_course == SITEID) {
2805 if (!defined('BACKUP_SILENTLY')) {
2806 echo "<li>".get_string("writingmessagesinfo").'</li>';
2808 if (!$status = backup_messages($backup_file,$preferences)) {
2809 if (!defined('BACKUP_SILENTLY')) {
2810 notify("An error occurred while backing up messages");
2812 else {
2813 $errorstr = "An error occurred while backing up messages";
2814 return false;
2819 //If we have selected to backup quizzes or other modules that use questions
2820 //we've already added ids of categories and questions to backup to backup_ids table
2821 if ($status) {
2822 if (!defined('BACKUP_SILENTLY')) {
2823 echo "<li>".get_string("writingcategoriesandquestions").'</li>';
2825 require_once($CFG->dirroot.'/question/backuplib.php');
2826 if (!$status = backup_question_categories($backup_file, $preferences)) {
2827 if (!defined('BACKUP_SILENTLY')) {
2828 notify("An error occurred while backing up quiz categories");
2830 else {
2831 $errorstr = "An error occurred while backing up quiz categories";
2832 return false;
2837 //Print logs if selected
2838 if ($status) {
2839 if ($preferences->backup_logs) {
2840 if (!defined('BACKUP_SILENTLY')) {
2841 echo "<li>".get_string("writingloginfo").'</li>';
2843 if (!$status = backup_log_info($backup_file,$preferences)) {
2844 if (!defined('BACKUP_SILENTLY')) {
2845 notify("An error occurred while backing up log info");
2847 else {
2848 $errorstr = "An error occurred while backing up log info";
2849 return false;
2855 //Print scales info
2856 if ($status) {
2857 if (!defined('BACKUP_SILENTLY')) {
2858 echo "<li>".get_string("writingscalesinfo").'</li>';
2860 if (!$status = backup_scales_info($backup_file,$preferences)) {
2861 if (!defined('BACKUP_SILENTLY')) {
2862 notify("An error occurred while backing up scales");
2864 else {
2865 $errorstr = "An error occurred while backing up scales";
2866 return false;
2871 //Print groupings info
2872 if ($status) {
2873 if (!defined('BACKUP_SILENTLY')) {
2874 echo "<li>".get_string("writinggroupingsinfo").'</li>';
2876 if (!$status = backup_groupings_info($backup_file,$preferences)) {
2877 if (!defined('BACKUP_SILENTLY')) {
2878 notify("An error occurred while backing up groupings");
2880 else {
2881 $errorstr = "An error occurred while backing up groupings";
2882 return false;
2887 //Print groups info
2888 if ($status) {
2889 if (!defined('BACKUP_SILENTLY')) {
2890 echo "<li>".get_string("writinggroupsinfo").'</li>';
2892 if (!$status = backup_groups_info($backup_file,$preferences)) {
2893 if (!defined('BACKUP_SILENTLY')) {
2894 notify("An error occurred while backing up groups");
2896 else {
2897 $errostr = "An error occurred while backing up groups";
2898 return false;
2903 //Print events info
2904 if ($status) {
2905 if (!defined('BACKUP_SILENTLY')) {
2906 echo "<li>".get_string("writingeventsinfo").'</li>';
2908 if (!$status = backup_events_info($backup_file,$preferences)) {
2909 if (!defined('BACKUP_SILENTLY')) {
2910 notify("An error occurred while backing up events");
2912 else {
2913 $errorstr = "An error occurred while backing up events";
2914 return false;
2919 //Print gradebook info
2920 if ($status) {
2921 if (!defined('BACKUP_SILENTLY')) {
2922 echo "<li>".get_string("writinggradebookinfo").'</li>';
2924 if (!$status = backup_gradebook_info($backup_file,$preferences)) {
2925 if (!defined('BACKUP_SILENTLY')) {
2926 notify("An error occurred while backing up gradebook");
2928 else {
2929 $errorstr = "An error occurred while backing up gradebook";
2930 return false;
2935 //Module info, this unique function makes all the work!!
2936 //db export and module fileis copy
2937 if ($status) {
2938 $mods_to_backup = false;
2939 //Check if we have any mod to backup
2940 foreach ($preferences->mods as $module) {
2941 if ($module->backup) {
2942 $mods_to_backup = true;
2945 //If we have to backup some module
2946 if ($mods_to_backup) {
2947 if (!defined('BACKUP_SILENTLY')) {
2948 echo "<li>".get_string("writingmoduleinfo");
2950 //Start modules tag
2951 if (!$status = backup_modules_start ($backup_file,$preferences)) {
2952 if (!defined('BACKUP_SILENTLY')) {
2953 notify("An error occurred while backing up module info");
2955 else {
2956 $errorstr = "An error occurred while backing up module info";
2957 return false;
2960 //Open ul for module list
2961 if (!defined('BACKUP_SILENTLY')) {
2962 echo "<ul>";
2964 //Iterate over modules and call backup
2965 foreach ($preferences->mods as $module) {
2966 if ($module->backup and $status) {
2967 if (!defined('BACKUP_SILENTLY')) {
2968 echo "<li>".get_string("modulenameplural",$module->name).'</li>';
2970 if (!$status = backup_module($backup_file,$preferences,$module->name)) {
2971 if (!defined('BACKUP_SILENTLY')) {
2972 notify("An error occurred while backing up '$module->name'");
2974 else {
2975 $errorstr = "An error occurred while backing up '$module->name'";
2976 return false;
2981 //Close ul for module list
2982 if (!defined('BACKUP_SILENTLY')) {
2983 echo "</ul></li>";
2985 //Close modules tag
2986 if (!$status = backup_modules_end ($backup_file,$preferences)) {
2987 if (!defined('BACKUP_SILENTLY')) {
2988 notify("An error occurred while finishing the module backups");
2990 else {
2991 $errorstr = "An error occurred while finishing the module backups";
2992 return false;
2998 //Backup course format data, if any.
2999 if (!defined('BACKUP_SILENTLY')) {
3000 echo '<li>'.get_string("courseformatdata").'</li>';
3002 if($status) {
3003 if (!$status = backup_format_data($backup_file,$preferences)) {
3004 if (!defined('BACKUP_SILENTLY')) {
3005 notify("An error occurred while backing up the course format data");
3007 else {
3008 $errorstr = "An error occurred while backing up the course format data";
3009 return false;
3014 //Prints course end
3015 if ($status) {
3016 if (!$status = backup_course_end($backup_file,$preferences)) {
3017 if (!defined('BACKUP_SILENTLY')) {
3018 notify("An error occurred while closing the course backup");
3020 else {
3021 $errorstr = "An error occurred while closing the course backup";
3022 return false;
3026 //Close the xml file and xml data
3027 if ($backup_file) {
3028 backup_close_xml($backup_file);
3031 //End xml contents (close ul)
3032 if (!defined('BACKUP_SILENTLY')) {
3033 echo "</ul></li>";
3037 //Now, if selected, copy user files
3038 if ($status) {
3039 if ($preferences->backup_user_files) {
3040 if (!defined('BACKUP_SILENTLY')) {
3041 echo "<li>".get_string("copyinguserfiles").'</li>';
3043 if (!$status = backup_copy_user_files ($preferences)) {
3044 if (!defined('BACKUP_SILENTLY')) {
3045 notify("An error occurred while copying user files");
3047 else {
3048 $errorstr = "An error occurred while copying user files";
3049 return false;
3055 //Now, if selected, copy course files
3056 if ($status) {
3057 if ($preferences->backup_course_files) {
3058 if (!defined('BACKUP_SILENTLY')) {
3059 echo "<li>".get_string("copyingcoursefiles").'</li>';
3061 if (!$status = backup_copy_course_files ($preferences)) {
3062 if (!defined('BACKUP_SILENTLY')) {
3063 notify("An error occurred while copying course files");
3065 else {
3066 $errorstr = "An error occurred while copying course files";
3067 return false;
3072 //Now, if selected, copy site files
3073 if ($status) {
3074 if ($preferences->backup_site_files) {
3075 if (!defined('BACKUP_SILENTLY')) {
3076 echo "<li>".get_string("copyingsitefiles").'</li>';
3078 if (!$status = backup_copy_site_files ($preferences)) {
3079 if (!defined('BACKUP_SILENTLY')) {
3080 notify("An error occurred while copying site files");
3082 else {
3083 $errorstr = "An error occurred while copying site files";
3084 return false;
3089 //Now, zip all the backup directory contents
3090 if ($status) {
3091 if (!defined('BACKUP_SILENTLY')) {
3092 echo "<li>".get_string("zippingbackup").'</li>';
3094 if (!$status = backup_zip ($preferences)) {
3095 if (!defined('BACKUP_SILENTLY')) {
3096 notify("An error occurred while zipping the backup");
3098 else {
3099 $errorstr = "An error occurred while zipping the backup";
3100 return false;
3105 //Now, copy the zip file to course directory
3106 if ($status) {
3107 if (!defined('BACKUP_SILENTLY')) {
3108 echo "<li>".get_string("copyingzipfile").'</li>';
3110 if (!$status = copy_zip_to_course_dir ($preferences)) {
3111 if (!defined('BACKUP_SILENTLY')) {
3112 notify("An error occurred while copying the zip file to the course directory");
3114 else {
3115 $errorstr = "An error occurred while copying the zip file to the course directory";
3116 return false;
3121 //Now, clean temporary data (db and filesystem)
3122 if ($status) {
3123 if (!defined('BACKUP_SILENTLY')) {
3124 echo "<li>".get_string("cleaningtempdata").'</li>';
3126 if (!$status = clean_temp_data ($preferences)) {
3127 if (!defined('BACKUP_SILENTLY')) {
3128 notify("An error occurred while cleaning up temporary data");
3130 else {
3131 $errorstr = "An error occurred while cleaning up temporary data";
3132 return false;
3137 return $status;
3141 * This function generates the default zipfile name for a backup
3142 * based on the course id and the unique code.
3144 * @param object $course course object
3145 * @param string $backup_unique_code (optional, if left out current timestamp used)
3148 * @return string filename (excluding path information)
3150 function backup_get_zipfile_name($course, $backup_unique_code='') {
3152 if (empty($backup_unique_code)) {
3153 $backup_unique_code = time();
3156 //Calculate the backup word
3157 //Take off some characters in the filename !!
3158 $takeoff = array(" ", ":", "/", "\\", "|");
3159 $backup_word = str_replace($takeoff,"_",moodle_strtolower(get_string("backupfilename")));
3160 //If non-translated, use "backup"
3161 if (substr($backup_word,0,1) == "[") {
3162 $backup_word= "backup";
3165 //Calculate the date format string
3166 $backup_date_format = str_replace(" ","_",get_string("backupnameformat"));
3167 //If non-translated, use "%Y%m%d-%H%M"
3168 if (substr($backup_date_format,0,1) == "[") {
3169 $backup_date_format = "%%Y%%m%%d-%%H%%M";
3172 //Calculate the shortname
3173 $backup_shortname = clean_filename($course->shortname);
3174 if (empty($backup_shortname) or $backup_shortname == '_' ) {
3175 $backup_shortname = $course->id;
3178 //Calculate the final backup filename
3179 //The backup word
3180 $backup_name = $backup_word."-";
3181 //The shortname
3182 $backup_name .= moodle_strtolower($backup_shortname)."-";
3183 //The date format
3184 $backup_name .= userdate(time(),$backup_date_format,99,false);
3185 //The extension
3186 $backup_name .= ".zip";
3187 //And finally, clean everything
3188 $backup_name = clean_filename($backup_name);
3190 return $backup_name;
3195 * This function adds on the standard items to the preferences
3196 * Like moodle version and backup version
3198 * @param object $preferences existing preferences object.
3199 * (passed by reference)
3201 function backup_add_static_preferences(&$preferences) {
3202 global $CFG;
3203 $preferences->moodle_version = $CFG->version;
3204 $preferences->moodle_release = $CFG->release;
3205 $preferences->backup_version = $CFG->backup_version;
3206 $preferences->backup_release = $CFG->backup_release;