"MDL-14932, accessibility imporvement, see tracker"
[moodle-linuxchix.git] / backup / backuplib.php
blobe286b62490e5c972db05451c526c280038ad796a
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 /**
7 * This function calculates the users to be added to backup based in the
8 * settings defined at backup. All the resulting user ids are sent to
9 * backup_ids for later usage.
10 * @param int $courseid id of the course to backup
11 * @param int $backup_unique_code unique code of the backup being executed
12 * @param int $backup_unique_code setting specifying what users to export (0=all, 1=needed, 2=none)
13 * @param int $backup_messages flag (true/false) defining if messages must be
14 * considered to extract needed users
15 * @param int $backup_blogs flag (true/false) defining if blogs must be
16 * considered to extract needed users
17 * @return array one array (key, value) sumarizing the result of the function (number of users)
19 function user_check_backup($courseid,$backup_unique_code,$backup_users,$backup_messages,$backup_blogs) {
21 $context = get_context_instance(CONTEXT_COURSE, $courseid);
22 $count_users = 0;
23 $backupable_users = array();
25 if ($backup_users == 0) { /// All users
26 $backupable_users = backup_get_all_users();
28 } else if ($backup_users == 1) { /// Needed users
30 /// Calculate needed users (calling every xxxx_get_participants function + scales users
31 /// + messages users + blogs users)
32 $needed_users = backup_get_needed_users($courseid, $backup_messages, $backup_blogs);
34 /// Calculate enrolled users (having course:view cap)
35 $enrolled_users = backup_get_enrolled_users($courseid);
37 /// Calculate backupable users (needed + enrolled)
38 /// First, needed
39 $backupable_users = $needed_users;
41 /// Now, enrolled
42 if ($enrolled_users) {
43 foreach ($enrolled_users as $enrolled_user) {
44 $backupable_users[$enrolled_user->id]->id = $enrolled_user->id;
49 /// If we have backupable users
50 if ($backupable_users) {
51 /// Iterate over users putting their roles
52 foreach ($backupable_users as $backupable_user) {
53 $backupable_user->info = "";
55 /// Is needed user or enrolled user, mark it as needed
56 if (isset($needed_users[$backupable_user->id]) || isset($enrolled_users[$backupable_user->id])) {
57 $backupable_user->info .= "needed";
58 } /// Yu: also needed because they can view course
59 /// might need another variable
61 /// Now create the backup_id record
62 $backupids_rec->backup_code = $backup_unique_code;
63 $backupids_rec->table_name = "user";
64 $backupids_rec->old_id = $backupable_user->id;
65 $backupids_rec->info = $backupable_user->info;
67 /// TODO: Change this call inserting to a standard backup_putid() call
68 /// And read data acordingly with backup_getid() when needed.
69 /// TODO: Also analyse it the "needed" info is really needed for anything. Drop if not.
70 /// Insert the user to the backup_ids table. backup_user_info() will use that info
71 $status = insert_record('backup_ids', $backupids_rec, false);
72 $count_users++;
74 /// Do some output
75 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 //Also it search for users having messages and
90 //users having blogs
91 //WARNING: It returns only NEEDED users, not every
92 // every student and teacher in the course, so it
93 //must be merged with backup_get_enrrolled_users !!
95 function backup_get_needed_users ($courseid, $includemessages=false, $includeblogs=false) {
97 global $CFG;
99 $result = false;
101 $course_modules = get_records_sql ("SELECT cm.id, m.name, cm.instance
102 FROM {$CFG->prefix}modules m,
103 {$CFG->prefix}course_modules cm
104 WHERE m.id = cm.module and
105 cm.course = '$courseid'");
107 if ($course_modules) {
108 //Iterate over each module
109 foreach ($course_modules as $course_module) {
110 $modlib = "$CFG->dirroot/mod/$course_module->name/lib.php";
111 $modgetparticipants = $course_module->name."_get_participants";
112 if (file_exists($modlib)) {
113 include_once($modlib);
114 if (function_exists($modgetparticipants)) {
115 $module_participants = $modgetparticipants($course_module->instance);
116 //Add them to result
117 if ($module_participants) {
118 foreach ($module_participants as $module_participant) {
119 $result[$module_participant->id]->id = $module_participant->id;
127 //Now, add scale users (from site and course scales)
128 //Get users
129 $scaleusers = get_records_sql("SELECT DISTINCT userid,userid
130 FROM {$CFG->prefix}scale
131 WHERE courseid = '0' or courseid = '$courseid'");
132 //Add scale users to results
133 if ($scaleusers) {
134 foreach ($scaleusers as $scaleuser) {
135 //If userid != 0
136 if ($scaleuser->userid != 0) {
137 $result[$scaleuser->userid]->id = $scaleuser->userid;
142 //Now, add message users if necessary
143 if ($includemessages) {
144 include_once("$CFG->dirroot/message/lib.php");
145 //Get users
146 $messageusers = message_get_participants();
147 //Add message users to results
148 if ($messageusers) {
149 foreach ($messageusers as $messageuser) {
150 //If id != 0
151 if ($messageuser->id !=0) {
152 $result[$messageuser->id]->id = $messageuser->id;
158 //Now, add blog users if necessary
159 if ($includeblogs) {
160 include_once("$CFG->dirroot/blog/lib.php");
161 //Get users
162 $blogusers = blog_get_participants();
163 //Add blog users to results
164 if ($blogusers) {
165 foreach ($blogusers as $bloguser) {
166 //If id != 0
167 if ($bloguser->id !=0) {
168 $result[$bloguser->id]->id = $bloguser->id;
174 return $result;
178 //Returns every enrolled user (student and teacher) in a course
180 function backup_get_enrolled_users ($courseid) {
182 global $CFG;
184 // get all users with moodle/course:view capability, this will include people
185 // assigned at cat level, or site level
186 // but it should be ok if they have no direct assignment at course, mod, block level
187 return get_users_by_capability(get_context_instance(CONTEXT_COURSE, $courseid), 'moodle/course:view');
190 //Returns all users ids (every record in users table)
191 function backup_get_all_users() {
193 return get_records('user', '', '', '', 'id, id');
196 //Calculate the number of log entries to backup
197 //Return an array of info (name,value)
198 function log_check_backup($course) {
200 global $CFG;
202 //Now execute the count
203 $ids = count_records("log","course",$course);
205 //Gets the user data
206 $info[0][0] = get_string("logs");
207 if ($ids) {
208 $info[0][1] = $ids;
209 } else {
210 $info[0][1] = 0;
213 return $info;
216 //Calculate the number of user files to backup
217 //Under $CFG->dataroot/users
218 //and put them (their path) in backup_ids
219 //Return an array of info (name,value)
220 function user_files_check_backup($course,$backup_unique_code) {
222 global $CFG;
224 $rootdir = $CFG->dataroot."/users";
225 //Check if directory exists
226 if (is_dir($rootdir)) {
227 //Get directories without descend
228 $userdirs = get_directory_list($rootdir,"",false,true,false);
229 foreach ($userdirs as $dir) {
230 //Extracts user id from file path
231 $tok = strtok($dir,"/");
232 if ($tok) {
233 $userid = $tok;
234 } else {
235 //We were getting $dir='0', so continue (WAS: $tok = "";)
236 continue;
238 //Look it is a backupable user
239 $data = get_record ("backup_ids","backup_code","$backup_unique_code",
240 "table_name","user",
241 "old_id",$userid);
242 if ($data) {
243 //Insert them into backup_files
244 $status = execute_sql("INSERT INTO {$CFG->prefix}backup_files
245 (backup_code, file_type, path, old_id)
246 VALUES
247 ('$backup_unique_code','user','".addslashes($dir)."','$userid')",false);
249 //Do some output
250 backup_flush(30);
254 //Now execute the select
255 $ids = get_records_sql("SELECT DISTINCT b.path, b.old_id
256 FROM {$CFG->prefix}backup_files b
257 WHERE backup_code = '$backup_unique_code' AND
258 file_type = 'user'");
259 //Gets the user data
260 $info[0][0] = get_string("files");
261 if ($ids) {
262 $info[0][1] = count($ids);
263 } else {
264 $info[0][1] = 0;
267 return $info;
271 * Calculate the number of course files to backup
272 * under $CFG->dataroot/$course, except $CFG->moddata, and backupdata
273 * and put them (their path) in backup_ids
274 * Return an array of info (name,value)
276 function course_files_check_backup($course, $backup_unique_code) {
278 global $CFG;
280 $rootdir = $CFG->dataroot."/$course";
281 //Check if directory exists
282 if (is_dir($rootdir)) {
283 //Get files and directories without descend
284 $coursedirs = get_directory_list($rootdir,$CFG->moddata,false,true,true);
285 $backupdata_dir = "backupdata";
286 foreach ($coursedirs as $dir) {
287 //Check it isn't backupdata_dir
288 if (strpos($dir,$backupdata_dir)!==0) {
289 //Insert them into backup_files
290 $status = execute_sql("INSERT INTO {$CFG->prefix}backup_files
291 (backup_code, file_type, path)
292 VALUES
293 ('$backup_unique_code','course','".addslashes($dir)."')",false);
295 //Do some output
296 backup_flush(30);
300 //Now execute the select
301 $ids = get_records_sql("SELECT DISTINCT b.path, b.old_id
302 FROM {$CFG->prefix}backup_files b
303 WHERE backup_code = '$backup_unique_code' AND
304 file_type = 'course'");
305 //Gets the user data
306 $info = array();
307 $info[0] = array();
308 $info[0][0] = get_string("files");
309 if ($ids) {
310 $info[0][1] = count($ids);
311 } else {
312 $info[0][1] = 0;
315 return $info;
319 * Calculate the number of site files to backup
320 * under $CFG->dataroot/SITEID
321 * Their path is already in backup_ids, put there by modules check_backup functions.
322 * Modules only put in paths of files that are used.
324 * Return an array of info (name,value)
326 function site_files_check_backup($course, $backup_unique_code) {
327 global $CFG;
329 //execute the select, records have been inserted by modules during their ****_check_backup_mods function.
330 $ids = get_records_sql("SELECT DISTINCT b.path
331 FROM {$CFG->prefix}backup_files b
332 WHERE backup_code = '$backup_unique_code' AND
333 file_type = 'site'");
334 //Gets the user data
335 $info = array();
336 $info[0] = array();
337 $info[0][0] = get_string('files');
338 if ($ids) {
339 $info[0][1] = count($ids);
340 } else {
341 $info[0][1] = 0;
344 return $info;
347 //Function to check and create the needed moddata dir to
348 //save all the mod backup files. We always name it moddata
349 //to be able to restore it, but in restore we check for
350 //$CFG->moddata !!
351 function check_and_create_moddata_dir($backup_unique_code) {
353 global $CFG;
355 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/moddata",true);
357 return $status;
360 //Function to check and create the "user_files" dir to
361 //save all the user files we need from "users" dir
362 function check_and_create_user_files_dir($backup_unique_code) {
364 global $CFG;
366 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/user_files",true);
368 return $status;
371 //Function to check and create the "group_files" dir to
372 //save all the user files we need from "groups" dir
373 function check_and_create_group_files_dir($backup_unique_code) {
375 global $CFG;
377 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/group_files",true);
379 return $status;
382 //Function to check and create the "course_files" dir to
383 //save all the course files we need from "CFG->datadir/course" dir
384 function check_and_create_course_files_dir($backup_unique_code) {
386 global $CFG;
388 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/course_files",true);
390 return $status;
393 //Function to check and create the "site_files" dir to
394 //save all the course files we need from "CFG->datadir/SITEID" dir
395 function check_and_create_site_files_dir($backup_unique_code) {
397 global $CFG;
399 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/site_files",true);
401 return $status;
404 //Function to create, open and write header of the xml file
405 function backup_open_xml($backup_unique_code) {
407 global $CFG;
409 $status = true;
411 //Open for writing
413 $file = $CFG->dataroot."/temp/backup/".$backup_unique_code."/moodle.xml";
414 $backup_file = fopen($file,"w");
415 //Writes the header
416 $status = fwrite ($backup_file,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
417 if ($status) {
418 $status = fwrite ($backup_file,start_tag("MOODLE_BACKUP",0,true));
420 if ($status) {
421 return $backup_file;
422 } else {
423 return false;
427 //Close the file
428 function backup_close_xml($backup_file) {
429 $status = fwrite ($backup_file,end_tag("MOODLE_BACKUP",0,true));
430 return fclose($backup_file);
433 //Return the xml start tag
434 function start_tag($tag,$level=0,$endline=false,$attributes=null) {
435 if ($endline) {
436 $endchar = "\n";
437 } else {
438 $endchar = "";
440 $attrstring = '';
441 if (!empty($attributes) && is_array($attributes)) {
442 foreach ($attributes as $key => $value) {
443 $attrstring .= " ".xml_tag_safe_content($key)."=\"".
444 xml_tag_safe_content($value)."\"";
447 return str_repeat(" ",$level*2)."<".strtoupper($tag).$attrstring.">".$endchar;
450 //Return the xml end tag
451 function end_tag($tag,$level=0,$endline=true) {
452 if ($endline) {
453 $endchar = "\n";
454 } else {
455 $endchar = "";
457 return str_repeat(" ",$level*2)."</".strtoupper($tag).">".$endchar;
460 //Return the start tag, the contents and the end tag
461 function full_tag($tag,$level=0,$endline=true,$content,$attributes=null) {
463 global $CFG;
464 //Here we encode absolute links
465 // MDL-10770
466 if (is_null($content)) {
467 $content = '$@NULL@$';
468 } else {
469 $content = backup_encode_absolute_links($content);
471 $st = start_tag($tag,$level,$endline,$attributes);
473 $co = xml_tag_safe_content($content);
475 $et = end_tag($tag,0,true);
477 return $st.$co.$et;
481 function xml_tag_safe_content($content) {
482 global $CFG;
483 //If enabled, we strip all the control chars (\x0-\x1f) from the text but tabs (\x9),
484 //newlines (\xa) and returns (\xd). The delete control char (\x7f) is also included.
485 //because they are forbiden in XML 1.0 specs. The expression below seems to be
486 //UTF-8 safe too because it simply ignores the rest of characters.
487 $content = preg_replace("/[\x-\x8\xb-\xc\xe-\x1f\x7f]/is","",$content);
488 $content = preg_replace("/\r\n|\r/", "\n", htmlspecialchars($content));
489 return $content;
492 //Prints General info about the course
493 //name, moodle_version (internal and release), backup_version, date, info in file...
494 function backup_general_info ($bf,$preferences) {
496 global $CFG;
498 fwrite ($bf,start_tag("INFO",1,true));
500 //The name of the backup
501 fwrite ($bf,full_tag("NAME",2,false,$preferences->backup_name));
502 //The moodle_version
503 fwrite ($bf,full_tag("MOODLE_VERSION",2,false,$preferences->moodle_version));
504 fwrite ($bf,full_tag("MOODLE_RELEASE",2,false,$preferences->moodle_release));
505 //The backup_version
506 fwrite ($bf,full_tag("BACKUP_VERSION",2,false,$preferences->backup_version));
507 fwrite ($bf,full_tag("BACKUP_RELEASE",2,false,$preferences->backup_release));
508 //The date
509 fwrite ($bf,full_tag("DATE",2,false,$preferences->backup_unique_code));
510 //The original site wwwroot
511 fwrite ($bf,full_tag("ORIGINAL_WWWROOT",2,false,$CFG->wwwroot));
512 //The zip method used
513 if (!empty($CFG->zip)) {
514 $zipmethod = 'external';
515 } else {
516 $zipmethod = 'internal';
518 //Indicate if it includes external MNET users
519 $sql = "SELECT b.old_id
520 FROM {$CFG->prefix}backup_ids b
521 JOIN {$CFG->prefix}user u ON b.old_id=u.id
522 WHERE b.backup_code = '$preferences->backup_unique_code'
523 AND b.table_name = 'user' AND u.mnethostid != '{$CFG->mnet_localhost_id}'";
524 if (record_exists_sql($sql)) {
525 fwrite ($bf,full_tag("MNET_REMOTEUSERS",2,false,'true'));
527 fwrite ($bf,full_tag("ZIP_METHOD",2,false,$zipmethod));
528 //Te includes tag
529 fwrite ($bf,start_tag("DETAILS",2,true));
530 //Now, go to mod element of preferences to print its status
531 foreach ($preferences->mods as $element) {
532 //Calculate info
533 $included = "false";
534 $userinfo = "false";
535 if ($element->backup) {
536 $included = "true";
537 if ($element->userinfo) {
538 $userinfo = "true";
541 //Prints the mod start
542 fwrite ($bf,start_tag("MOD",3,true));
543 fwrite ($bf,full_tag("NAME",4,false,$element->name));
544 fwrite ($bf,full_tag("INCLUDED",4,false,$included));
545 fwrite ($bf,full_tag("USERINFO",4,false,$userinfo));
547 if (isset($preferences->mods[$element->name]->instances)
548 && is_array($preferences->mods[$element->name]->instances)
549 && count($preferences->mods[$element->name]->instances)) {
550 fwrite ($bf, start_tag("INSTANCES",4,true));
551 foreach ($preferences->mods[$element->name]->instances as $id => $object) {
552 if (!empty($object->backup)) {
553 //Calculate info
554 $included = "false";
555 $userinfo = "false";
556 if ($object->backup) {
557 $included = "true";
558 if ($object->userinfo) {
559 $userinfo = "true";
562 fwrite ($bf, start_tag("INSTANCE",5,true));
563 fwrite ($bf, full_tag("ID",5,false,$id));
564 fwrite ($bf, full_tag("NAME",5,false,$object->name));
565 fwrite ($bf, full_tag("INCLUDED",5,false,$included)) ;
566 fwrite ($bf, full_tag("USERINFO",5,false,$userinfo));
567 fwrite ($bf, end_tag("INSTANCE",5,true));
570 fwrite ($bf, end_tag("INSTANCES",4,true));
574 //Print the end
575 fwrite ($bf,end_tag("MOD",3,true));
577 //The metacourse in backup
578 if ($preferences->backup_metacourse == 1) {
579 fwrite ($bf,full_tag("METACOURSE",3,false,"true"));
580 } else {
581 fwrite ($bf,full_tag("METACOURSE",3,false,"false"));
583 //The user in backup
584 if ($preferences->backup_users == 1) {
585 fwrite ($bf,full_tag("USERS",3,false,"course"));
586 } else if ($preferences->backup_users == 0) {
587 fwrite ($bf,full_tag("USERS",3,false,"all"));
588 } else {
589 fwrite ($bf,full_tag("USERS",3,false,"none"));
591 //The logs in backup
592 if ($preferences->backup_logs == 1) {
593 fwrite ($bf,full_tag("LOGS",3,false,"true"));
594 } else {
595 fwrite ($bf,full_tag("LOGS",3,false,"false"));
597 //The user files
598 if ($preferences->backup_user_files == 1) {
599 fwrite ($bf,full_tag("USERFILES",3,false,"true"));
600 } else {
601 fwrite ($bf,full_tag("USERFILES",3,false,"false"));
603 //The course files
604 if ($preferences->backup_course_files == 1) {
605 fwrite ($bf,full_tag("COURSEFILES",3,false,"true"));
606 } else {
607 fwrite ($bf,full_tag("COURSEFILES",3,false,"false"));
609 //The site files
610 if ($preferences->backup_site_files == 1) {
611 fwrite ($bf,full_tag("SITEFILES",3,false,"true"));
612 } else {
613 fwrite ($bf,full_tag("SITEFILES",3,false,"false"));
615 //The gradebook histories
616 if ($preferences->backup_gradebook_history == 1) {
617 fwrite ($bf,full_tag("GRADEBOOKHISTORIES",3,false,"true"));
618 } else {
619 fwrite ($bf,full_tag("GRADEBOOKHISTORIES",3,false,"false"));
621 //The messages in backup
622 if ($preferences->backup_messages == 1 && $preferences->backup_course == SITEID) {
623 fwrite ($bf,full_tag("MESSAGES",3,false,"true"));
624 } else {
625 fwrite ($bf,full_tag("MESSAGES",3,false,"false"));
627 //The blogs in backup
628 if ($preferences->backup_blogs == 1 && $preferences->backup_course == SITEID) {
629 fwrite ($bf,full_tag("BLOGS",3,false,"true"));
630 } else {
631 fwrite ($bf,full_tag("BLOGS",3,false,"false"));
633 //The mode of writing the block data
634 fwrite ($bf,full_tag('BLOCKFORMAT',3,false,'instances'));
635 fwrite ($bf,end_tag("DETAILS",2,true));
637 $status = fwrite ($bf,end_tag("INFO",1,true));
639 ///Roles stuff goes in here
641 fwrite ($bf, start_tag('ROLES', 1, true));
642 $roles = backup_fetch_roles($preferences);
644 $sitecontext = get_context_instance(CONTEXT_SYSTEM);
645 $coursecontext = get_context_instance(CONTEXT_COURSE, $preferences->backup_course);
647 foreach ($roles as $role) {
648 fwrite ($bf,start_tag('ROLE',2,true));
649 fwrite ($bf,full_tag('ID', 3, false, $role->id));
650 fwrite ($bf,full_tag('NAME',3,false,$role->name));
651 fwrite ($bf,full_tag('SHORTNAME',3,false,$role->shortname));
652 /// Calculate $role name in course
653 $nameincourse = role_get_name($role, $coursecontext);
654 if ($nameincourse != $role->name) {
655 fwrite ($bf,full_tag('NAMEINCOURSE', 3, false, $nameincourse));
657 // find and write all default capabilities
658 fwrite ($bf,start_tag('CAPABILITIES',3,true));
659 // pull out all default (site context) capabilities
660 if ($capabilities = role_context_capabilities($role->id, $sitecontext)) {
661 foreach ($capabilities as $capability=>$value) {
662 fwrite ($bf,start_tag('CAPABILITY',4,true));
663 fwrite ($bf,full_tag('NAME', 5, false, $capability));
664 fwrite ($bf,full_tag('PERMISSION', 5, false, $value));
665 // use this to pull out the other info (timemodified and modifierid)
667 $cap = get_record_sql("SELECT *
668 FROM {$CFG->prefix}role_capabilities
669 WHERE capability = '$capability'
670 AND contextid = $sitecontext->id
671 AND roleid = $role->id");
672 fwrite ($bf, full_tag("TIMEMODIFIED", 5, false, $cap->timemodified));
673 fwrite ($bf, full_tag("MODIFIERID", 5, false, $cap->modifierid));
674 fwrite ($bf,end_tag('CAPABILITY',4,true));
677 fwrite ($bf,end_tag('CAPABILITIES',3,true));
678 fwrite ($bf,end_tag('ROLE',2,true));
680 fwrite ($bf,end_tag('ROLES', 1, true));
681 return $status;
684 //Prints course's general info (table course)
685 function backup_course_start ($bf,$preferences) {
687 global $CFG;
689 $status = true;
691 //Course open tag
692 fwrite ($bf,start_tag("COURSE",1,true));
693 //Header open tag
694 fwrite ($bf,start_tag("HEADER",2,true));
696 //Get info from course
697 $course = get_record("course","id",$preferences->backup_course);
698 $context = get_context_instance(CONTEXT_COURSE, $course->id);
699 if ($course) {
700 //Prints course info
701 fwrite ($bf,full_tag("ID",3,false,$course->id));
702 //Obtain the category
703 $category = get_record("course_categories","id","$course->category");
704 if ($category) {
705 //Prints category info
706 fwrite ($bf,start_tag("CATEGORY",3,true));
707 fwrite ($bf,full_tag("ID",4,false,$course->category));
708 fwrite ($bf,full_tag("NAME",4,false,$category->name));
709 fwrite ($bf,end_tag("CATEGORY",3,true));
711 //Continues with the course
712 fwrite ($bf,full_tag("PASSWORD",3,false,$course->password));
713 fwrite ($bf,full_tag("FULLNAME",3,false,$course->fullname));
714 fwrite ($bf,full_tag("SHORTNAME",3,false,$course->shortname));
715 fwrite ($bf,full_tag("IDNUMBER",3,false,$course->idnumber));
716 fwrite ($bf,full_tag("SUMMARY",3,false,$course->summary));
717 fwrite ($bf,full_tag("FORMAT",3,false,$course->format));
718 fwrite ($bf,full_tag("SHOWGRADES",3,false,$course->showgrades));
719 fwrite ($bf,full_tag("NEWSITEMS",3,false,$course->newsitems));
720 fwrite ($bf,full_tag("TEACHER",3,false,$course->teacher));
721 fwrite ($bf,full_tag("TEACHERS",3,false,$course->teachers));
722 fwrite ($bf,full_tag("STUDENT",3,false,$course->student));
723 fwrite ($bf,full_tag("STUDENTS",3,false,$course->students));
724 fwrite ($bf,full_tag("GUEST",3,false,$course->guest));
725 fwrite ($bf,full_tag("STARTDATE",3,false,$course->startdate));
726 fwrite ($bf,full_tag("NUMSECTIONS",3,false,$course->numsections));
727 //fwrite ($bf,full_tag("SHOWRECENT",3,false,$course->showrecent)); INFO: This is out in 1.3
728 fwrite ($bf,full_tag("MAXBYTES",3,false,$course->maxbytes));
729 fwrite ($bf,full_tag("SHOWREPORTS",3,false,$course->showreports));
730 fwrite ($bf,full_tag("GROUPMODE",3,false,$course->groupmode));
731 fwrite ($bf,full_tag("GROUPMODEFORCE",3,false,$course->groupmodeforce));
732 fwrite ($bf,full_tag("DEFAULTGROUPINGID",3,false,$course->defaultgroupingid));
733 fwrite ($bf,full_tag("LANG",3,false,$course->lang));
734 fwrite ($bf,full_tag("THEME",3,false,$course->theme));
735 fwrite ($bf,full_tag("COST",3,false,$course->cost));
736 fwrite ($bf,full_tag("CURRENCY",3,false,$course->currency));
737 fwrite ($bf,full_tag("MARKER",3,false,$course->marker));
738 fwrite ($bf,full_tag("VISIBLE",3,false,$course->visible));
739 fwrite ($bf,full_tag("HIDDENSECTIONS",3,false,$course->hiddensections));
740 fwrite ($bf,full_tag("TIMECREATED",3,false,$course->timecreated));
741 fwrite ($bf,full_tag("TIMEMODIFIED",3,false,$course->timemodified));
742 //If not selected, force metacourse to 0
743 if (!$preferences->backup_metacourse) {
744 $status = fwrite ($bf,full_tag("METACOURSE",3,false,'0'));
745 //else, export the field as is in DB
746 } else {
747 $status = fwrite ($bf,full_tag("METACOURSE",3,false,$course->metacourse));
749 fwrite ($bf,full_tag("EXPIRENOTIFY",3,false,$course->expirynotify));
750 fwrite ($bf,full_tag("NOTIFYSTUDENTS",3,false,$course->notifystudents));
751 fwrite ($bf,full_tag("EXPIRYTHRESHOLD",3,false,$course->expirythreshold));
752 fwrite ($bf,full_tag("ENROLLABLE",3,false,$course->enrollable));
753 fwrite ($bf,full_tag("ENROLSTARTDATE",3,false,$course->enrolstartdate));
754 fwrite ($bf,full_tag("ENROLENDDATE",3,false,$course->enrolenddate));
755 fwrite ($bf,full_tag("ENROLPERIOD",3,false,$course->enrolperiod));
757 /// write local course overrides here?
758 write_role_overrides_xml($bf, $context, 3);
759 /// write role_assign code here
760 write_role_assignments_xml($bf, $preferences, $context, 3);
761 //Print header end
762 fwrite ($bf,end_tag("HEADER",2,true));
763 } else {
764 $status = false;
767 return $status;
770 //Prints course's end tag
771 function backup_course_end ($bf,$preferences) {
773 //Course end tag
774 $status = fwrite ($bf,end_tag("COURSE",1,true));
776 return $status;
780 //Prints course's metacourse info (table course_meta)
781 function backup_course_metacourse ($bf,$preferences) {
783 global $CFG;
785 $status = true;
787 //Get info from meta
788 $parents = get_records_sql ("SELECT m.*, c.idnumber, c.shortname
789 FROM {$CFG->prefix}course_meta m,
790 {$CFG->prefix}course c
791 WHERE m.child_course = '$preferences->backup_course' AND
792 m.parent_course = c.id");
793 $childs = get_records_sql ("SELECT m.*, c.idnumber, c.shortname
794 FROM {$CFG->prefix}course_meta m,
795 {$CFG->prefix}course c
796 WHERE m.parent_course = '$preferences->backup_course' AND
797 m.child_course = c.id");
799 if ($parents || $childs) {
800 //metacourse open tag
801 fwrite ($bf,start_tag("METACOURSE",2,true));
802 if ($parents) {
803 fwrite($bf, start_tag("PARENTS",3,true));
804 //Iterate over every parent
805 foreach ($parents as $parent) {
806 //Begin parent
807 fwrite ($bf,start_tag("PARENT",4,true));
808 fwrite ($bf,full_tag("ID",5,false,$parent->parent_course));
809 fwrite ($bf,full_tag("IDNUMBER",5,false,$parent->idnumber));
810 fwrite ($bf,full_tag("SHORTNAME",5,false,$parent->shortname));
811 //End parent
812 fwrite ($bf,end_tag("PARENT",4,true));
814 fwrite ($bf,end_tag("PARENTS",3,true));
816 if ($childs) {
817 fwrite($bf, start_tag("CHILDS",3,true));
818 //Iterate over every child
819 foreach ($childs as $child) {
820 //Begin parent
821 fwrite ($bf,start_tag("CHILD",4,true));
822 fwrite ($bf,full_tag("ID",5,false,$child->child_course));
823 fwrite ($bf,full_tag("IDNUMBER",5,false,$child->idnumber));
824 fwrite ($bf,full_tag("SHORTNAME",5,false,$child->shortname));
825 //End parent
826 fwrite ($bf,end_tag("CHILD",4,true));
828 fwrite ($bf,end_tag("CHILDS",3,true));
830 //metacourse close tag
831 $status = fwrite ($bf,end_tag("METACOURSE",3,true));
834 return $status;
838 //Prints course's messages info (tables message, message_read and message_contacts)
839 function backup_messages ($bf,$preferences) {
841 global $CFG;
843 $status = true;
845 /// Check we have something to backup
846 $unreads = count_records ('message');
847 $reads = count_records ('message_read');
848 $contacts= count_records ('message_contacts');
850 if ($unreads || $reads || $contacts) {
851 $counter = 0;
852 /// message open tag
853 fwrite ($bf,start_tag("MESSAGES",2,true));
855 if ($unreads) {
856 $rs_unreads = get_recordset('message');
857 /// Iterate over every unread
858 while ($unread = rs_fetch_next_record($rs_unreads)) {
859 /// start message
860 fwrite($bf, start_tag("MESSAGE",3,true));
861 fwrite ($bf,full_tag("ID",4,false,$unread->id));
862 fwrite ($bf,full_tag("STATUS",4,false,"UNREAD"));
863 fwrite ($bf,full_tag("USERIDFROM",4,false,$unread->useridfrom));
864 fwrite ($bf,full_tag("USERIDTO",4,false,$unread->useridto));
865 fwrite ($bf,full_tag("MESSAGE",4,false,$unread->message));
866 fwrite ($bf,full_tag("FORMAT",4,false,$unread->format));
867 fwrite ($bf,full_tag("TIMECREATED",4,false,$unread->timecreated));
868 fwrite ($bf,full_tag("MESSAGETYPE",4,false,$unread->messagetype));
869 /// end message
870 fwrite ($bf,end_tag("MESSAGE",3,true));
872 /// Do some output
873 $counter++;
874 if ($counter % 20 == 0) {
875 echo ".";
876 if ($counter % 400 == 0) {
877 echo "<br />";
879 backup_flush(300);
882 rs_close($rs_unreads);
885 if ($reads) {
886 $rs_reads = get_recordset('message_read');
887 /// Iterate over every unread
888 while ($read = rs_fetch_next_record($rs_reads)) {
889 /// start message
890 fwrite($bf, start_tag("MESSAGE",3,true));
891 fwrite ($bf,full_tag("ID",4,false,$read->id));
892 fwrite ($bf,full_tag("STATUS",4,false,"READ"));
893 fwrite ($bf,full_tag("USERIDFROM",4,false,$read->useridfrom));
894 fwrite ($bf,full_tag("USERIDTO",4,false,$read->useridto));
895 fwrite ($bf,full_tag("MESSAGE",4,false,$read->message));
896 fwrite ($bf,full_tag("FORMAT",4,false,$read->format));
897 fwrite ($bf,full_tag("TIMECREATED",4,false,$read->timecreated));
898 fwrite ($bf,full_tag("MESSAGETYPE",4,false,$read->messagetype));
899 fwrite ($bf,full_tag("TIMEREAD",4,false,$read->timeread));
900 fwrite ($bf,full_tag("MAILED",4,false,$read->mailed));
901 /// end message
902 fwrite ($bf,end_tag("MESSAGE",3,true));
904 /// Do some output
905 $counter++;
906 if ($counter % 20 == 0) {
907 echo ".";
908 if ($counter % 400 == 0) {
909 echo "<br />";
911 backup_flush(300);
914 rs_close($rs_reads);
917 if ($contacts) {
918 fwrite($bf, start_tag("CONTACTS",3,true));
919 $rs_contacts = get_recordset('message_contacts');
920 /// Iterate over every contact
921 while ($contact = rs_fetch_next_record($rs_contacts)) {
922 /// start contact
923 fwrite($bf, start_tag("CONTACT",4,true));
924 fwrite ($bf,full_tag("ID",5,false,$contact->id));
925 fwrite ($bf,full_tag("USERID",5,false,$contact->userid));
926 fwrite ($bf,full_tag("CONTACTID",5,false,$contact->contactid));
927 fwrite ($bf,full_tag("BLOCKED",5,false,$contact->blocked));
928 /// end contact
929 fwrite ($bf,end_tag("CONTACT",4,true));
931 /// Do some output
932 $counter++;
933 if ($counter % 20 == 0) {
934 echo ".";
935 if ($counter % 400 == 0) {
936 echo "<br />";
938 backup_flush(300);
941 rs_close($rs_contacts);
942 fwrite($bf, end_tag("CONTACTS",3,true));
945 /// messages close tag
946 $status = fwrite ($bf,end_tag("MESSAGES",2,true));
949 return $status;
953 //Print blogs info (post table, module=blog, course=0)
954 function backup_blogs($bf, $preferences) {
956 global $CFG;
958 $status = true;
960 /// Check we have something to backup
961 $siteblogs = count_records('post', 'module', 'blog', 'courseid', 0);
963 if ($siteblogs) {
964 $counter = 0;
965 /// blogs open tag
966 fwrite ($bf, start_tag("BLOGS",2,true));
968 if ($siteblogs) {
969 $rs_blogs = get_recordset_sql("SELECT * from {$CFG->prefix}post
970 WHERE module = 'blog'
971 AND courseid = 0");
972 /// Iterate over every blog
973 while ($blog = rs_fetch_next_record($rs_blogs)) {
974 /// start blog
975 fwrite($bf, start_tag("BLOG",3,true));
976 /// blog body
977 fwrite ($bf,full_tag("ID",4,false,$blog->id));
978 fwrite ($bf,full_tag("MODULE",4,false,$blog->module));
979 fwrite ($bf,full_tag("USERID",4,false,$blog->userid));
980 fwrite ($bf,full_tag("COURSEID",4,false,$blog->courseid));
981 fwrite ($bf,full_tag("GROUPID",4,false,$blog->groupid));
982 fwrite ($bf,full_tag("MODULEID",4,false,$blog->moduleid));
983 fwrite ($bf,full_tag("COURSEMODULEID",4,false,$blog->coursemoduleid));
984 fwrite ($bf,full_tag("SUBJECT",4,false,$blog->subject));
985 fwrite ($bf,full_tag("SUMMARY",4,false,$blog->summary));
986 fwrite ($bf,full_tag("CONTENT",4,false,$blog->content));
987 fwrite ($bf,full_tag("UNIQUEHASH",4,false,$blog->uniquehash));
988 fwrite ($bf,full_tag("RATING",4,false,$blog->rating));
989 fwrite ($bf,full_tag("FORMAT",4,false,$blog->format));
990 fwrite ($bf,full_tag("ATTACHMENT",4,false,$blog->attachment));
991 fwrite ($bf,full_tag("PUBLISHSTATE",4,false,$blog->publishstate));
992 fwrite ($bf,full_tag("LASTMODIFIED",4,false,$blog->lastmodified));
993 fwrite ($bf,full_tag("CREATED",4,false,$blog->created));
994 fwrite ($bf,full_tag("USERMODIFIED",4,false,$blog->usermodified));
996 /// Blog tags
997 /// Check if we have blog tags to backup
998 if (!empty($CFG->usetags)) {
999 if ($tags = tag_get_tags('post', $blog->id)) { //This return them ordered by default
1000 /// Start BLOG_TAGS tag
1001 fwrite ($bf,start_tag("BLOG_TAGS",4,true));
1002 /// Write blog tags fields
1003 foreach ($tags as $tag) {
1004 fwrite ($bf,start_tag("BLOG_TAG",5,true));
1005 fwrite ($bf,full_tag("NAME",6,false,$tag->name));
1006 fwrite ($bf,full_tag("RAWNAME",6,false,$tag->rawname));
1007 fwrite ($bf,end_tag("BLOG_TAG",5,true));
1009 /// End BLOG_TAGS tag
1010 fwrite ($bf,end_tag("BLOG_TAGS",4,true));
1014 /// Blog comments
1015 /// TODO: Blog comments go here (2.0)
1017 /// end blog
1018 fwrite($bf, end_tag("BLOG",3,true));
1020 /// Do some output
1021 $counter++;
1022 if ($counter % 20 == 0) {
1023 echo ".";
1024 if ($counter % 400 == 0) {
1025 echo "<br />";
1027 backup_flush(300);
1030 rs_close($rs_blogs);
1032 /// blogs close tag
1033 $status = fwrite($bf, end_tag("BLOGS",2,true));
1036 return $status;
1039 //Prints course's blocks info (table block_instance)
1040 function backup_course_blocks ($bf,$preferences) {
1042 global $CFG;
1044 $status = true;
1046 // Read all of the block table
1047 $blocks = blocks_get_record();
1049 $pages = array();
1050 $pages[] = page_create_object(PAGE_COURSE_VIEW, $preferences->backup_course);
1052 if (!empty($CFG->showblocksonmodpages)) {
1053 // get course structure
1054 $course = get_record('course', 'id', $preferences->backup_course);
1055 $modinfo =& get_fast_modinfo($course);
1057 foreach($preferences->mods as $module) {
1058 if (!$module->backup) {
1059 continue;
1062 if (empty($modinfo->instances[$module->name])) {
1063 continue;
1066 $pagetypes = page_import_types('mod/'.$module->name.'/');
1067 if (empty($pagetypes)) {
1068 continue;
1071 foreach($pagetypes as $pagetype) {
1072 foreach($modinfo->instances[$module->name] as $cm) {
1073 if (!empty($module->instances[$cm->instance]->backup)) {
1074 $pages[] = page_create_object($pagetype, $cm->instance);
1081 //Blocks open tag
1082 fwrite ($bf,start_tag('BLOCKS',2,true));
1084 foreach($pages as $page) {
1085 if ($instances = blocks_get_by_page($page)) {
1086 //Iterate over every block
1087 foreach ($instances as $position) {
1088 foreach ($position as $instance) {
1090 //If we somehow have a block with an invalid id, skip it
1091 if(empty($blocks[$instance->blockid]->name)) {
1092 continue;
1094 $blockname = $blocks[$instance->blockid]->name;
1096 if (!$blockobj = block_instance($blockname, $instance)) {
1097 // Invalid block
1098 continue;
1101 // encode absolute links in block config
1102 $instance->configdata = $blockobj->get_backup_encoded_config();
1104 //Begin Block
1105 fwrite ($bf,start_tag('BLOCK',3,true));
1106 fwrite ($bf,full_tag('ID', 4, false,$instance->id));
1107 fwrite ($bf,full_tag('NAME',4,false,$blockname));
1108 fwrite ($bf,full_tag('PAGEID',4,false,$instance->pageid));
1109 fwrite ($bf,full_tag('PAGETYPE',4,false,$instance->pagetype));
1110 fwrite ($bf,full_tag('POSITION',4,false,$instance->position));
1111 fwrite ($bf,full_tag('WEIGHT',4,false,$instance->weight));
1112 fwrite ($bf,full_tag('VISIBLE',4,false,$instance->visible));
1113 fwrite ($bf,full_tag('CONFIGDATA',4,false,$instance->configdata));
1114 // Write instance data if needed
1115 if ($blockobj->backuprestore_instancedata_used()) {
1116 fwrite ($bf,start_tag('INSTANCEDATA',4,true));
1117 $status = $blockobj->instance_backup($bf, $preferences);
1118 fwrite ($bf,end_tag('INSTANCEDATA',4,true));
1120 $context = get_context_instance(CONTEXT_BLOCK, $instance->id);
1121 write_role_overrides_xml($bf, $context, 4);
1122 /// write role_assign code here
1123 write_role_assignments_xml($bf, $preferences, $context, 4);
1124 //End Block
1125 fwrite ($bf,end_tag('BLOCK',3,true));
1131 //Blocks close tag
1132 $status = fwrite ($bf,end_tag('BLOCKS',2,true));
1134 return $status;
1138 //Prints course's sections info (table course_sections)
1139 function backup_course_sections ($bf,$preferences) {
1141 global $CFG;
1143 $status = true;
1146 //Get info from sections
1147 $section=false;
1148 if ($sections = get_records("course_sections","course",$preferences->backup_course,"section")) {
1149 //Section open tag
1150 fwrite ($bf,start_tag("SECTIONS",2,true));
1151 //Iterate over every section (ordered by section)
1152 foreach ($sections as $section) {
1153 //Begin Section
1154 fwrite ($bf,start_tag("SECTION",3,true));
1155 fwrite ($bf,full_tag("ID",4,false,$section->id));
1156 fwrite ($bf,full_tag("NUMBER",4,false,$section->section));
1157 fwrite ($bf,full_tag("SUMMARY",4,false,$section->summary));
1158 fwrite ($bf,full_tag("VISIBLE",4,false,$section->visible));
1159 //Now print the mods in section
1160 backup_course_modules ($bf,$preferences,$section);
1161 //End section
1162 fwrite ($bf,end_tag("SECTION",3,true));
1164 //Section close tag
1165 $status = fwrite ($bf,end_tag("SECTIONS",2,true));
1168 return $status;
1172 //Prints course's format data (any data the format might want to save).
1173 function backup_format_data ($bf,$preferences) {
1174 global $CFG;
1176 // Check course format
1177 if(!($format=get_field('course','format','id',$preferences->backup_course))) {
1178 return false;
1180 // Write appropriate tag. Note that we always put this tag there even if
1181 // blank, it makes parsing easier
1182 fwrite ($bf,start_tag("FORMATDATA",2,true));
1184 $file=$CFG->dirroot."/course/format/$format/backuplib.php";
1185 if(file_exists($file)) {
1186 // If the file is there, the function must be or it's an error.
1187 require_once($file);
1188 $function=$format.'_backup_format_data';
1189 if(!function_exists($function)) {
1190 return false;
1192 if(!$function($bf,$preferences)) {
1193 return false;
1197 // This last return just checks the file writing has been ok (ish)
1198 return fwrite ($bf,end_tag("FORMATDATA",2,true));
1201 //Prints course's modules info (table course_modules)
1202 //Only for selected mods in preferences
1203 function backup_course_modules ($bf,$preferences,$section) {
1205 global $CFG;
1207 $status = true;
1209 $first_record = true;
1211 //Now print the mods in section
1212 //Extracts mod id from sequence
1213 $tok = strtok($section->sequence,",");
1214 while ($tok) {
1215 //Get module's type
1216 $moduletype = get_module_type ($preferences->backup_course,$tok);
1217 //Check if we've selected to backup that type
1218 if ($moduletype and $preferences->mods[$moduletype]->backup) {
1219 $selected = true;
1220 } else {
1221 $selected = false;
1224 if ($selected) {
1225 $context = get_context_instance(CONTEXT_MODULE, $tok);
1226 //Gets course_module data from db - verify activity exists and is enabled!
1227 $sql = "SELECT cm.*
1228 FROM {$CFG->prefix}course_modules cm
1229 JOIN {$CFG->prefix}modules m ON m.id = cm.module
1230 JOIN {$CFG->prefix}$moduletype a ON a.id = cm.instance
1231 WHERE m.visible = 1 AND cm.id = $tok";
1232 if (!$course_module = get_record_sql($sql)) {
1233 // cm exists but activity instance missing - probably caused by double clicking
1234 $tok = strtok(",");
1235 continue;
1238 //If it's the first, pring MODS tag
1239 if ($first_record) {
1240 fwrite ($bf,start_tag("MODS",4,true));
1241 $first_record = false;
1243 // if we're doing selected instances, check that too.
1244 if (is_array($preferences->mods[$moduletype]->instances)
1245 && count($preferences->mods[$moduletype]->instances)
1246 && (!array_key_exists($course_module->instance,$preferences->mods[$moduletype]->instances)
1247 || empty($preferences->mods[$moduletype]->instances[$course_module->instance]->backup))) {
1248 $tok = strtok(",");
1249 continue;
1252 // find all role values that has an override in this context
1253 $roles = get_records('role_capabilities', 'contextid', $context->id);
1255 //Print mod info from course_modules
1256 fwrite ($bf,start_tag("MOD",5,true));
1257 //Save neccesary info to backup_ids
1258 fwrite ($bf,full_tag("ID",6,false,$tok));
1259 fwrite ($bf,full_tag("TYPE",6,false,$moduletype));
1260 fwrite ($bf,full_tag("INSTANCE",6,false,$course_module->instance));
1261 fwrite ($bf,full_tag("ADDED",6,false,$course_module->added));
1262 fwrite ($bf,full_tag("SCORE",6,false,$course_module->score));
1263 fwrite ($bf,full_tag("INDENT",6,false,$course_module->indent));
1264 fwrite ($bf,full_tag("VISIBLE",6,false,$course_module->visible));
1265 fwrite ($bf,full_tag("GROUPMODE",6,false,$course_module->groupmode));
1266 fwrite ($bf,full_tag("GROUPINGID",6,false,$course_module->groupingid));
1267 fwrite ($bf,full_tag("GROUPMEMBERSONLY",6,false,$course_module->groupmembersonly));
1268 fwrite ($bf,full_tag("IDNUMBER",6,false,$course_module->idnumber));
1269 // get all the role_capabilities overrides in this mod
1270 write_role_overrides_xml($bf, $context, 6);
1271 /// write role_assign code here
1272 write_role_assignments_xml($bf, $preferences, $context, 6);
1273 /// write role_assign code here
1275 fwrite ($bf,end_tag("MOD",5,true));
1277 //check for next
1278 $tok = strtok(",");
1281 //Si ha habido modulos, final de MODS
1282 if (!$first_record) {
1283 $status =fwrite ($bf,end_tag("MODS",4,true));
1286 return $status;
1289 //Print users to xml
1290 //Only users previously calculated in backup_ids will output
1292 function backup_user_info ($bf,$preferences) {
1294 global $CFG;
1295 require_once ($CFG->dirroot.'/tag/lib.php');
1297 $status = true;
1299 // Use a recordset to for the memory handling on to
1300 // the DB and run faster
1301 $users = get_recordset_sql("SELECT b.old_id, b.table_name, b.info,
1302 u.*, m.wwwroot
1303 FROM {$CFG->prefix}backup_ids b
1304 JOIN {$CFG->prefix}user u ON b.old_id=u.id
1305 JOIN {$CFG->prefix}mnet_host m ON u.mnethostid=m.id
1306 WHERE b.backup_code = '$preferences->backup_unique_code' AND
1307 b.table_name = 'user'");
1309 //If we have users to backup
1310 if ($users && !rs_EOF($users)) {
1311 //Begin Users tag
1312 fwrite ($bf,start_tag("USERS",2,true));
1313 $counter = 0;
1314 //With every user
1315 while ($user = rs_fetch_next_record($users)) {
1316 //Begin User tag
1317 fwrite ($bf,start_tag("USER",3,true));
1318 //Output all user data
1319 fwrite ($bf,full_tag("ID",4,false,$user->id));
1320 fwrite ($bf,full_tag("AUTH",4,false,$user->auth));
1321 fwrite ($bf,full_tag("CONFIRMED",4,false,$user->confirmed));
1322 fwrite ($bf,full_tag("POLICYAGREED",4,false,$user->policyagreed));
1323 fwrite ($bf,full_tag("DELETED",4,false,$user->deleted));
1324 fwrite ($bf,full_tag("USERNAME",4,false,$user->username));
1325 fwrite ($bf,full_tag("PASSWORD",4,false,$user->password));
1326 fwrite ($bf,full_tag("IDNUMBER",4,false,$user->idnumber));
1327 fwrite ($bf,full_tag("FIRSTNAME",4,false,$user->firstname));
1328 fwrite ($bf,full_tag("LASTNAME",4,false,$user->lastname));
1329 fwrite ($bf,full_tag("EMAIL",4,false,$user->email));
1330 fwrite ($bf,full_tag("EMAILSTOP",4,false,$user->emailstop));
1331 fwrite ($bf,full_tag("ICQ",4,false,$user->icq));
1332 fwrite ($bf,full_tag("SKYPE",4,false,$user->skype));
1333 fwrite ($bf,full_tag("YAHOO",4,false,$user->yahoo));
1334 fwrite ($bf,full_tag("AIM",4,false,$user->aim));
1335 fwrite ($bf,full_tag("MSN",4,false,$user->msn));
1336 fwrite ($bf,full_tag("PHONE1",4,false,$user->phone1));
1337 fwrite ($bf,full_tag("PHONE2",4,false,$user->phone2));
1338 fwrite ($bf,full_tag("INSTITUTION",4,false,$user->institution));
1339 fwrite ($bf,full_tag("DEPARTMENT",4,false,$user->department));
1340 fwrite ($bf,full_tag("ADDRESS",4,false,$user->address));
1341 fwrite ($bf,full_tag("CITY",4,false,$user->city));
1342 fwrite ($bf,full_tag("COUNTRY",4,false,$user->country));
1343 fwrite ($bf,full_tag("LANG",4,false,$user->lang));
1344 fwrite ($bf,full_tag("THEME",4,false,$user->theme));
1345 fwrite ($bf,full_tag("TIMEZONE",4,false,$user->timezone));
1346 fwrite ($bf,full_tag("FIRSTACCESS",4,false,$user->firstaccess));
1347 fwrite ($bf,full_tag("LASTACCESS",4,false,$user->lastaccess));
1348 fwrite ($bf,full_tag("LASTLOGIN",4,false,$user->lastlogin));
1349 fwrite ($bf,full_tag("CURRENTLOGIN",4,false,$user->currentlogin));
1350 fwrite ($bf,full_tag("LASTIP",4,false,$user->lastip));
1351 fwrite ($bf,full_tag("SECRET",4,false,$user->secret));
1352 fwrite ($bf,full_tag("PICTURE",4,false,$user->picture));
1353 fwrite ($bf,full_tag("URL",4,false,$user->url));
1354 fwrite ($bf,full_tag("DESCRIPTION",4,false,$user->description));
1355 fwrite ($bf,full_tag("MAILFORMAT",4,false,$user->mailformat));
1356 fwrite ($bf,full_tag("MAILDIGEST",4,false,$user->maildigest));
1357 fwrite ($bf,full_tag("MAILDISPLAY",4,false,$user->maildisplay));
1358 fwrite ($bf,full_tag("HTMLEDITOR",4,false,$user->htmleditor));
1359 fwrite ($bf,full_tag("AJAX",4,false,$user->ajax));
1360 fwrite ($bf,full_tag("AUTOSUBSCRIBE",4,false,$user->autosubscribe));
1361 fwrite ($bf,full_tag("TRACKFORUMS",4,false,$user->trackforums));
1362 if ($user->mnethostid != $CFG->mnet_localhost_id) {
1363 fwrite ($bf,full_tag("MNETHOSTURL",4,false,$user->wwwroot));
1365 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$user->timemodified));
1367 /// write assign/override code for context_userid
1369 $user->isneeded = strpos($user->info,"needed");
1371 fwrite ($bf,start_tag("ROLES",4,true));
1372 if ($user->info != "needed" && $user->info!="") {
1373 //PRINT ROLE INFO
1374 $roles = explode(",", $user->info);
1375 foreach ($roles as $role) {
1376 if ($role!="" && $role!="needed") {
1377 fwrite ($bf,start_tag("ROLE",5,true));
1378 //Print Role info
1379 fwrite ($bf,full_tag("TYPE",6,false,$role));
1380 //Print ROLE end
1381 fwrite ($bf,end_tag("ROLE",5,true));
1385 //Needed
1386 if ($user->isneeded!==false) {
1387 //Print ROLE start
1388 fwrite ($bf,start_tag("ROLE",5,true));
1389 //Print Role info
1390 fwrite ($bf,full_tag("TYPE",6,false,"needed"));
1391 //Print ROLE end
1392 fwrite ($bf,end_tag("ROLE",5,true));
1395 //End ROLES tag
1396 fwrite ($bf,end_tag("ROLES",4,true));
1398 //Check if we have custom profile fields to backup
1399 if ($cpfields = get_records_sql("SELECT uif.shortname, uif.datatype, uid.data
1400 FROM {$CFG->prefix}user_info_field uif,
1401 {$CFG->prefix}user_info_data uid
1402 WHERE uif.id = uid.fieldid
1403 AND uid.userid = $user->id")) {
1404 //Start USER_CUSTOM_PROFILE_FIELDS tag
1405 fwrite ($bf,start_tag("USER_CUSTOM_PROFILE_FIELDS",4,true));
1406 //Write custom profile fields
1407 foreach ($cpfields as $cpfield) {
1408 fwrite ($bf,start_tag("USER_CUSTOM_PROFILE_FIELD",5,true));
1409 fwrite ($bf,full_tag("FIELD_NAME",6,false,$cpfield->shortname));
1410 fwrite ($bf,full_tag("FIELD_TYPE",6,false,$cpfield->datatype));
1411 fwrite ($bf,full_tag("FIELD_DATA",6,false,$cpfield->data));
1412 fwrite ($bf,end_tag("USER_CUSTOM_PROFILE_FIELD",5,true));
1414 //End USER_CUSTOM_PROFILE_FIELDS tag
1415 fwrite ($bf,end_tag("USER_CUSTOM_PROFILE_FIELDS",4,true));
1418 //Check if we have user tags to backup
1419 if (!empty($CFG->usetags)) {
1420 if ($tags = tag_get_tags('user', $user->id)) { //This return them ordered by default
1421 //Start USER_TAGS tag
1422 fwrite ($bf,start_tag("USER_TAGS",4,true));
1423 //Write user tags fields
1424 foreach ($tags as $tag) {
1425 fwrite ($bf,start_tag("USER_TAG",5,true));
1426 fwrite ($bf,full_tag("NAME",6,false,$tag->name));
1427 fwrite ($bf,full_tag("RAWNAME",6,false,$tag->rawname));
1428 fwrite ($bf,end_tag("USER_TAG",5,true));
1430 //End USER_TAGS tag
1431 fwrite ($bf,end_tag("USER_TAGS",4,true));
1435 //Check if we have user_preferences to backup
1436 if ($preferences_data = get_records("user_preferences","userid",$user->old_id)) {
1437 //Start USER_PREFERENCES tag
1438 fwrite ($bf,start_tag("USER_PREFERENCES",4,true));
1439 //Write each user_preference
1440 foreach ($preferences_data as $user_preference) {
1441 fwrite ($bf,start_tag("USER_PREFERENCE",5,true));
1442 fwrite ($bf,full_tag("NAME",6,false,$user_preference->name));
1443 fwrite ($bf,full_tag("VALUE",6,false,$user_preference->value));
1444 fwrite ($bf,end_tag("USER_PREFERENCE",5,true));
1446 //End USER_PREFERENCES tag
1447 fwrite ($bf,end_tag("USER_PREFERENCES",4,true));
1450 $context = get_context_instance(CONTEXT_USER, $user->old_id);
1452 write_role_overrides_xml($bf, $context, 4);
1453 /// write role_assign code here
1454 write_role_assignments_xml($bf, $preferences, $context, 4);
1455 //End User tag
1456 fwrite ($bf,end_tag("USER",3,true));
1457 //Do some output
1458 $counter++;
1459 if ($counter % 10 == 0) {
1460 echo ".";
1461 if ($counter % 200 == 0) {
1462 echo "<br />";
1464 backup_flush(300);
1467 //End Users tag
1468 fwrite ($bf,end_tag("USERS",2,true));
1469 } else {
1470 // There aren't any users.
1471 $status = true;
1474 if ($users) {
1475 rs_close($users);
1478 return $status;
1481 //Backup log info (time ordered)
1482 function backup_log_info($bf,$preferences) {
1484 global $CFG;
1486 //Number of records to get in every chunk
1487 $recordset_size = 1000;
1489 $status = true;
1491 //Counter, points to current record
1492 $counter = 0;
1494 //Count records
1495 $count_logs = count_records("log","course",$preferences->backup_course);
1497 //Pring logs header
1498 if ($count_logs > 0 ) {
1499 fwrite ($bf,start_tag("LOGS",2,true));
1501 while ($counter < $count_logs) {
1502 //Get a chunk of records
1503 $logs = get_records ("log","course",$preferences->backup_course,"time","*",$counter,$recordset_size);
1505 //We have logs
1506 if ($logs) {
1507 //Iterate
1508 foreach ($logs as $log) {
1509 //See if it is a valid module to backup
1510 if ($log->module == "course" or
1511 $log->module == "user" or
1512 (array_key_exists($log->module, $preferences->mods) and $preferences->mods[$log->module]->backup == 1)) {
1513 // logs with 'upload' in module field are ignored, there is no restore code anyway
1514 //Begin log tag
1515 fwrite ($bf,start_tag("LOG",3,true));
1517 //Output log tag
1518 fwrite ($bf,full_tag("ID",4,false,$log->id));
1519 fwrite ($bf,full_tag("TIME",4,false,$log->time));
1520 fwrite ($bf,full_tag("USERID",4,false,$log->userid));
1521 fwrite ($bf,full_tag("IP",4,false,$log->ip));
1522 fwrite ($bf,full_tag("MODULE",4,false,$log->module));
1523 fwrite ($bf,full_tag("CMID",4,false,$log->cmid));
1524 fwrite ($bf,full_tag("ACTION",4,false,$log->action));
1525 fwrite ($bf,full_tag("URL",4,false,$log->url));
1526 fwrite ($bf,full_tag("INFO",4,false,$log->info));
1528 //End log tag
1529 fwrite ($bf,end_tag("LOG",3,true));
1531 //Do some output
1532 $counter++;
1533 if ($counter % 20 == 0) {
1534 echo ".";
1535 if ($counter % 400 == 0) {
1536 echo "<br />";
1538 backup_flush(300);
1543 //End logs tag
1544 if ($count_logs > 0 ) {
1545 $status = fwrite ($bf,end_tag("LOGS",2,true));
1547 return $status;
1550 //Backup gradebook info
1551 function backup_gradebook_info($bf, $preferences) {
1552 global $CFG;
1553 require_once($CFG->libdir.'/gradelib.php');
1555 //first make sure items are properly sorted and everything is ok
1556 grade_category::fetch_course_tree($preferences->backup_course, true);
1557 grade_regrade_final_grades($preferences->backup_course);
1559 $status = true;
1561 // see if ALL grade items of type mod of this course are being backed up
1562 // if not, we do not need to backup grade category and associated grade items/grades
1563 $backupall = true;
1565 if ($grade_items = get_records_sql("SELECT *
1566 FROM {$CFG->prefix}grade_items
1567 WHERE courseid = $preferences->backup_course
1568 AND itemtype = 'mod'")) {
1569 foreach ($grade_items as $grade_item) {
1570 // get module information
1571 // if no user data selected, we do not backup categories
1572 if (!backup_userdata_selected($preferences,$grade_item->itemmodule,$grade_item->iteminstance)) {
1573 $backupall = false;
1574 break;
1577 unset($grade_items); //free memory
1580 //Gradebook header
1581 fwrite ($bf,start_tag("GRADEBOOK",2,true));
1583 $status = backup_gradebook_outcomes_info($bf, $preferences);
1584 $status = backup_gradebook_grade_letters_info($bf,$preferences);
1586 // Now backup grade_item (inside grade_category)
1587 if ($backupall) {
1588 $status = backup_gradebook_category_info($bf,$preferences);
1591 $status = backup_gradebook_item_info($bf,$preferences, $backupall);
1593 // backup gradebook histories
1594 if ($preferences->backup_gradebook_history) {
1595 $status = backup_gradebook_outcomes_history($bf, $preferences);
1596 $status = backup_gradebook_categories_history_info($bf, $preferences);
1597 $status = backup_gradebook_items_history_info($bf, $preferences);
1598 $status = backup_gradebook_grades_history_info($bf, $preferences);
1601 //Gradebook footer
1602 $status = fwrite ($bf,end_tag("GRADEBOOK",2,true));
1603 return $status;
1606 function backup_gradebook_category_info($bf, $preferences) {
1607 global $CFG;
1608 $status = true;
1610 // get grade categories in proper order - specified in category grade items
1611 $course_item = grade_item::fetch_course_item($preferences->backup_course);
1612 $grade_categories = get_records_sql("SELECT gc.*, gi.sortorder
1613 FROM {$CFG->prefix}grade_categories gc
1614 JOIN {$CFG->prefix}grade_items gi
1615 ON (gi.iteminstance = gc.id)
1616 WHERE gc.courseid = $preferences->backup_course
1617 AND (gi.itemtype='course' OR gi.itemtype='category')
1618 ORDER BY gi.sortorder ASC");
1620 if ($grade_categories) {
1621 //Begin grade_categories tag
1622 fwrite ($bf,start_tag("GRADE_CATEGORIES",3,true));
1623 //Iterate for each category
1624 foreach ($grade_categories as $grade_category) {
1625 //Begin grade_category
1626 fwrite ($bf,start_tag("GRADE_CATEGORY",4,true));
1627 //Output individual fields
1628 fwrite ($bf,full_tag("ID",5,false,$grade_category->id));
1630 // not keeping path and depth because they can be derived
1631 fwrite ($bf,full_tag("PARENT",5,false,$grade_category->parent));
1632 fwrite ($bf,full_tag("FULLNAME",5,false,$grade_category->fullname));
1633 fwrite ($bf,full_tag("AGGREGATION",5,false,$grade_category->aggregation));
1634 fwrite ($bf,full_tag("KEEPHIGH",5,false,$grade_category->keephigh));
1635 fwrite ($bf,full_tag("DROPLOW",5,false,$grade_category->droplow));
1636 fwrite ($bf,full_tag("AGGREGATEONLYGRADED",5,false,$grade_category->aggregateonlygraded));
1637 fwrite ($bf,full_tag("AGGREGATEOUTCOMES",5,false,$grade_category->aggregateoutcomes));
1638 fwrite ($bf,full_tag("AGGREGATESUBCATS",5,false,$grade_category->aggregatesubcats));
1639 fwrite ($bf,full_tag("TIMECREATED",5,false,$grade_category->timecreated));
1640 fwrite ($bf,full_tag("TIMEMODIFIED",5,false,$grade_category->timemodified));
1642 //End grade_category
1643 fwrite ($bf,end_tag("GRADE_CATEGORY",4,true));
1645 //End grade_categories tag
1646 $status = fwrite ($bf,end_tag("GRADE_CATEGORIES",3,true));
1649 return $status;
1652 //Backup gradebook_item (called from backup_gradebook_info
1653 function backup_gradebook_item_info($bf, $preferences, $backupall) {
1654 global $CFG;
1656 $status = true;
1657 // get all the grade_items, ordered by sort order since upon restoring, it is not always
1658 // possible to use the same sort order. We could at least preserve the sortorder by restoring
1659 // grade_items in the original sortorder
1660 if ($grade_items = get_records_sql("SELECT *
1661 FROM {$CFG->prefix}grade_items
1662 WHERE courseid = $preferences->backup_course
1663 ORDER BY sortorder ASC")) {
1665 //Begin grade_items tag
1666 fwrite ($bf,start_tag("GRADE_ITEMS",3,true));
1667 //Iterate over each item
1668 foreach ($grade_items as $item) {
1669 // Instantiate a grade_item object, to access its methods
1670 $grade_item = new grade_item($item, false);
1672 // do not restore if this grade_item is a mod, and
1673 if ($grade_item->itemtype == 'mod') {
1674 //MDL-12463 - exclude grade_items of instances not chosen for backup
1675 if (empty($preferences->mods[$grade_item->itemmodule]->instances[$grade_item->iteminstance]->backup)) {
1676 continue;
1679 } else if ($grade_item->itemtype == 'category') {
1680 // if not all grade items are being backed up
1681 // we ignore this type of grade_item and grades associated
1682 if (!$backupall) {
1683 continue;
1687 //Begin grade_item
1688 fwrite ($bf,start_tag("GRADE_ITEM",4,true));
1689 //Output individual fields
1691 fwrite ($bf,full_tag("ID",5,false,$grade_item->id));
1692 fwrite ($bf,full_tag("CATEGORYID",5,false,$grade_item->categoryid));
1693 fwrite ($bf,full_tag("ITEMNAME",5,false,$grade_item->itemname));
1694 fwrite ($bf,full_tag("ITEMTYPE",5,false,$grade_item->itemtype));
1695 fwrite ($bf,full_tag("ITEMMODULE",5,false,$grade_item->itemmodule));
1696 fwrite ($bf,full_tag("ITEMINSTANCE",5,false,$grade_item->iteminstance));
1697 fwrite ($bf,full_tag("ITEMNUMBER",5,false,$grade_item->itemnumber));
1698 fwrite ($bf,full_tag("ITEMINFO",5,false,$grade_item->iteminfo));
1699 fwrite ($bf,full_tag("IDNUMBER",5,false,$grade_item->idnumber));
1700 // use [idnumber] in calculation instead of [#giXXX#]
1701 fwrite ($bf,full_tag("CALCULATION",5,false,$grade_item->get_calculation()));
1702 fwrite ($bf,full_tag("GRADETYPE",5,false,$grade_item->gradetype));
1703 fwrite ($bf,full_tag("GRADEMAX",5,false,$grade_item->grademax));
1704 fwrite ($bf,full_tag("GRADEMIN",5,false,$grade_item->grademin));
1705 fwrite ($bf,full_tag("SCALEID",5,false,$grade_item->scaleid));
1706 fwrite ($bf,full_tag("OUTCOMEID",5,false,$grade_item->outcomeid));
1707 fwrite ($bf,full_tag("GRADEPASS",5,false,$grade_item->gradepass));
1708 fwrite ($bf,full_tag("MULTFACTOR",5,false,$grade_item->multfactor));
1709 fwrite ($bf,full_tag("PLUSFACTOR",5,false,$grade_item->plusfactor));
1710 fwrite ($bf,full_tag("AGGREGATIONCOEF",5,false,$grade_item->aggregationcoef));
1711 fwrite ($bf,full_tag("DISPLAY",5,false,$grade_item->display));
1712 fwrite ($bf,full_tag("DECIMALS",5,false,$grade_item->decimals));
1713 fwrite ($bf,full_tag("HIDDEN",5,false,$grade_item->hidden));
1714 fwrite ($bf,full_tag("LOCKED",5,false,$grade_item->locked));
1715 fwrite ($bf,full_tag("LOCKTIME",5,false,$grade_item->locktime));
1716 fwrite ($bf,full_tag("NEEDSUPDATE",5,false,$grade_item->needsupdate));
1717 fwrite ($bf,full_tag("TIMECREATED",5,false,$grade_item->timecreated));
1718 fwrite ($bf,full_tag("TIMEMODIFIED",5,false,$grade_item->timemodified));
1720 // back up the other stuff here
1721 // mod grades should only be backed up if selected
1722 if ($grade_item->itemtype == 'mod' && !backup_userdata_selected($preferences,$grade_item->itemmodule,$grade_item->iteminstance)) {
1723 // do not write grades if a mod grade_item is being restored
1724 // but userdata is not selected
1725 } else {
1726 $status = backup_gradebook_grades_info($bf,$preferences,$grade_item->id);
1728 //End grade_item
1729 fwrite ($bf,end_tag("GRADE_ITEM",4,true));
1731 //End grade_items tag
1732 $status = fwrite ($bf,end_tag("GRADE_ITEMS",3,true));
1735 return $status;
1737 //Backup gradebook_item (called from backup_gradebook_info
1739 function backup_gradebook_grade_letters_info($bf, $preferences) {
1740 global $CFG;
1741 $status = true;
1743 $context = get_context_instance(CONTEXT_COURSE, $preferences->backup_course);
1744 $grade_letters = get_records_sql("SELECT *
1745 FROM {$CFG->prefix}grade_letters
1746 WHERE contextid = $context->id");
1747 if ($grade_letters) {
1748 //Begin grade_l tag
1749 fwrite ($bf,start_tag("GRADE_LETTERS",3,true));
1750 //Iterate for each letter
1751 foreach ($grade_letters as $grade_letter) {
1752 //Begin grade_letter
1753 fwrite ($bf,start_tag("GRADE_LETTER",4,true));
1754 //Output individual fields
1755 fwrite ($bf,full_tag("ID",5,false,$grade_letter->id));
1756 fwrite ($bf,full_tag("LOWERBOUNDARY",5,false,$grade_letter->lowerboundary));
1757 fwrite ($bf,full_tag("LETTER",5,false,$grade_letter->letter));
1759 //End grade_letter
1760 fwrite ($bf,end_tag("GRADE_LETTER",4,true));
1762 //End grade_categories tag
1763 $status = fwrite ($bf,end_tag("GRADE_LETTERS",3,true));
1766 return $status;
1769 function backup_gradebook_outcomes_info($bf, $preferences) {
1771 global $CFG;
1772 $status = true;
1773 // only back up courses already in the grade_outcomes_courses table
1774 $grade_outcomes = get_records_sql("SELECT go.*
1775 FROM {$CFG->prefix}grade_outcomes go
1776 JOIN {$CFG->prefix}grade_outcomes_courses goc
1777 ON (goc.outcomeid = go.id)
1778 WHERE goc.courseid = $preferences->backup_course");
1780 if (!empty($grade_outcomes)) {
1781 //Begin grade_outcomes tag
1782 fwrite ($bf,start_tag("GRADE_OUTCOMES",3,true));
1783 //Iterate for each outcome
1784 foreach ($grade_outcomes as $grade_outcome) {
1785 //Begin grade_outcome
1786 fwrite ($bf,start_tag("GRADE_OUTCOME",4,true));
1787 //Output individual fields
1789 fwrite ($bf,full_tag("ID",5,false,$grade_outcome->id));
1790 fwrite ($bf,full_tag("COURSEID",5,false,$grade_outcome->courseid));
1791 fwrite ($bf,full_tag("SHORTNAME",5,false,$grade_outcome->shortname));
1792 fwrite ($bf,full_tag("FULLNAME",5,false,$grade_outcome->fullname));
1793 fwrite ($bf,full_tag("SCALEID",5,false,$grade_outcome->scaleid));
1794 fwrite ($bf,full_tag("DESCRIPTION",5,false,$grade_outcome->description));
1795 fwrite ($bf,full_tag("TIMECREATED",5,false,$grade_outcome->timecreated));
1796 fwrite ($bf,full_tag("TIMEMODIFIED",5,false,$grade_outcome->timemodified));
1797 fwrite ($bf,full_tag("USERMODIFIED",5,false,$grade_outcome->usermodified));
1799 //End grade_outcome
1800 fwrite ($bf,end_tag("GRADE_OUTCOME",4,true));
1802 //End grade_outcomes tag
1803 $status = fwrite ($bf,end_tag("GRADE_OUTCOMES",3,true));
1805 return $status;
1808 function backup_gradebook_grades_info($bf,$preferences, $itemid) {
1810 global $CFG;
1812 $status = true;
1814 // find all grades belonging to this item
1815 if ($grades = get_records('grade_grades', 'itemid', $itemid)) {
1816 fwrite ($bf,start_tag("GRADE_GRADES",5,true));
1817 foreach ($grades as $grade) {
1818 /// Grades are only sent to backup if the user is one target user
1819 if (backup_getid($preferences->backup_unique_code, 'user', $grade->userid)) {
1820 fwrite ($bf,start_tag("GRADE",6,true));
1821 fwrite ($bf,full_tag("ID",7,false,$grade->id));
1822 fwrite ($bf,full_tag("USERID",7,false,$grade->userid));
1823 fwrite ($bf,full_tag("RAWGRADE",7,false,$grade->rawgrade));
1824 fwrite ($bf,full_tag("RAWGRADEMAX",7,false,$grade->rawgrademax));
1825 fwrite ($bf,full_tag("RAWGRADEMIN",7,false,$grade->rawgrademin));
1826 fwrite ($bf,full_tag("RAWSCALEID",7,false,$grade->rawscaleid));
1827 fwrite ($bf,full_tag("USERMODIFIED",7,false,$grade->usermodified));
1828 fwrite ($bf,full_tag("FINALGRADE",7,false,$grade->finalgrade));
1829 fwrite ($bf,full_tag("HIDDEN",7,false,$grade->hidden));
1830 fwrite ($bf,full_tag("LOCKED",7,false,$grade->locked));
1831 fwrite ($bf,full_tag("LOCKTIME",7,false,$grade->locktime));
1832 fwrite ($bf,full_tag("EXPORTED",7,false,$grade->exported));
1833 fwrite ($bf,full_tag("OVERRIDDEN",7,false,$grade->overridden));
1834 fwrite ($bf,full_tag("EXCLUDED",7,false,$grade->excluded));
1835 fwrite ($bf,full_tag("FEEDBACK",7,false,$grade->feedback));
1836 fwrite ($bf,full_tag("FEEDBACKFORMAT",7,false,$grade->feedbackformat));
1837 fwrite ($bf,full_tag("INFORMATION",7,false,$grade->information));
1838 fwrite ($bf,full_tag("INFORMATIONFORMAT",7,false,$grade->informationformat));
1839 fwrite ($bf,full_tag("TIMECREATED",7,false,$grade->timecreated));
1840 fwrite ($bf,full_tag("TIMEMODIFIED",7,false,$grade->timemodified));
1841 fwrite ($bf,end_tag("GRADE",6,true));
1844 $status = fwrite ($bf,end_tag("GRADE_GRADES",5,true));
1846 return $status;
1849 function backup_gradebook_categories_history_info($bf, $preferences) {
1851 global $CFG;
1852 $status = true;
1854 // find all grade categories history
1855 if ($chs = get_records('grade_categories_history', 'courseid', $preferences->backup_course)) {
1856 fwrite ($bf,start_tag("GRADE_CATEGORIES_HISTORIES",5,true));
1857 foreach ($chs as $ch) {
1858 fwrite ($bf,start_tag("GRADE_CATEGORIES_HISTORY",6,true));
1859 fwrite ($bf,full_tag("ID",7,false,$ch->id));
1860 fwrite ($bf,full_tag("ACTION",7,false,$ch->action));
1861 fwrite ($bf,full_tag("OLDID",7,false,$ch->oldid));
1862 fwrite ($bf,full_tag("SOURCE",7,false,$ch->source));
1863 fwrite ($bf,full_tag("TIMEMODIFIED",7,false,$ch->timemodified));
1864 fwrite ($bf,full_tag("LOGGEDUSER",7,false,$ch->loggeduser));
1865 fwrite ($bf,full_tag("PARENT",7,false,$ch->parent));
1866 fwrite ($bf,full_tag("DEPTH",7,false,$ch->depth));
1867 fwrite ($bf,full_tag("PATH",7,false,$ch->path));
1868 fwrite ($bf,full_tag("FULLNAME",7,false,$ch->fullname));
1869 fwrite ($bf,full_tag("AGGRETGATION",7,false,$ch->aggregation));
1870 fwrite ($bf,full_tag("KEEPHIGH",7,false,$ch->keephigh));
1871 fwrite ($bf,full_tag("DROPLOW",7,false,$ch->droplow));
1872 fwrite ($bf,full_tag("AGGREGATEONLYGRADED",7,false,$ch->aggregateonlygraded));
1873 fwrite ($bf,full_tag("AGGREGATEOUTCOMES",7,false,$ch->aggregateoutcomes));
1874 fwrite ($bf,full_tag("AGGREGATESUBCATS",7,false,$ch->aggregatesubcats));
1875 fwrite ($bf,end_tag("GRADE_CATEGORIES_HISTORY",6,true));
1877 $status = fwrite ($bf,end_tag("GRADE_CATEGORIES_HISTORIES",5,true));
1879 return $status;
1882 function backup_gradebook_grades_history_info($bf, $preferences) {
1884 global $CFG;
1885 $status = true;
1887 // find all grade categories history
1888 if ($chs = get_records_sql("SELECT ggh.*
1889 FROM {$CFG->prefix}grade_grades_history ggh
1890 JOIN {$CFG->prefix}grade_items gi
1891 ON gi.id = ggh.itemid
1892 WHERE gi.courseid = $preferences->backup_course")) {
1893 fwrite ($bf,start_tag("GRADE_GRADES_HISTORIES",5,true));
1894 foreach ($chs as $ch) {
1895 /// Grades are only sent to backup if the user is one target user
1896 if (backup_getid($preferences->backup_unique_code, 'user', $ch->userid)) {
1897 fwrite ($bf,start_tag("GRADE_GRADES_HISTORY",6,true));
1898 fwrite ($bf,full_tag("ID",7,false,$ch->id));
1899 fwrite ($bf,full_tag("ACTION",7,false,$ch->action));
1900 fwrite ($bf,full_tag("OLDID",7,false,$ch->oldid));
1901 fwrite ($bf,full_tag("SOURCE",7,false,$ch->source));
1902 fwrite ($bf,full_tag("TIMEMODIFIED",7,false,$ch->timemodified));
1903 fwrite ($bf,full_tag("LOGGEDUSER",7,false,$ch->loggeduser));
1904 fwrite ($bf,full_tag("ITEMID",7,false,$ch->itemid));
1905 fwrite ($bf,full_tag("USERID",7,false,$ch->userid));
1906 fwrite ($bf,full_tag("RAWGRADE",7,false,$ch->rawgrade));
1907 fwrite ($bf,full_tag("RAWGRADEMAX",7,false,$ch->rawgrademax));
1908 fwrite ($bf,full_tag("RAWGRADEMIN",7,false,$ch->rawgrademin));
1909 fwrite ($bf,full_tag("RAWSCALEID",7,false,$ch->rawscaleid));
1910 fwrite ($bf,full_tag("USERMODIFIED",7,false,$ch->usermodified));
1911 fwrite ($bf,full_tag("FINALGRADE",7,false,$ch->finalgrade));
1912 fwrite ($bf,full_tag("HIDDEN",7,false,$ch->hidden));
1913 fwrite ($bf,full_tag("LOCKED",7,false,$ch->locked));
1914 fwrite ($bf,full_tag("LOCKTIME",7,false,$ch->locktime));
1915 fwrite ($bf,full_tag("EXPORTED",7,false,$ch->exported));
1916 fwrite ($bf,full_tag("OVERRIDDEN",7,false,$ch->overridden));
1917 fwrite ($bf,full_tag("EXCLUDED",7,false,$ch->excluded));
1918 fwrite ($bf,full_tag("FEEDBACK",7,false,$ch->feedback));
1919 fwrite ($bf,full_tag("FEEDBACKFORMAT",7,false,$ch->feedbackformat));
1920 fwrite ($bf,full_tag("INFORMATION",7,false,$ch->information));
1921 fwrite ($bf,full_tag("INFORMATIONFORMAT",7,false,$ch->informationformat));
1922 fwrite ($bf,end_tag("GRADE_GRADES_HISTORY",6,true));
1925 $status = fwrite ($bf,end_tag("GRADE_GRADES_HISTORIES",5,true));
1927 return $status;
1930 function backup_gradebook_items_history_info($bf, $preferences) {
1932 global $CFG;
1933 $status = true;
1935 // find all grade categories history
1936 if ($chs = get_records('grade_items_history','courseid', $preferences->backup_course)) {
1937 fwrite ($bf,start_tag("GRADE_ITEM_HISTORIES",5,true));
1938 foreach ($chs as $ch) {
1939 fwrite ($bf,start_tag("GRADE_ITEM_HISTORY",6,true));
1940 fwrite ($bf,full_tag("ID",7,false,$ch->id));
1941 fwrite ($bf,full_tag("ACTION",7,false,$ch->action));
1942 fwrite ($bf,full_tag("OLDID",7,false,$ch->oldid));
1943 fwrite ($bf,full_tag("SOURCE",7,false,$ch->source));
1944 fwrite ($bf,full_tag("TIMEMODIFIED",7,false,$ch->timemodified));
1945 fwrite ($bf,full_tag("LOGGEDUSER",7,false,$ch->loggeduser));
1946 fwrite ($bf,full_tag("CATEGORYID",7,false,$ch->categoryid));
1947 fwrite ($bf,full_tag("ITEMNAME",7,false,$ch->itemname));
1948 fwrite ($bf,full_tag("ITEMTYPE",7,false,$ch->itemtype));
1949 fwrite ($bf,full_tag("ITEMMODULE",7,false,$ch->itemmodule));
1950 fwrite ($bf,full_tag("ITEMINSTANCE",7,false,$ch->iteminstance));
1951 fwrite ($bf,full_tag("ITEMNUMBER",7,false,$ch->itemnumber));
1952 fwrite ($bf,full_tag("ITEMINFO",7,false,$ch->iteminfo));
1953 fwrite ($bf,full_tag("IDNUMBER",7,false,$ch->idnumber));
1954 fwrite ($bf,full_tag("CALCULATION",7,false,$ch->calculation));
1955 fwrite ($bf,full_tag("GRADETYPE",7,false,$ch->gradetype));
1956 fwrite ($bf,full_tag("GRADEMAX",7,false,$ch->grademax));
1957 fwrite ($bf,full_tag("GRADEMIN",7,false,$ch->grademin));
1958 fwrite ($bf,full_tag("SCALEID",7,false,$ch->scaleid));
1959 fwrite ($bf,full_tag("OUTCOMEID",7,false,$ch->outcomeid));
1960 fwrite ($bf,full_tag("GRADEPASS",7,false,$ch->gradepass));
1961 fwrite ($bf,full_tag("MULTFACTOR",7,false,$ch->multfactor));
1962 fwrite ($bf,full_tag("PLUSFACTOR",7,false,$ch->plusfactor));
1963 fwrite ($bf,full_tag("AGGREGATIONCOEF",7,false,$ch->aggregationcoef));
1964 fwrite ($bf,full_tag("SORTORDER",7,false,$ch->sortorder));
1965 //fwrite ($bf,full_tag("DISPLAY",7,false,$ch->display));
1966 //fwrite ($bf,full_tag("DECIMALS",7,false,$ch->decimals));
1967 fwrite ($bf,full_tag("HIDDEN",7,false,$ch->hidden));
1968 fwrite ($bf,full_tag("LOCKED",7,false,$ch->locked));
1969 fwrite ($bf,full_tag("LOCKTIME",7,false,$ch->locktime));
1970 fwrite ($bf,full_tag("NEEDSUPDATE",7,false,$ch->needsupdate));
1971 fwrite ($bf,end_tag("GRADE_ITEM_HISTORY",6,true));
1973 $status = fwrite ($bf,end_tag("GRADE_ITEM_HISTORIES",5,true));
1976 return $status;
1979 function backup_gradebook_outcomes_history($bf, $preferences) {
1980 global $CFG;
1981 $status = true;
1983 // find all grade categories history
1984 if ($chs = get_records('grade_outcomes_history','courseid', $preferences->backup_course)) {
1985 fwrite ($bf,start_tag("GRADE_OUTCOME_HISTORIES",5,true));
1986 foreach ($chs as $ch) {
1987 fwrite ($bf,start_tag("GRADE_OUTCOME_HISTORY",6,true));
1988 fwrite ($bf,full_tag("ID",7,false,$ch->id));
1989 fwrite ($bf,full_tag("OLDID",7,false,$ch->oldid));
1990 fwrite ($bf,full_tag("ACTION",7,false,$ch->action));
1991 fwrite ($bf,full_tag("SOURCE",7,false,$ch->source));
1992 fwrite ($bf,full_tag("TIMEMODIFIED",7,false,$ch->timemodified));
1993 fwrite ($bf,full_tag("LOGGEDUSER",7,false,$ch->loggeduser));
1994 fwrite ($bf,full_tag("SHORTNAME",7,false,$ch->shortname));
1995 fwrite ($bf,full_tag("FULLNAME",7,false,$ch->fullname));
1996 fwrite ($bf,full_tag("SCALEID",7,false,$ch->scaleid));
1997 fwrite ($bf,full_tag("DESCRIPTION",7,false,$ch->description));
1998 fwrite ($bf,end_tag("GRADE_OUTCOME_HISTORY",6,true));
2000 $status = fwrite ($bf,end_tag("GRADE_OUTCOME_HISTORIES",5,true));
2002 return $status;
2005 //Backup scales info (common and course scales)
2006 function backup_scales_info($bf,$preferences) {
2008 global $CFG;
2010 $status = true;
2012 //Counter, points to current record
2013 $counter = 0;
2015 //Get scales (common and course scales)
2016 $scales = get_records_sql("SELECT id, courseid, userid, name, scale, description, timemodified
2017 FROM {$CFG->prefix}scale
2018 WHERE courseid = 0 OR courseid = $preferences->backup_course");
2020 //Copy only used scales to $backupscales. They will be in backup (unused no). See Bug 1223.
2021 $backupscales = array();
2022 if ($scales) {
2023 foreach ($scales as $scale) {
2024 if (course_scale_used($preferences->backup_course, $scale->id)) {
2025 $backupscales[] = $scale;
2030 //Pring scales header
2031 if ($backupscales) {
2032 //Pring scales header
2033 fwrite ($bf,start_tag("SCALES",2,true));
2034 //Iterate
2035 foreach ($backupscales as $scale) {
2036 //Begin scale tag
2037 fwrite ($bf,start_tag("SCALE",3,true));
2038 //Output scale tag
2039 fwrite ($bf,full_tag("ID",4,false,$scale->id));
2040 fwrite ($bf,full_tag("COURSEID",4,false,$scale->courseid));
2041 fwrite ($bf,full_tag("USERID",4,false,$scale->userid));
2042 fwrite ($bf,full_tag("NAME",4,false,$scale->name));
2043 fwrite ($bf,full_tag("SCALETEXT",4,false,$scale->scale));
2044 fwrite ($bf,full_tag("DESCRIPTION",4,false,$scale->description));
2045 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$scale->timemodified));
2046 //End scale tag
2047 fwrite ($bf,end_tag("SCALE",3,true));
2049 //End scales tag
2050 $status = fwrite ($bf,end_tag("SCALES",2,true));
2052 return $status;
2055 //Backup events info (course events)
2056 function backup_events_info($bf,$preferences) {
2058 global $CFG;
2060 $status = true;
2062 //Counter, points to current record
2063 $counter = 0;
2065 //Get events (course events)
2066 $events = get_records_select("event","courseid='$preferences->backup_course' AND instance='0'","id");
2068 //Pring events header
2069 if ($events) {
2070 //Pring events header
2071 fwrite ($bf,start_tag("EVENTS",2,true));
2072 //Iterate
2073 foreach ($events as $event) {
2074 //Begin event tag
2075 fwrite ($bf,start_tag("EVENT",3,true));
2076 //Output event tag
2077 fwrite ($bf,full_tag("ID",4,false,$event->id));
2078 fwrite ($bf,full_tag("NAME",4,false,$event->name));
2079 fwrite ($bf,full_tag("DESCRIPTION",4,false,$event->description));
2080 fwrite ($bf,full_tag("FORMAT",4,false,$event->format));
2081 fwrite ($bf,full_tag("GROUPID",4,false,$event->groupid));
2082 fwrite ($bf,full_tag("USERID",4,false,$event->userid));
2083 fwrite ($bf,full_tag("REPEATID",4,false,$event->repeatid));
2084 fwrite ($bf,full_tag("EVENTTYPE",4,false,$event->eventtype));
2085 fwrite ($bf,full_tag("MODULENAME",4,false,$event->modulename));
2086 fwrite ($bf,full_tag("TIMESTART",4,false,$event->timestart));
2087 fwrite ($bf,full_tag("TIMEDURATION",4,false,$event->timeduration));
2088 fwrite ($bf,full_tag("VISIBLE",4,false,$event->visible));
2089 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$event->timemodified));
2090 //End event tag
2091 fwrite ($bf,end_tag("EVENT",3,true));
2093 //End events tag
2094 $status = fwrite ($bf,end_tag("EVENTS",2,true));
2096 return $status;
2099 //Backup groups info
2100 function backup_groups_info($bf,$preferences) {
2102 global $CFG;
2104 $status = true;
2105 $status2 = true;
2107 //Get groups
2108 $groups = get_records("groups","courseid",$preferences->backup_course);
2110 //Pring groups header
2111 if ($groups) {
2112 //Pring groups header
2113 fwrite ($bf,start_tag("GROUPS",2,true));
2114 //Iterate
2115 foreach ($groups as $group) {
2116 //Begin group tag
2117 fwrite ($bf,start_tag("GROUP",3,true));
2118 //Output group contents
2119 fwrite ($bf,full_tag("ID",4,false,$group->id));
2120 //fwrite ($bf,full_tag("COURSEID",4,false,$group->courseid));
2121 fwrite ($bf,full_tag("NAME",4,false,$group->name));
2122 fwrite ($bf,full_tag("DESCRIPTION",4,false,$group->description));
2123 fwrite ($bf,full_tag("ENROLMENTKEY",4,false,$group->enrolmentkey));
2124 fwrite ($bf,full_tag("PICTURE",4,false,$group->picture));
2125 fwrite ($bf,full_tag("HIDEPICTURE",4,false,$group->hidepicture));
2126 fwrite ($bf,full_tag("TIMECREATED",4,false,$group->timecreated));
2127 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$group->timemodified));
2129 //Now, backup groups_members, only if users are included
2130 if ($preferences->backup_users != 2) {
2131 $status2 = backup_groups_members_info($bf,$preferences,$group->id);
2134 //End group tag
2135 fwrite ($bf,end_tag("GROUP",3,true));
2137 //End groups tag
2138 $status = fwrite ($bf,end_tag("GROUPS",2,true));
2140 //Now save group_files
2141 if ($status && $status2) {
2142 $status2 = backup_copy_group_files($preferences);
2145 return ($status && $status2);
2148 //Backup groups_members info
2149 function backup_groups_members_info($bf,$preferences,$groupid) {
2151 global $CFG;
2153 $status = true;
2155 //Get groups_members that are being included in backup
2156 $groups_members = get_records_sql("SELECT gm.*
2157 FROM {$CFG->prefix}groups_members gm,
2158 {$CFG->prefix}backup_ids bi
2159 WHERE gm.groupid = $groupid
2160 AND bi.backup_code = $preferences->backup_unique_code
2161 AND bi.table_name = 'user'");
2163 //Pring groups_members header
2164 if ($groups_members) {
2165 //Pring groups_members header
2166 fwrite ($bf,start_tag("MEMBERS",4,true));
2167 //Iterate
2168 foreach ($groups_members as $group_member) {
2169 //Begin group_member tag
2170 fwrite ($bf,start_tag("MEMBER",5,true));
2171 //Output group_member contents
2172 fwrite ($bf,full_tag("GROUPID",6,false,$group_member->groupid));
2173 fwrite ($bf,full_tag("USERID",6,false,$group_member->userid));
2174 fwrite ($bf,full_tag("TIMEADDED",6,false,$group_member->timeadded));
2175 //End group_member tag
2176 fwrite ($bf,end_tag("MEMBER",5,true));
2178 //End groups_members tag
2179 $status = fwrite ($bf,end_tag("MEMBERS",4,true));
2181 return $status;
2184 //Backup groupings info
2185 function backup_groupings_info($bf,$preferences) {
2187 global $CFG;
2189 $status = true;
2191 //Get groups
2192 $groupings = get_records("groupings","courseid",$preferences->backup_course);
2194 //Pring groups header
2195 if ($groupings) {
2196 //Pring groups header
2197 fwrite ($bf,start_tag("GROUPINGS",2,true));
2198 //Iterate
2199 foreach ($groupings as $grouping) {
2200 //Begin group tag
2201 fwrite ($bf,start_tag("GROUPING",3,true));
2202 //Output group contents
2203 fwrite ($bf,full_tag("ID",4,false,$grouping->id));
2204 //fwrite ($bf,full_tag("COURSEID",4,false,$grouping->courseid));
2205 fwrite ($bf,full_tag("NAME",4,false,$grouping->name));
2206 fwrite ($bf,full_tag("DESCRIPTION",4,false,$grouping->description));
2207 fwrite ($bf,full_tag("CONFIGDATA",4,false,$grouping->configdata));
2208 fwrite ($bf,full_tag("TIMECREATED",4,false,$grouping->timecreated));
2209 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$grouping->timemodified));
2211 //End group tag
2212 fwrite ($bf,end_tag("GROUPING",3,true));
2214 //End groups tag
2215 $status = fwrite ($bf,end_tag("GROUPINGS",2,true));
2217 //(Now save grouping_files)
2219 return $status;
2222 //Backup groupings-groups info
2223 function backup_groupings_groups_info($bf,$preferences) {
2225 global $CFG;
2227 $status = true;
2229 //Get grouping_groups
2230 $courseid = $preferences->backup_course;
2231 $sql = "SELECT gg.* FROM {$CFG->prefix}groupings g, {$CFG->prefix}groupings_groups gg
2232 WHERE g.courseid=$courseid AND g.id=gg.groupingid";
2233 $grouping_groups = get_records_sql($sql);
2235 //Pring grouping_groups header
2236 if ($grouping_groups) {
2237 //Pring grouping_groups header
2238 fwrite ($bf,start_tag("GROUPINGSGROUPS",2,true));
2239 //Iterate
2240 foreach ($grouping_groups as $members) {
2241 //Begin grouping_group tag
2242 fwrite ($bf,start_tag("GROUPINGGROUP",3,true));
2243 //Output group_member contents
2244 fwrite ($bf,full_tag("ID",4,false,$members->id));
2245 fwrite ($bf,full_tag("GROUPINGID",4,false,$members->groupingid));
2246 fwrite ($bf,full_tag("GROUPID",4,false,$members->groupid));
2247 fwrite ($bf,full_tag("TIMEADDED",4,false,$members->timeadded));
2248 //End grouping_group tag
2249 fwrite ($bf,end_tag("GROUPINGGROUP",3,true));
2251 //End grouping_groups tag
2252 $status = fwrite ($bf,end_tag("GROUPINGSGROUPS",2,true));
2254 return $status;
2257 //Start the modules tag
2258 function backup_modules_start ($bf,$preferences) {
2260 return fwrite ($bf,start_tag("MODULES",2,true));
2263 //End the modules tag
2264 function backup_modules_end ($bf,$preferences) {
2266 return fwrite ($bf,end_tag("MODULES",2,true));
2269 //This function makes all the necesary calls to every mod
2270 //to export itself and its files !!!
2271 function backup_module($bf,$preferences,$module) {
2273 global $CFG;
2275 $status = true;
2277 require_once($CFG->dirroot.'/mod/'.$module.'/backuplib.php');
2279 if (isset($preferences->mods[$module]->instances)
2280 && is_array($preferences->mods[$module]->instances)) {
2281 $onemodbackup = $module.'_backup_one_mod';
2282 if (function_exists($onemodbackup)) {
2283 foreach ($preferences->mods[$module]->instances as $instance => $object) {
2284 if (!empty($object->backup)) {
2285 $statusm = $onemodbackup($bf,$preferences,$instance);
2286 if (!$statusm) {
2287 if (!defined('BACKUP_SILENTLY')) {
2288 notify('backup of '.$module.'-'.$object->name.' failed.');
2290 $status = false;
2294 } else {
2295 $status = false;
2297 } else { // whole module.
2298 //First, re-check if necessary functions exists
2299 $modbackup = $module."_backup_mods";
2300 if (function_exists($modbackup)) {
2301 //Call the function
2302 $status = $modbackup($bf,$preferences);
2303 } else {
2304 //Something was wrong. Function should exist.
2305 $status = false;
2309 return $status;
2313 //This function encode things to make backup multi-site fully functional
2314 //It does this conversions:
2315 // - $CFG->wwwroot/file.php/courseid ------------------> $@FILEPHP@$ (slasharguments links)
2316 // - $CFG->wwwroot/file.php?file=/courseid ------------> $@FILEPHP@$ (non-slasharguments links)
2317 // - Every module xxxx_encode_content_links() is executed too
2319 function backup_encode_absolute_links($content) {
2321 global $CFG,$preferences;
2323 /// MDL-14072: Prevent NULLs, empties and numbers to be processed by the
2324 /// heavy interlinking. Just a few cpu cycles saved.
2325 if ($content === NULL) {
2326 return NULL;
2327 } else if ($content === '') {
2328 return '';
2329 } else if (is_numeric($content)) {
2330 return $content;
2333 //Use one static variable to cache all the require_once calls that,
2334 //under PHP5 seems to increase load too much, and we are requiring
2335 //them here thousands of times (one per content). MDL-8700.
2336 //Once fixed by PHP, we'll delete this hack
2338 static $includedfiles;
2339 if (!isset($includedfiles)) {
2340 $includedfiles = array();
2343 //Check if preferences is ok. If it isn't set, we are
2344 //in a scheduled_backup to we are able to get a copy
2345 //from CFG->backup_preferences
2346 if (!isset($preferences)) {
2347 $mypreferences = $CFG->backup_preferences;
2348 } else {
2349 //We are in manual backups so global preferences must exist!!
2350 $mypreferences = $preferences;
2353 //First, we check for every call to file.php inside the course
2354 $search = array($CFG->wwwroot.'/file.php/'.$mypreferences->backup_course,
2355 $CFG->wwwroot.'/file.php?file=/'.$mypreferences->backup_course);
2357 $replace = array('$@FILEPHP@$','$@FILEPHP@$');
2359 $result = str_replace($search,$replace,$content);
2361 foreach ($mypreferences->mods as $name => $info) {
2362 /// We only include the corresponding backuplib.php if it hasn't been included before
2363 /// This will save some load under PHP5. MDL-8700.
2364 /// Once fixed by PHP, we'll delete this hack
2365 if (!in_array($name, $includedfiles)) {
2366 include_once("$CFG->dirroot/mod/$name/backuplib.php");
2367 $includedfiles[] = $name;
2369 //Check if the xxxx_encode_content_links exists
2370 $function_name = $name."_encode_content_links";
2371 if (function_exists($function_name)) {
2372 $result = $function_name($result,$mypreferences);
2376 // For each block, call its encode_content_links method.
2377 // This encodes forexample links to blocks/something/viewphp?id=666
2378 // that are stored in other activities.
2379 static $blockobjects = null;
2380 if (!isset($blockobjects)) {
2381 $blockobjects = array();
2382 if ($blocks = get_records('block', 'visible', 1)) {
2383 foreach ($blocks as $block) {
2384 if ($blockobject = block_instance($block->name)) {
2385 $blockobjects[] = $blockobject;
2391 foreach ($blockobjects as $blockobject) {
2392 $result = $blockobject->encode_content_links($result,$mypreferences);
2395 if ($result != $content) {
2396 debugging('<br /><hr />'.s($content).'<br />changed to<br />'.s($result).'<hr /><br />');
2399 return $result;
2402 //This function copies all the needed files under the "users" directory to the "user_files"
2403 //directory under temp/backup
2404 function backup_copy_user_files ($preferences) {
2406 global $CFG;
2408 $status = true;
2410 //First we check to "user_files" exists and create it as necessary
2411 //in temp/backup/$backup_code dir
2412 $status = check_and_create_user_files_dir($preferences->backup_unique_code);
2414 //Now iterate over directories under "user" to check if that user must be copied to backup
2416 // Method to get a list of userid=>array(basedir => $basedir, userfolder => $userfolder)
2417 $userlist = get_user_directories();
2419 foreach ($userlist as $userid => $userinfo) {
2420 //Look for dir like username in backup_ids
2421 $data = count_records("backup_ids","backup_code",$preferences->backup_unique_code, "table_name","user", "old_id",$userid);
2423 //If exists, copy it
2424 if ($data) {
2425 $parts = explode('/', $userinfo['userfolder']);
2426 $status = true;
2428 if (is_array($parts)) {
2429 $group = $parts[0];
2430 $userid = $parts[1];
2432 // Create group dir first
2433 $status = check_dir_exists("$CFG->dataroot/temp/backup/$preferences->backup_unique_code/user_files/". $group, true);
2436 $status = $status && backup_copy_file($userinfo['basedir'] . '/' . $userinfo['userfolder'],
2437 "$CFG->dataroot/temp/backup/$preferences->backup_unique_code/user_files/{$userinfo['userfolder']}");
2441 return $status;
2444 //This function copies all the needed files under the "groups" directory to the "group_files"
2445 //directory under temp/backup
2446 function backup_copy_group_files ($preferences) {
2448 global $CFG;
2450 $status = true;
2452 //First we check if "group_files" exists and create it as necessary
2453 //in temp/backup/$backup_code dir
2454 $status = check_and_create_group_files_dir($preferences->backup_unique_code);
2456 //Now iterate over directories under "groups" to check if that user must be
2457 //copied to backup
2459 $rootdir = $CFG->dataroot.'/groups';
2460 //Check if directory exists
2461 if (is_dir($rootdir)) {
2462 $list = list_directories ($rootdir);
2463 if ($list) {
2464 //Iterate
2465 foreach ($list as $dir) {
2466 //Look for dir like group in groups table
2467 $data = get_record ('groups', 'courseid', $preferences->backup_course,
2468 'id',$dir);
2469 //If exists, copy it
2470 if ($data) {
2471 $status = backup_copy_file($rootdir."/".$dir,
2472 $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/group_files/".$dir);
2477 return $status;
2480 //This function copies all the course files under the course directory (except the moddata
2481 //directory to the "course_files" directory under temp/backup
2482 function backup_copy_course_files ($preferences) {
2484 global $CFG;
2486 $status = true;
2488 //First we check to "course_files" exists and create it as necessary
2489 //in temp/backup/$backup_code dir
2490 $status = check_and_create_course_files_dir($preferences->backup_unique_code);
2492 //Now iterate over files and directories except $CFG->moddata and backupdata to be
2493 //copied to backup
2495 $rootdir = $CFG->dataroot."/".$preferences->backup_course;
2497 $name_moddata = $CFG->moddata;
2498 $name_backupdata = "backupdata";
2499 //Check if directory exists
2500 if (is_dir($rootdir)) {
2501 $list = list_directories_and_files ($rootdir);
2502 if ($list) {
2503 //Iterate
2504 foreach ($list as $dir) {
2505 if ($dir !== $name_moddata and $dir !== $name_backupdata) {
2506 $status = backup_copy_file($rootdir."/".$dir,
2507 $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/course_files/".$dir);
2512 return $status;
2515 * This function copies all the site files under the site directory (except the moddata and backupdata
2516 * directories to the "site_files" directory under temp/backup
2518 function backup_copy_site_files ($preferences) {
2520 global $CFG;
2522 $status = true;
2524 if ($preferences->backup_course == SITEID){
2525 return $status;
2528 //First we check to "site_files" exists and create it as necessary
2529 //in temp/backup/$backup_code dir
2530 $status = $status && check_and_create_site_files_dir($preferences->backup_unique_code);
2532 $rootdir = $CFG->dataroot."/".SITEID;
2536 $files = get_records_select('backup_files',
2537 "backup_code = '$preferences->backup_unique_code' AND file_type = 'site'");
2538 if ($files) {
2539 //Iterate
2540 foreach ($files as $fileobj) {
2541 //check for dir structure and create recursively
2542 $file = $fileobj->path;
2543 $status = $status && check_dir_exists(dirname($CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/site_files/".$file), true, true);
2544 $status = $status && backup_copy_file($rootdir."/".$file,
2545 $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/site_files/".$file);
2548 return $status;
2550 //This function creates the zip file containing all the backup info
2551 //moodle.xml, moddata, user_files, course_files.
2552 //The zipped file is created in the backup directory and named with
2553 //the "oficial" name of the backup
2554 //It uses "pclzip" if available or system "zip" (unix only)
2555 function backup_zip ($preferences) {
2557 global $CFG;
2559 $status = true;
2561 //Base dir where everything happens
2562 $basedir = cleardoubleslashes($CFG->dataroot."/temp/backup/".$preferences->backup_unique_code);
2563 //Backup zip file name
2564 $name = $preferences->backup_name;
2565 //List of files and directories
2566 $filelist = list_directories_and_files ($basedir);
2568 //Convert them to full paths
2569 $files = array();
2570 foreach ($filelist as $file) {
2571 $files[] = "$basedir/$file";
2574 $status = zip_files($files, "$basedir/$name");
2576 //echo "<br/>Status: ".$status; //Debug
2577 return $status;
2581 //This function copies the final zip to the course dir
2582 function copy_zip_to_course_dir ($preferences) {
2584 global $CFG;
2586 $status = true;
2588 //Define zip location (from)
2589 $from_zip_file = $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/".$preferences->backup_name;
2591 //Initialise $to_zip_file
2592 $to_zip_file="";
2594 //If $preferences->backup_destination isn't empty, then copy to custom directory
2595 if (!empty($preferences->backup_destination)) {
2596 $to_zip_file = $preferences->backup_destination."/".$preferences->backup_name;
2597 } else {
2598 //Define zip destination (course dir)
2599 $to_zip_file = $CFG->dataroot."/".$preferences->backup_course;
2601 //echo "<p>From: ".$from_zip_file."<br />"; //Debug
2603 //echo "<p>Checking: ".$to_zip_file."<br />"; //Debug
2605 //Checks course dir exists
2606 $status = check_dir_exists($to_zip_file,true);
2608 //Define zip destination (backup dir)
2609 $to_zip_file = $to_zip_file."/backupdata";
2611 //echo "<p>Checking: ".$to_zip_file."<br />"; //Debug
2613 //Checks backup dir exists
2614 $status = check_dir_exists($to_zip_file,true);
2616 //Define zip destination (zip file)
2617 $to_zip_file = $to_zip_file."/".$preferences->backup_name;
2620 //echo "<p>To: ".$to_zip_file."<br />"; //Debug
2622 //Copy zip file
2623 if ($status) {
2624 $status = backup_copy_file ($from_zip_file,$to_zip_file);
2627 return $status;
2631 * compatibility function
2632 * with new granular backup
2633 * we need to know
2635 function backup_userdata_selected($preferences,$modname,$modid) {
2636 return ((empty($preferences->mods[$modname]->instances)
2637 && !empty($preferences->mods[$modname]->userinfo))
2638 || (is_array($preferences->mods[$modname]->instances)
2639 && array_key_exists($modid,$preferences->mods[$modname]->instances)
2640 && !empty($preferences->mods[$modname]->instances[$modid]->userinfo)));
2644 function backup_mod_selected($preferences,$modname,$modid) {
2645 return ((empty($preferences->mods[$modname]->instances)
2646 && !empty($preferences->mods[$modname]->backup))
2647 || (is_array($preferences->mods[$modname]->instances)
2648 && array_key_exists($modid,$preferences->mods[$modname]->instances)
2649 && !empty($preferences->mods[$modname]->instances[$modid]->backup)));
2653 * Checks for the required files/functions to backup every mod
2654 * And check if there is data about it
2656 function backup_fetch_prefs_from_request(&$preferences,&$count,$course) {
2657 global $CFG,$SESSION;
2659 // check to see if it's in the session already
2660 if (!empty($SESSION->backupprefs) && array_key_exists($course->id,$SESSION->backupprefs) && !empty($SESSION->backupprefs[$course->id])) {
2661 $sprefs = $SESSION->backupprefs[$course->id];
2662 $preferences = $sprefs;
2663 // refetch backup_name just in case.
2664 $bn = optional_param('backup_name','',PARAM_FILE);
2665 if (!empty($bn)) {
2666 $preferences->backup_name = $bn;
2668 $count = 1;
2669 return true;
2672 if ($allmods = get_records("modules") ) {
2673 foreach ($allmods as $mod) {
2674 $modname = $mod->name;
2675 $modfile = "$CFG->dirroot/mod/$modname/backuplib.php";
2676 $modbackup = $modname."_backup_mods";
2677 $modbackupone = $modname."_backup_one_mod";
2678 $modcheckbackup = $modname."_check_backup_mods";
2679 if (!file_exists($modfile)) {
2680 continue;
2682 include_once($modfile);
2683 if (!function_exists($modbackup) || !function_exists($modcheckbackup)) {
2684 continue;
2686 $var = "exists_".$modname;
2687 $preferences->$var = true;
2688 $count++;
2689 // check that there are instances and we can back them up individually
2690 if (!count_records('course_modules','course',$course->id,'module',$mod->id) || !function_exists($modbackupone)) {
2691 continue;
2693 $var = 'exists_one_'.$modname;
2694 $preferences->$var = true;
2695 $varname = $modname.'_instances';
2696 $preferences->$varname = get_all_instances_in_course($modname, $course, NULL, true);
2697 foreach ($preferences->$varname as $instance) {
2698 $preferences->mods[$modname]->instances[$instance->id]->name = $instance->name;
2699 $var = 'backup_'.$modname.'_instance_'.$instance->id;
2700 $$var = optional_param($var,0);
2701 $preferences->$var = $$var;
2702 $preferences->mods[$modname]->instances[$instance->id]->backup = $$var;
2703 $var = 'backup_user_info_'.$modname.'_instance_'.$instance->id;
2704 $$var = optional_param($var,0);
2705 $preferences->$var = $$var;
2706 $preferences->mods[$modname]->instances[$instance->id]->userinfo = $$var;
2707 $var = 'backup_'.$modname.'_instances';
2708 $preferences->$var = 1; // we need this later to determine what to display in modcheckbackup.
2711 //Check data
2712 //Check module info
2713 $preferences->mods[$modname]->name = $modname;
2715 $var = "backup_".$modname;
2716 $$var = optional_param( $var,0);
2717 $preferences->$var = $$var;
2718 $preferences->mods[$modname]->backup = $$var;
2720 //Check include user info
2721 $var = "backup_user_info_".$modname;
2722 $$var = optional_param( $var,0);
2723 $preferences->$var = $$var;
2724 $preferences->mods[$modname]->userinfo = $$var;
2729 //Check other parameters
2730 $preferences->backup_metacourse = optional_param('backup_metacourse',1,PARAM_INT);
2731 $preferences->backup_users = optional_param('backup_users',1,PARAM_INT);
2732 $preferences->backup_logs = optional_param('backup_logs',0,PARAM_INT);
2733 $preferences->backup_user_files = optional_param('backup_user_files',1,PARAM_INT);
2734 $preferences->backup_course_files = optional_param('backup_course_files',1,PARAM_INT);
2735 $preferences->backup_gradebook_history = optional_param('backup_gradebook_history', 1, PARAM_INT);
2736 $preferences->backup_site_files = optional_param('backup_site_files',1,PARAM_INT);
2737 $preferences->backup_messages = optional_param('backup_messages',1,PARAM_INT);
2738 $preferences->backup_blogs = optional_param('backup_blogs',1,PARAM_INT);
2739 $preferences->backup_course = $course->id;
2740 $preferences->backup_name = required_param('backup_name',PARAM_FILE);
2741 $preferences->backup_unique_code = required_param('backup_unique_code');
2743 $roles = get_records('role', '', '', 'sortorder');
2744 $preferences->backuproleassignments = array();
2745 foreach ($roles as $role) {
2746 if (optional_param('backupassignments_' . $role->shortname, 0, PARAM_INT)) {
2747 $preferences->backuproleassignments[$role->id] = $role;
2751 // put it (back) in the session
2752 $SESSION->backupprefs[$course->id] = $preferences;
2755 /* Finds all related roles used in course, mod and blocks context
2756 * @param object $preferences
2757 * @param object $course
2758 * @return array of role objects
2760 function backup_fetch_roles($preferences) {
2762 global $CFG;
2763 $contexts = array();
2764 $roles = array();
2766 /// adding course context
2767 $coursecontext = get_context_instance(CONTEXT_COURSE, $preferences->backup_course);
2768 $contexts[$coursecontext->id] = $coursecontext;
2770 /// adding mod contexts
2771 $mods = $preferences->mods;
2772 foreach ($mods as $modname => $mod) {
2773 $instances = $mod->instances;
2774 foreach ($instances as $id => $instance) {
2775 // if this type of mod is to be backed up
2776 if ($instance->backup) {
2777 $cm = get_coursemodule_from_instance($modname, $id);
2778 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
2779 // put context in array keys
2780 $contexts[$context->id] = $context;
2785 // add all roles assigned at user context
2786 if ($preferences->backup_users) {
2787 if ($users = get_records_sql("SELECT u.old_id, u.table_name,u.info
2788 FROM {$CFG->prefix}backup_ids u
2789 WHERE u.backup_code = '$preferences->backup_unique_code' AND
2790 u.table_name = 'user'")) {
2791 foreach ($users as $user) {
2792 $context = get_context_instance(CONTEXT_USER, $user->old_id);
2793 $contexts[$context->id] = $context;
2799 // add all roles assigned at block context
2800 if ($courseblocks = get_records_sql("SELECT *
2801 FROM {$CFG->prefix}block_instance
2802 WHERE pagetype = '".PAGE_COURSE_VIEW."'
2803 AND pageid = {$preferences->backup_course}")) {
2805 foreach ($courseblocks as $courseblock) {
2807 $context = get_context_instance(CONTEXT_BLOCK, $courseblock->id);
2808 $contexts[$context->id] = $context;
2812 // foreach context, call get_roles_on_exact_context insert into array
2813 foreach ($contexts as $context) {
2814 if ($proles = get_roles_on_exact_context($context)) {
2815 foreach ($proles as $prole) {
2816 $roles[$prole->id] = $prole;
2821 return $roles;
2824 /* function to print xml for overrides */
2825 function write_role_overrides_xml($bf, $context, $startlevel) {
2826 fwrite ($bf, start_tag("ROLES_OVERRIDES", $startlevel, true));
2827 if ($roles = get_roles_with_override_on_context($context)) {
2828 foreach ($roles as $role) {
2829 fwrite ($bf, start_tag("ROLE", $startlevel+1, true));
2830 fwrite ($bf, full_tag("ID", $startlevel+2, false, $role->id));
2831 fwrite ($bf, full_tag("NAME", $startlevel+2, false, $role->name));
2832 fwrite ($bf, full_tag("SHORTNAME", $startlevel+2, false, $role->shortname));
2833 fwrite ($bf, start_tag("CAPABILITIES", $startlevel+2, true));
2834 if ($capabilities = get_capabilities_from_role_on_context($role, $context)) {
2835 foreach ($capabilities as $capability) {
2836 fwrite ($bf, start_tag("CAPABILITY", $startlevel+3, true));
2837 fwrite ($bf, full_tag("NAME", $startlevel+4, false, $capability->capability));
2838 fwrite ($bf, full_tag("PERMISSION", $startlevel+4, false, $capability->permission));
2839 fwrite ($bf, full_tag("TIMEMODIFIED", $startlevel+4, false, $capability->timemodified));
2840 if (!isset($capability->modifierid)) {
2841 $capability->modifierid = 0;
2843 fwrite ($bf, full_tag("MODIFIERID", $startlevel+4, false, $capability->modifierid));
2844 fwrite ($bf, end_tag("CAPABILITY", $startlevel+3, true));
2847 fwrite ($bf, end_tag("CAPABILITIES", $startlevel+2, true));
2848 fwrite ($bf, end_tag("ROLE", $startlevel+1, true));
2851 fwrite ($bf, end_tag("ROLES_OVERRIDES", $startlevel, true));
2854 /* function to print xml for assignment */
2855 function write_role_assignments_xml($bf, $preferences, $context, $startlevel) {
2856 /// write role_assign code here
2857 fwrite ($bf, start_tag("ROLES_ASSIGNMENTS", $startlevel, true));
2859 if ($roles = get_roles_with_assignment_on_context($context)) {
2860 foreach ($roles as $role) {
2861 /// Skip non-selected roles
2862 if (!isset($preferences->backuproleassignments[$role->id])) {
2863 continue;
2865 fwrite ($bf, start_tag("ROLE", $startlevel+1, true));
2866 fwrite ($bf, full_tag("ID", $startlevel+2, false, $role->id));
2867 fwrite ($bf, full_tag("NAME", $startlevel+2, false, $role->name));
2868 fwrite ($bf, full_tag("SHORTNAME", $startlevel+2, false, $role->shortname));
2869 fwrite ($bf, start_tag("ASSIGNMENTS", $startlevel+2, true));
2870 if ($assignments = get_users_from_role_on_context($role, $context)) {
2871 foreach ($assignments as $assignment) {
2872 /// Role assignments are only sent to backup if the user is one target user
2873 if (backup_getid($preferences->backup_unique_code, 'user', $assignment->userid)) {
2874 fwrite ($bf, start_tag("ASSIGNMENT", $startlevel+3, true));
2875 fwrite ($bf, full_tag("USERID", $startlevel+4, false, $assignment->userid));
2876 fwrite ($bf, full_tag("HIDDEN", $startlevel+4, false, $assignment->hidden));
2877 fwrite ($bf, full_tag("TIMESTART", $startlevel+4, false, $assignment->timestart));
2878 fwrite ($bf, full_tag("TIMEEND", $startlevel+4, false, $assignment->timeend));
2879 fwrite ($bf, full_tag("TIMEMODIFIED", $startlevel+4, false, $assignment->timemodified));
2880 if (!isset($assignment->modifierid)) {
2881 $assignment->modifierid = 0;
2883 fwrite ($bf, full_tag("MODIFIERID", $startlevel+4, false, $assignment->modifierid));
2884 fwrite ($bf, full_tag("ENROL", $startlevel+4, false, $assignment->enrol));
2885 fwrite ($bf, full_tag("SORTORDER", $startlevel+4, false, $assignment->sortorder));
2886 fwrite ($bf, end_tag("ASSIGNMENT", $startlevel+3, true));
2890 fwrite ($bf, end_tag("ASSIGNMENTS", $startlevel+2, true));
2891 fwrite ($bf, end_tag("ROLE", $startlevel+1, true));
2894 fwrite ($bf, end_tag("ROLES_ASSIGNMENTS", $startlevel, true));
2898 function backup_execute(&$preferences, &$errorstr) {
2899 global $CFG;
2900 $status = true;
2902 //Check for temp and backup and backup_unique_code directory
2903 //Create them as needed
2904 if (!defined('BACKUP_SILENTLY')) {
2905 echo "<li>".get_string("creatingtemporarystructures").'</li>';
2908 $status = check_and_create_backup_dir($preferences->backup_unique_code);
2909 //Empty dir
2910 if ($status) {
2911 $status = clear_backup_dir($preferences->backup_unique_code);
2914 //Delete old_entries from backup tables
2915 if (!defined('BACKUP_SILENTLY')) {
2916 echo "<li>".get_string("deletingolddata").'</li>';
2918 $status = backup_delete_old_data();
2919 if (!$status) {
2920 if (!defined('BACKUP_SILENTLY')) {
2921 notify ("An error occurred deleting old backup data");
2923 else {
2924 $errorstr = "An error occurred deleting old backup data";
2925 return false;
2929 //Create the moodle.xml file
2930 if ($status) {
2931 if (!defined('BACKUP_SILENTLY')) {
2932 echo "<li>".get_string("creatingxmlfile");
2933 //Begin a new list to xml contents
2934 echo "<ul>";
2935 echo "<li>".get_string("writingheader").'</li>';
2937 //Obtain the xml file (create and open) and print prolog information
2938 $backup_file = backup_open_xml($preferences->backup_unique_code);
2939 if (!defined('BACKUP_SILENTLY')) {
2940 echo "<li>".get_string("writinggeneralinfo").'</li>';
2942 //Prints general info about backup to file
2943 if ($backup_file) {
2944 if (!$status = backup_general_info($backup_file,$preferences)) {
2945 if (!defined('BACKUP_SILENTLY')) {
2946 notify("An error occurred while backing up general info");
2948 else {
2949 $errorstr = "An error occurred while backing up general info";
2950 return false;
2954 if (!defined('BACKUP_SILENTLY')) {
2955 echo "<li>".get_string("writingcoursedata");
2956 //Start new ul (for course)
2957 echo "<ul>";
2958 echo "<li>".get_string("courseinfo").'</li>';
2960 //Prints course start (tag and general info)
2961 if ($status) {
2962 if (!$status = backup_course_start($backup_file,$preferences)) {
2963 if (!defined('BACKUP_SILENTLY')) {
2964 notify("An error occurred while backing up course start");
2966 else {
2967 $errorstr = "An error occurred while backing up course start";
2968 return false;
2972 //Metacourse information
2973 if ($status && $preferences->backup_metacourse) {
2974 if (!defined('BACKUP_SILENTLY')) {
2975 echo "<li>".get_string("metacourse").'</li>';
2977 if (!$status = backup_course_metacourse($backup_file,$preferences)) {
2978 if (!defined('BACKUP_SILENTLY')) {
2979 notify("An error occurred while backing up metacourse info");
2981 else {
2982 $errorstr = "An error occurred while backing up metacourse info";
2983 return false;
2987 if (!defined('BACKUP_SILENTLY')) {
2988 echo "<li>".get_string("blocks").'</li>';
2990 //Blocks information
2991 if ($status) {
2992 if (!$status = backup_course_blocks($backup_file,$preferences)) {
2993 if (!defined('BACKUP_SILENTLY')) {
2994 notify("An error occurred while backing up course blocks");
2996 else {
2997 $errorstr = "An error occurred while backing up course blocks";
2998 return false;
3002 if (!defined('BACKUP_SILENTLY')) {
3003 echo "<li>".get_string("sections").'</li>';
3005 //Section info
3006 if ($status) {
3007 if (!$status = backup_course_sections($backup_file,$preferences)) {
3008 if (!defined('BACKUP_SILENTLY')) {
3009 notify("An error occurred while backing up course sections");
3011 else {
3012 $errorstr = "An error occurred while backing up course sections";
3013 return false;
3018 //End course contents (close ul)
3019 if (!defined('BACKUP_SILENTLY')) {
3020 echo "</ul></li>";
3023 //User info
3024 if ($status) {
3025 if (!defined('BACKUP_SILENTLY')) {
3026 echo "<li>".get_string("writinguserinfo").'</li>';
3028 if (!$status = backup_user_info($backup_file,$preferences)) {
3029 if (!defined('BACKUP_SILENTLY')) {
3030 notify("An error occurred while backing up user info");
3032 else {
3033 $errorstr = "An error occurred while backing up user info";
3034 return false;
3039 //If we have selected to backup messages and we are
3040 //doing a SITE backup, let's do it
3041 if ($status && $preferences->backup_messages && $preferences->backup_course == SITEID) {
3042 if (!defined('BACKUP_SILENTLY')) {
3043 echo "<li>".get_string("writingmessagesinfo").'</li>';
3045 if (!$status = backup_messages($backup_file,$preferences)) {
3046 if (!defined('BACKUP_SILENTLY')) {
3047 notify("An error occurred while backing up messages");
3049 else {
3050 $errorstr = "An error occurred while backing up messages";
3051 return false;
3056 //If we have selected to backup blogs and we are
3057 //doing a SITE backup, let's do it
3058 if ($status && $preferences->backup_blogs && $preferences->backup_course == SITEID) {
3059 if (!defined('BACKUP_SILENTLY')) {
3060 echo "<li>".get_string("writingblogsinfo").'</li>';
3062 if (!$status = backup_blogs($backup_file,$preferences)) {
3063 if (!defined('BACKUP_SILENTLY')) {
3064 notify("An error occurred while backing up blogs");
3066 else {
3067 $errorstr = "An error occurred while backing up blogs";
3068 return false;
3073 //If we have selected to backup quizzes or other modules that use questions
3074 //we've already added ids of categories and questions to backup to backup_ids table
3075 if ($status) {
3076 if (!defined('BACKUP_SILENTLY')) {
3077 echo "<li>".get_string("writingcategoriesandquestions").'</li>';
3079 require_once($CFG->dirroot.'/question/backuplib.php');
3080 if (!$status = backup_question_categories($backup_file, $preferences)) {
3081 if (!defined('BACKUP_SILENTLY')) {
3082 notify("An error occurred while backing up quiz categories");
3084 else {
3085 $errorstr = "An error occurred while backing up quiz categories";
3086 return false;
3091 //Print logs if selected
3092 if ($status) {
3093 if ($preferences->backup_logs) {
3094 if (!defined('BACKUP_SILENTLY')) {
3095 echo "<li>".get_string("writingloginfo").'</li>';
3097 if (!$status = backup_log_info($backup_file,$preferences)) {
3098 if (!defined('BACKUP_SILENTLY')) {
3099 notify("An error occurred while backing up log info");
3101 else {
3102 $errorstr = "An error occurred while backing up log info";
3103 return false;
3109 //Print scales info
3110 if ($status) {
3111 if (!defined('BACKUP_SILENTLY')) {
3112 echo "<li>".get_string("writingscalesinfo").'</li>';
3114 if (!$status = backup_scales_info($backup_file,$preferences)) {
3115 if (!defined('BACKUP_SILENTLY')) {
3116 notify("An error occurred while backing up scales");
3118 else {
3119 $errorstr = "An error occurred while backing up scales";
3120 return false;
3125 //Print groups info
3126 if ($status) {
3127 if (!defined('BACKUP_SILENTLY')) {
3128 echo "<li>".get_string("writinggroupsinfo").'</li>';
3130 if (!$status = backup_groups_info($backup_file,$preferences)) {
3131 if (!defined('BACKUP_SILENTLY')) {
3132 notify("An error occurred while backing up groups");
3134 else {
3135 $errostr = "An error occurred while backing up groups";
3136 return false;
3141 //Print groupings info
3142 if ($status) {
3143 if (!defined('BACKUP_SILENTLY')) {
3144 echo "<li>".get_string("writinggroupingsinfo").'</li>';
3146 if (!$status = backup_groupings_info($backup_file,$preferences)) {
3147 if (!defined('BACKUP_SILENTLY')) {
3148 notify("An error occurred while backing up groupings");
3150 else {
3151 $errorstr = "An error occurred while backing up groupings";
3152 return false;
3157 //Print groupings_groups info
3158 if ($status) {
3159 if (!defined('BACKUP_SILENTLY')) {
3160 echo "<li>".get_string("writinggroupingsgroupsinfo").'</li>';
3162 if (!$status = backup_groupings_groups_info($backup_file,$preferences)) {
3163 if (!defined('BACKUP_SILENTLY')) {
3164 notify("An error occurred while backing up groupings groups");
3166 else {
3167 $errorstr = "An error occurred while backing up groupings groups";
3168 return false;
3173 //Print events info
3174 if ($status) {
3175 if (!defined('BACKUP_SILENTLY')) {
3176 echo "<li>".get_string("writingeventsinfo").'</li>';
3178 if (!$status = backup_events_info($backup_file,$preferences)) {
3179 if (!defined('BACKUP_SILENTLY')) {
3180 notify("An error occurred while backing up events");
3182 else {
3183 $errorstr = "An error occurred while backing up events";
3184 return false;
3189 //Print gradebook info
3190 if ($status) {
3191 if (!defined('BACKUP_SILENTLY')) {
3192 echo "<li>".get_string("writinggradebookinfo").'</li>';
3194 if (!$status = backup_gradebook_info($backup_file,$preferences)) {
3195 if (!defined('BACKUP_SILENTLY')) {
3196 notify("An error occurred while backing up gradebook");
3198 else {
3199 $errorstr = "An error occurred while backing up gradebook";
3200 return false;
3205 //Module info, this unique function makes all the work!!
3206 //db export and module fileis copy
3207 if ($status) {
3208 $mods_to_backup = false;
3209 //Check if we have any mod to backup
3210 foreach ($preferences->mods as $module) {
3211 if ($module->backup) {
3212 $mods_to_backup = true;
3215 //If we have to backup some module
3216 if ($mods_to_backup) {
3217 if (!defined('BACKUP_SILENTLY')) {
3218 echo "<li>".get_string("writingmoduleinfo");
3220 //Start modules tag
3221 if (!$status = backup_modules_start ($backup_file,$preferences)) {
3222 if (!defined('BACKUP_SILENTLY')) {
3223 notify("An error occurred while backing up module info");
3225 else {
3226 $errorstr = "An error occurred while backing up module info";
3227 return false;
3230 //Open ul for module list
3231 if (!defined('BACKUP_SILENTLY')) {
3232 echo "<ul>";
3234 //Iterate over modules and call backup
3235 foreach ($preferences->mods as $module) {
3236 if ($module->backup and $status) {
3237 if (!defined('BACKUP_SILENTLY')) {
3238 echo "<li>".get_string("modulenameplural",$module->name).'</li>';
3240 if (!$status = backup_module($backup_file,$preferences,$module->name)) {
3241 if (!defined('BACKUP_SILENTLY')) {
3242 notify("An error occurred while backing up '$module->name'");
3244 else {
3245 $errorstr = "An error occurred while backing up '$module->name'";
3246 return false;
3251 //Close ul for module list
3252 if (!defined('BACKUP_SILENTLY')) {
3253 echo "</ul></li>";
3255 //Close modules tag
3256 if (!$status = backup_modules_end ($backup_file,$preferences)) {
3257 if (!defined('BACKUP_SILENTLY')) {
3258 notify("An error occurred while finishing the module backups");
3260 else {
3261 $errorstr = "An error occurred while finishing the module backups";
3262 return false;
3268 //Backup course format data, if any.
3269 if (!defined('BACKUP_SILENTLY')) {
3270 echo '<li>'.get_string("courseformatdata").'</li>';
3272 if($status) {
3273 if (!$status = backup_format_data($backup_file,$preferences)) {
3274 if (!defined('BACKUP_SILENTLY')) {
3275 notify("An error occurred while backing up the course format data");
3277 else {
3278 $errorstr = "An error occurred while backing up the course format data";
3279 return false;
3284 //Prints course end
3285 if ($status) {
3286 if (!$status = backup_course_end($backup_file,$preferences)) {
3287 if (!defined('BACKUP_SILENTLY')) {
3288 notify("An error occurred while closing the course backup");
3290 else {
3291 $errorstr = "An error occurred while closing the course backup";
3292 return false;
3296 //Close the xml file and xml data
3297 if ($backup_file) {
3298 backup_close_xml($backup_file);
3301 //End xml contents (close ul)
3302 if (!defined('BACKUP_SILENTLY')) {
3303 echo "</ul></li>";
3307 //Now, if selected, copy user files
3308 if ($status) {
3309 if ($preferences->backup_user_files) {
3310 if (!defined('BACKUP_SILENTLY')) {
3311 echo "<li>".get_string("copyinguserfiles").'</li>';
3313 if (!$status = backup_copy_user_files ($preferences)) {
3314 if (!defined('BACKUP_SILENTLY')) {
3315 notify("An error occurred while copying user files");
3317 else {
3318 $errorstr = "An error occurred while copying user files";
3319 return false;
3325 //Now, if selected, copy course files
3326 if ($status) {
3327 if ($preferences->backup_course_files) {
3328 if (!defined('BACKUP_SILENTLY')) {
3329 echo "<li>".get_string("copyingcoursefiles").'</li>';
3331 if (!$status = backup_copy_course_files ($preferences)) {
3332 if (!defined('BACKUP_SILENTLY')) {
3333 notify("An error occurred while copying course files");
3335 else {
3336 $errorstr = "An error occurred while copying course files";
3337 return false;
3342 //Now, if selected, copy site files
3343 if ($status) {
3344 if ($preferences->backup_site_files) {
3345 if (!defined('BACKUP_SILENTLY')) {
3346 echo "<li>".get_string("copyingsitefiles").'</li>';
3348 if (!$status = backup_copy_site_files ($preferences)) {
3349 if (!defined('BACKUP_SILENTLY')) {
3350 notify("An error occurred while copying site files");
3352 else {
3353 $errorstr = "An error occurred while copying site files";
3354 return false;
3359 //Now, zip all the backup directory contents
3360 if ($status) {
3361 if (!defined('BACKUP_SILENTLY')) {
3362 echo "<li>".get_string("zippingbackup").'</li>';
3364 if (!$status = backup_zip ($preferences)) {
3365 if (!defined('BACKUP_SILENTLY')) {
3366 notify("An error occurred while zipping the backup");
3368 else {
3369 $errorstr = "An error occurred while zipping the backup";
3370 return false;
3375 //Now, copy the zip file to course directory
3376 if ($status) {
3377 if (!defined('BACKUP_SILENTLY')) {
3378 echo "<li>".get_string("copyingzipfile").'</li>';
3380 if (!$status = copy_zip_to_course_dir ($preferences)) {
3381 if (!defined('BACKUP_SILENTLY')) {
3382 notify("An error occurred while copying the zip file to the course directory");
3384 else {
3385 $errorstr = "An error occurred while copying the zip file to the course directory";
3386 return false;
3391 //Now, clean temporary data (db and filesystem)
3392 if ($status) {
3393 if (!defined('BACKUP_SILENTLY')) {
3394 echo "<li>".get_string("cleaningtempdata").'</li>';
3396 if (!$status = clean_temp_data ($preferences)) {
3397 if (!defined('BACKUP_SILENTLY')) {
3398 notify("An error occurred while cleaning up temporary data");
3400 else {
3401 $errorstr = "An error occurred while cleaning up temporary data";
3402 return false;
3407 return $status;
3411 * This function calculates the "backup" part of the file name
3412 * from lang files. Used both in manual and scheduled backups
3414 * @param object $course course object
3415 * @return string "backup" part of the filename
3417 function backup_get_backup_string($course) {
3419 /// Calculate the backup word
3420 /// Take off some characters in the filename !!
3421 $takeoff = array(" ", ":", "/", "\\", "|");
3422 $backup_word = str_replace($takeoff,"_",moodle_strtolower(get_string("backupfilename")));
3423 /// If non-translated, use "backup"
3424 if (substr($backup_word,0,1) == "[") {
3425 $backup_word= "backup";
3428 return $backup_word;
3432 * This function generates the default zipfile name for a backup
3433 * based on the course shortname
3435 * @param object $course course object
3436 * @return string filename (excluding path information)
3438 function backup_get_zipfile_name($course) {
3440 //Calculate the backup word
3441 $backup_word = backup_get_backup_string($course);
3443 //Calculate the date format string
3444 $backup_date_format = str_replace(" ","_",get_string("backupnameformat"));
3445 //If non-translated, use "%Y%m%d-%H%M"
3446 if (substr($backup_date_format,0,1) == "[") {
3447 $backup_date_format = "%%Y%%m%%d-%%H%%M";
3450 //Calculate the shortname
3451 $backup_shortname = clean_filename($course->shortname);
3452 if (empty($backup_shortname) or $backup_shortname == '_' ) {
3453 $backup_shortname = $course->id;
3456 //Calculate the final backup filename
3457 //The backup word
3458 $backup_name = $backup_word."-";
3459 //The shortname
3460 $backup_name .= moodle_strtolower($backup_shortname)."-";
3461 //The date format
3462 $backup_name .= userdate(time(),$backup_date_format,99,false);
3463 //The extension
3464 $backup_name .= ".zip";
3465 //And finally, clean everything
3466 $backup_name = clean_filename($backup_name);
3468 return $backup_name;
3472 * This function generates the common file substring for a course
3473 * used to keep n copies by the scheduled backup
3475 * @param object $course course object
3476 * @return string common part of filename in backups of this course
3478 function backup_get_keep_name($course) {
3480 //Calculate the backup word
3481 $backup_word = backup_get_backup_string($course);
3483 //Calculate the shortname
3484 $backup_shortname = clean_filename($course->shortname);
3485 if (empty($backup_shortname) or $backup_shortname == '_' ) {
3486 $backup_shortname = $course->id;
3489 $keep_name = $backup_word . "-" . moodle_strtolower($backup_shortname)."-";
3490 $keep_name = clean_filename($keep_name);
3492 return $keep_name;
3495 * This function adds on the standard items to the preferences
3496 * Like moodle version and backup version
3498 * @param object $preferences existing preferences object.
3499 * (passed by reference)
3501 function backup_add_static_preferences(&$preferences) {
3502 global $CFG;
3503 $preferences->moodle_version = $CFG->version;
3504 $preferences->moodle_release = $CFG->release;
3505 $preferences->backup_version = $CFG->backup_version;
3506 $preferences->backup_release = $CFG->backup_release;