Added link to Cloze
[moodle.git] / backup / backuplib.php
blob33f072615ad216837257b98a5b0a5016b8341ca5
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 //Insert necessary category ids to backup_ids table
7 function insert_category_ids ($course,$backup_unique_code) {
8 global $CFG;
9 $status = true;
10 $status = execute_sql("INSERT INTO {$CFG->prefix}backup_ids
11 (backup_code, table_name, old_id)
12 SELECT DISTINCT '$backup_unique_code','quiz_categories',t.category
13 FROM {$CFG->prefix}quiz_questions t,
14 {$CFG->prefix}quiz_question_grades g,
15 {$CFG->prefix}quiz q
16 WHERE q.course = '$course' AND
17 g.quiz = q.id AND
18 g.question = t.id",false);
19 return $status;
22 //Delete category ids from backup_ids table
23 function delete_category_ids ($backup_unique_code) {
24 global $CFG;
25 $status = true;
26 $status = execute_sql("DELETE FROM {$CFG->prefix}backup_ids
27 WHERE backup_code = '$backup_unique_code'",false);
28 return $status;
31 //Calculate the number of users to backup and put their ids in backup_ids
32 //Return an array of info (name,value)
33 function user_check_backup($course,$backup_unique_code,$backup_users) {
34 //$backup_users=0-->all
35 // 1-->course (needed + enrolled)
37 global $CFG;
38 global $db;
40 $count_users = 0;
42 //Calculate needed users (calling every xxxx_get_participants function + scales users)
43 $needed_users = backup_get_needed_users($course);
45 //Calculate enrolled users (students + teachers)
46 $enrolled_users = backup_get_enrolled_users($course);
48 //Calculate all users (every record in users table)
49 $all_users = backup_get_all_users();
51 //Calculate course users (needed + enrolled)
52 //First, needed
53 $course_users = $needed_users;
55 //Now, enrolled
56 if ($enrolled_users) {
57 foreach ($enrolled_users as $enrolled_user) {
58 $course_users[$enrolled_user->id]->id = $enrolled_user->id;
62 //Now, depending of parameters, create $backupable_users
63 if ($backup_users == 0) {
64 $backupable_users = $all_users;
65 } else {
66 $backupable_users = $course_users;
69 //If we have backupable users
70 if ($backupable_users) {
71 //Iterate over users putting their roles
72 foreach ($backupable_users as $backupable_user) {
73 $backupable_user->info = "";
74 //Is Admin in tables (not is_admin()) !!
75 if (record_exists("user_admins","userid",$backupable_user->id)) {
76 $backupable_user->info .= "admin";
78 //Is Course Creator in tables (not is_coursecreator()) !!
79 if (record_exists("user_coursecreators","userid",$backupable_user->id)) {
80 $backupable_user->info .= "coursecreator";
82 //Is Teacher in tables (not is_teacher()) !!
83 if (record_exists("user_teachers","course",$course,"userid",$backupable_user->id)) {
84 $backupable_user->info .= "teacher";
86 //Is Student in tables (not is_student()) !!
87 if (record_exists("user_students","course",$course,"userid",$backupable_user->id)) {
88 $backupable_user->info .= "student";
90 //Is needed user (exists in needed_users)
91 if (isset($needed_users[$backupable_user->id])) {
92 $backupable_user->info .= "needed";
94 //Now create the backup_id record
95 $backupids_rec->backup_code = $backup_unique_code;
96 $backupids_rec->table_name = "user";
97 $backupids_rec->old_id = $backupable_user->id;
98 $backupids_rec->info = $backupable_user->info;
100 //Insert the record id. backup_users decide it.
101 //When all users
102 $status = insert_record("backup_ids",$backupids_rec,false,"backup_code");
103 $count_users++;
105 //Do some output
106 backup_flush(30);
109 //Prepare Info
110 //Gets the user data
111 $info[0][0] = get_string("users");
112 $info[0][1] = $count_users;
114 return $info;
117 //Returns every needed user (participant) in a course
118 //It uses the xxxx_get_participants() function
119 //plus users needed to backup scales.
120 //WARNING: It returns only NEEDED users, not every
121 // every student and teacher in the course, so it
122 //must be merged with backup_get_enrrolled_users !!
124 function backup_get_needed_users ($courseid) {
126 global $CFG;
128 $result = false;
130 $course_modules = get_records_sql ("SELECT cm.id, m.name, cm.instance
131 FROM {$CFG->prefix}modules m,
132 {$CFG->prefix}course_modules cm
133 WHERE m.id = cm.module and
134 cm.course = '$courseid'");
136 if ($course_modules) {
137 //Iterate over each module
138 foreach ($course_modules as $course_module) {
139 $modlib = "$CFG->dirroot/mod/$course_module->name/lib.php";
140 $modgetparticipants = $course_module->name."_get_participants";
141 if (file_exists($modlib)) {
142 include_once($modlib);
143 if (function_exists($modgetparticipants)) {
144 $module_participants = $modgetparticipants($course_module->instance);
145 //Add them to result
146 if ($module_participants) {
147 foreach ($module_participants as $module_participant) {
148 $result[$module_participant->id]->id = $module_participant->id;
156 //Now, add scales users (from site and course scales)
157 //Get users
158 $scaleusers = get_records_sql("SELECT DISTINCT userid,userid
159 FROM {$CFG->prefix}scale
160 WHERE courseid = '0' or courseid = '$courseid'");
161 //Add scale users to results
162 if ($scaleusers) {
163 foreach ($scaleusers as $scaleuser) {
164 //If userid != 0
165 if ($scaleuser->userid != 0) {
166 $result[$scaleuser->userid]->id = $scaleuser->userid;
171 return $result;
175 //Returns every enrolled user (student and teacher) in a course
177 function backup_get_enrolled_users ($courseid) {
179 global $CFG;
181 $result = false;
183 //Get teachers
184 $teachers = get_records_sql("SELECT DISTINCT userid,userid
185 FROM {$CFG->prefix}user_teachers
186 WHERE course = '$courseid'");
187 //Get students
188 $students = get_records_sql("SELECT DISTINCT userid,userid
189 FROM {$CFG->prefix}user_students
190 WHERE course = '$courseid'");
191 //Add teachers
192 if ($teachers) {
193 foreach ($teachers as $teacher) {
194 $result[$teacher->userid]->id = $teacher->userid;
197 //Add students
198 if ($students) {
199 foreach ($students as $student) {
200 $result[$student->userid]->id = $student->userid;
204 return $result;
207 //Returns all users (every record in users table)
209 function backup_get_all_users() {
211 global $CFG;
213 $result = false;
215 //Get users
216 $users = get_records_sql("SELECT DISTINCT id,id
217 FROM {$CFG->prefix}user");
218 //Add users
219 if ($users) {
220 foreach ($users as $user) {
221 $result[$user->id]->id = $user->id;
225 return $result;
228 //Calculate the number of log entries to backup
229 //Return an array of info (name,value)
230 function log_check_backup($course) {
232 global $CFG;
234 //Now execute the count
235 $ids = count_records("log","course",$course);
237 //Gets the user data
238 $info[0][0] = get_string("logs");
239 if ($ids) {
240 $info[0][1] = $ids;
241 } else {
242 $info[0][1] = 0;
245 return $info;
248 //Calculate the number of user files to backup
249 //Under $CFG->dataroot/users
250 //and put them (their path) in backup_ids
251 //Return an array of info (name,value)
252 function user_files_check_backup($course,$backup_unique_code) {
254 global $CFG;
256 $rootdir = $CFG->dataroot."/users";
257 //Check if directory exists
258 if (is_dir($rootdir)) {
259 $coursedirs = get_directory_list($rootdir);
260 foreach ($coursedirs as $dir) {
261 //Extracts user id from file path
262 $tok = strtok($dir,"/");
263 if ($tok) {
264 $userid = $tok;
265 } else {
266 $tok = "";
268 //Look it is a backupable user
269 $data = get_record ("backup_ids","backup_code","$backup_unique_code",
270 "table_name","user",
271 "old_id",$userid);
272 if ($data) {
273 //Insert them into backup_files
274 $status = execute_sql("INSERT INTO {$CFG->prefix}backup_files
275 (backup_code, file_type, path, old_id)
276 VALUES
277 ('$backup_unique_code','user','$dir','$userid')",false);
279 //Do some output
280 backup_flush(30);
284 //Now execute the select
285 $ids = get_records_sql("SELECT DISTINCT b.path, b.old_id
286 FROM {$CFG->prefix}backup_files b
287 WHERE backup_code = '$backup_unique_code' AND
288 file_type = 'user'");
289 //Gets the user data
290 $info[0][0] = get_string("files");
291 if ($ids) {
292 $info[0][1] = count($ids);
293 } else {
294 $info[0][1] = 0;
297 return $info;
300 //Calculate the number of course files to backup
301 //under $CFG->dataroot/$course, except $CFG->moddata, and backupdata
302 //and put them (their path) in backup_ids
303 //Return an array of info (name,value)
304 function course_files_check_backup($course,$backup_unique_code) {
306 global $CFG;
308 $rootdir = $CFG->dataroot."/$course";
309 //Check if directory exists
310 if (is_dir($rootdir)) {
311 $coursedirs = get_directory_list($rootdir,$CFG->moddata);
312 $backupdata_dir = "backupdata";
313 foreach ($coursedirs as $dir) {
314 //Check it isn't backupdata_dir
315 if (strpos($dir,$backupdata_dir)!==0) {
316 //Insert them into backup_files
317 $status = execute_sql("INSERT INTO {$CFG->prefix}backup_files
318 (backup_code, file_type, path)
319 VALUES
320 ('$backup_unique_code','course','$dir')",false);
322 //Do some output
323 backup_flush(30);
327 //Now execute the select
328 $ids = get_records_sql("SELECT DISTINCT b.path, b.old_id
329 FROM {$CFG->prefix}backup_files b
330 WHERE backup_code = '$backup_unique_code' AND
331 file_type = 'course'");
332 //Gets the user data
333 $info[0][0] = get_string("files");
334 if ($ids) {
335 $info[0][1] = count($ids);
336 } else {
337 $info[0][1] = 0;
340 return $info;
343 //Function to check and create the needed moddata dir to
344 //save all the mod backup files. We always name it moddata
345 //to be able to restore it, but in restore we check for
346 //$CFG->moddata !!
347 function check_and_create_moddata_dir($backup_unique_code) {
349 global $CFG;
351 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/moddata",true);
353 return $status;
356 //Function to check and create the "user_files" dir to
357 //save all the user files we need from "users" dir
358 function check_and_create_user_files_dir($backup_unique_code) {
360 global $CFG;
362 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/user_files",true);
364 return $status;
367 //Function to check and create the "course_files" dir to
368 //save all the course files we need from "CFG->datadir/course" dir
369 function check_and_create_course_files_dir($backup_unique_code) {
371 global $CFG;
373 $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/course_files",true);
375 return $status;
378 //Function to create, open and write header of the xml file
379 function backup_open_xml($backup_unique_code) {
381 global $CFG;
383 $status = true;
385 //Open for writing
387 $file = $CFG->dataroot."/temp/backup/".$backup_unique_code."/moodle.xml";
388 $backup_file = fopen($file,"w");
389 //Writes the header
390 $status = fwrite ($backup_file,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
391 if ($status) {
392 $status = fwrite ($backup_file,start_tag("MOODLE_BACKUP",0,true));
394 if ($status) {
395 return $backup_file;
396 } else {
397 return false;
401 //Close the file
402 function backup_close_xml($backup_file) {
403 $status = fwrite ($backup_file,end_tag("MOODLE_BACKUP",0,true));
404 return fclose($backup_file);
407 //Return the xml start tag
408 function start_tag($tag,$level=0,$endline=false) {
409 if ($endline) {
410 $endchar = "\n";
411 } else {
412 $endchar = "";
414 return str_repeat(" ",$level*2)."<".strtoupper($tag).">".$endchar;
417 //Return the xml end tag
418 function end_tag($tag,$level=0,$endline=true) {
419 if ($endline) {
420 $endchar = "\n";
421 } else {
422 $endchar = "";
424 return str_repeat(" ",$level*2)."</".strtoupper($tag).">".$endchar;
427 //Return the start tag, the contents and the end tag
428 function full_tag($tag,$level=0,$endline=true,$content,$to_utf=true) {
429 $st = start_tag($tag,$level,$endline);
430 $co="";
431 if ($to_utf) {
432 $co = preg_replace("/\r\n|\r/", "\n", utf8_encode(htmlspecialchars($content)));
433 } else {
434 $co = preg_replace("/\r\n|\r/", "\n", htmlspecialchars($content));
436 $et = end_tag($tag,0,true);
437 return $st.$co.$et;
440 //Prints General info about the course
441 //name, moodle_version (internal and release), backup_version, date, info in file...
442 function backup_general_info ($bf,$preferences) {
444 global $CFG;
446 fwrite ($bf,start_tag("INFO",1,true));
448 //The name of the backup
449 fwrite ($bf,full_tag("NAME",2,false,$preferences->backup_name));
450 //The moodle_version
451 fwrite ($bf,full_tag("MOODLE_VERSION",2,false,$preferences->moodle_version));
452 fwrite ($bf,full_tag("MOODLE_RELEASE",2,false,$preferences->moodle_release));
453 //The backup_version
454 fwrite ($bf,full_tag("BACKUP_VERSION",2,false,$preferences->backup_version));
455 fwrite ($bf,full_tag("BACKUP_RELEASE",2,false,$preferences->backup_release));
456 //The date
457 fwrite ($bf,full_tag("DATE",2,false,$preferences->backup_unique_code));
458 //Te includes tag
459 fwrite ($bf,start_tag("DETAILS",2,true));
460 //Now, go to mod element of preferences to print its status
461 foreach ($preferences->mods as $element) {
462 //Calculate info
463 $included = "false";
464 $userinfo = "false";
465 if ($element->backup) {
466 $included = "true";
467 if ($element->userinfo) {
468 $userinfo = "true";
471 //Prints the mod start
472 fwrite ($bf,start_tag("MOD",3,true));
473 fwrite ($bf,full_tag("NAME",4,false,$element->name));
474 fwrite ($bf,full_tag("INCLUDED",4,false,$included));
475 fwrite ($bf,full_tag("USERINFO",4,false,$userinfo));
477 //Print the end
478 fwrite ($bf,end_tag("MOD",3,true));
480 //The user in backup
481 if ($preferences->backup_users == 1) {
482 fwrite ($bf,full_tag("USERS",3,false,"course"));
483 } else {
484 fwrite ($bf,full_tag("USERS",3,false,"all"));
486 //The logs in backup
487 if ($preferences->backup_logs == 1) {
488 fwrite ($bf,full_tag("LOGS",3,false,"true"));
489 } else {
490 fwrite ($bf,full_tag("LOGS",3,false,"false"));
492 //The user files
493 if ($preferences->backup_user_files == 1) {
494 fwrite ($bf,full_tag("USERFILES",3,false,"true"));
495 } else {
496 fwrite ($bf,full_tag("USERFILES",3,false,"false"));
498 //The course files
499 if ($preferences->backup_course_files == 1) {
500 fwrite ($bf,full_tag("COURSEFILES",3,false,"true"));
501 } else {
502 fwrite ($bf,full_tag("COURSEFILES",3,false,"false"));
505 fwrite ($bf,end_tag("DETAILS",2,true));
508 $status = fwrite ($bf,end_tag("INFO",1,true));
510 return $status;
513 //Prints course's general info (table course)
514 function backup_course_start ($bf,$preferences) {
516 global $CFG;
518 $status = true;
520 //Course open tag
521 fwrite ($bf,start_tag("COURSE",1,true));
522 //Header open tag
523 fwrite ($bf,start_tag("HEADER",2,true));
525 //Get info from course
526 $course=false;
527 if ($courses = get_records("course","id",$preferences->backup_course)) {
528 $course = $courses[$preferences->backup_course];
530 if ($course) {
531 //Prints course info
532 fwrite ($bf,full_tag("ID",3,false,$course->id));
533 //Obtain the category
534 $category = false;
535 if ($categories = get_records("course_categories","id","$course->category")) {
536 $category = $categories[$course->category];
538 if ($category) {
539 //Prints category info
540 fwrite ($bf,start_tag("CATEGORY",3,true));
541 fwrite ($bf,full_tag("ID",4,false,$course->category));
542 fwrite ($bf,full_tag("NAME",4,false,$category->name));
543 fwrite ($bf,end_tag("CATEGORY",3,true));
545 //Continues with the course
546 fwrite ($bf,full_tag("PASSWORD",3,false,$course->password));
547 fwrite ($bf,full_tag("FULLNAME",3,false,$course->fullname));
548 fwrite ($bf,full_tag("SHORTNAME",3,false,$course->shortname));
549 fwrite ($bf,full_tag("SUMMARY",3,false,$course->summary));
550 fwrite ($bf,full_tag("FORMAT",3,false,$course->format));
551 fwrite ($bf,full_tag("SHOWGRADES",3,false,$course->showgrades));
552 fwrite ($bf,full_tag("NEWSITEMS",3,false,$course->newsitems));
553 fwrite ($bf,full_tag("TEACHER",3,false,$course->teacher));
554 fwrite ($bf,full_tag("TEACHERS",3,false,$course->teachers));
555 fwrite ($bf,full_tag("STUDENT",3,false,$course->student));
556 fwrite ($bf,full_tag("STUDENTS",3,false,$course->students));
557 fwrite ($bf,full_tag("GUEST",3,false,$course->guest));
558 fwrite ($bf,full_tag("STARTDATE",3,false,$course->startdate));
559 fwrite ($bf,full_tag("NUMSECTIONS",3,false,$course->numsections));
560 fwrite ($bf,full_tag("SHOWRECENT",3,false,$course->showrecent));
561 fwrite ($bf,full_tag("MAXBYTES",3,false,$course->maxbytes));
562 fwrite ($bf,full_tag("SHOWREPORTS",3,false,$course->showreports));
563 fwrite ($bf,full_tag("GROUPMODE",3,false,$course->groupmode));
564 fwrite ($bf,full_tag("GROUPMODEFORCE",3,false,$course->groupmodeforce));
565 fwrite ($bf,full_tag("LANG",3,false,$course->lang));
566 fwrite ($bf,full_tag("MARKER",3,false,$course->marker));
567 fwrite ($bf,full_tag("VISIBLE",3,false,$course->visible));
568 fwrite ($bf,full_tag("TIMECREATED",3,false,$course->timecreated));
569 $status = fwrite ($bf,full_tag("TIMEMODIFIED",3,false,$course->timemodified));
570 //Print header end
571 fwrite ($bf,end_tag("HEADER",2,true));
572 } else {
573 $status = false;
576 return $status;
579 //Prints course's end tag
580 function backup_course_end ($bf,$preferences) {
582 //Course end tag
583 $status = fwrite ($bf,end_tag("COURSE",1,true));
585 return $status;
589 //Prints course's sections info (table course_sections)
590 function backup_course_sections ($bf,$preferences) {
592 global $CFG;
594 $status = true;
597 //Get info from sections
598 $section=false;
599 if ($sections = get_records("course_sections","course",$preferences->backup_course,"section")) {
600 //Section open tag
601 fwrite ($bf,start_tag("SECTIONS",2,true));
602 //Iterate over every section (ordered by section)
603 foreach ($sections as $section) {
604 //Begin Section
605 fwrite ($bf,start_tag("SECTION",3,true));
606 fwrite ($bf,full_tag("ID",4,false,$section->id));
607 fwrite ($bf,full_tag("NUMBER",4,false,$section->section));
608 fwrite ($bf,full_tag("SUMMARY",4,false,$section->summary));
609 fwrite ($bf,full_tag("VISIBLE",4,false,$section->visible));
610 //Now print the mods in section
611 backup_course_modules ($bf,$preferences,$section);
612 //End section
613 fwrite ($bf,end_tag("SECTION",3,true));
615 //Section close tag
616 $status = fwrite ($bf,end_tag("SECTIONS",2,true));
619 return $status;
623 //Prints course's modules info (table course_modules)
624 //Only for selected mods in preferences
625 function backup_course_modules ($bf,$preferences,$section) {
627 global $CFG;
629 $status = true;
631 $first_record = true;
633 //Now print the mods in section
634 //Extracts mod id from sequence
635 $tok = strtok($section->sequence,",");
636 while ($tok) {
637 //Get module's type
638 $moduletype = get_module_type ($preferences->backup_course,$tok);
639 //Check if we've selected to backup that type
640 if ($moduletype and $preferences->mods[$moduletype]->backup) {
641 $selected = true;
642 } else {
643 $selected = false;
646 if ($selected) {
647 //Gets course_module data from db
648 $course_module = get_records ("course_modules","id",$tok);
649 //If it's the first, pring MODS tag
650 if ($first_record) {
651 fwrite ($bf,start_tag("MODS",4,true));
652 $first_record = false;
654 //Print mod info from course_modules
655 fwrite ($bf,start_tag("MOD",5,true));
656 //Save neccesary info to backup_ids
657 fwrite ($bf,full_tag("ID",6,false,$tok));
658 fwrite ($bf,full_tag("TYPE",6,false,$moduletype));
659 fwrite ($bf,full_tag("INSTANCE",6,false,$course_module[$tok]->instance));
660 fwrite ($bf,full_tag("ADDED",6,false,$course_module[$tok]->added));
661 fwrite ($bf,full_tag("DELETED",6,false,$course_module[$tok]->deleted));
662 fwrite ($bf,full_tag("SCORE",6,false,$course_module[$tok]->score));
663 fwrite ($bf,full_tag("INDENT",6,false,$course_module[$tok]->indent));
664 fwrite ($bf,full_tag("VISIBLE",6,false,$course_module[$tok]->visible));
665 fwrite ($bf,full_tag("GROUPMODE",6,false,$course_module[$tok]->groupmode));
666 fwrite ($bf,end_tag("MOD",5,true));
668 //check for next
669 $tok = strtok(",");
672 //Si ha habido modulos, final de MODS
673 if (!$first_record) {
674 $status =fwrite ($bf,end_tag("MODS",4,true));
677 return $status;
680 //Print users to xml
681 //Only users previously calculated in backup_ids will output
683 function backup_user_info ($bf,$preferences) {
685 global $CFG;
687 $status = true;
689 $users = get_records_sql("SELECT u.old_id, u.table_name,u.info
690 FROM {$CFG->prefix}backup_ids u
691 WHERE u.backup_code = '$preferences->backup_unique_code' AND
692 u.table_name = 'user'");
694 //If we have users to backup
695 if ($users) {
696 //Begin Users tag
697 fwrite ($bf,start_tag("USERS",2,true));
698 $counter = 0;
699 //With every user
700 foreach ($users as $user) {
701 //Get user data from table
702 $user_data = get_record("user","id",$user->old_id);
703 //Begin User tag
704 fwrite ($bf,start_tag("USER",3,true));
705 //Output all user data
706 fwrite ($bf,full_tag("ID",4,false,$user_data->id));
707 fwrite ($bf,full_tag("CONFIRMED",4,false,$user_data->confirmed));
708 fwrite ($bf,full_tag("DELETED",4,false,$user_data->deleted));
709 fwrite ($bf,full_tag("USERNAME",4,false,$user_data->username));
710 fwrite ($bf,full_tag("PASSWORD",4,false,$user_data->password));
711 fwrite ($bf,full_tag("IDNUMBER",4,false,$user_data->idnumber));
712 fwrite ($bf,full_tag("FIRSTNAME",4,false,$user_data->firstname));
713 fwrite ($bf,full_tag("LASTNAME",4,false,$user_data->lastname));
714 fwrite ($bf,full_tag("EMAIL",4,false,$user_data->email));
715 fwrite ($bf,full_tag("EMAILSTOP",4,false,$user_data->emailstop));
716 fwrite ($bf,full_tag("ICQ",4,false,$user_data->icq));
717 fwrite ($bf,full_tag("PHONE1",4,false,$user_data->phone1));
718 fwrite ($bf,full_tag("PHONE2",4,false,$user_data->phone2));
719 fwrite ($bf,full_tag("INSTITUTION",4,false,$user_data->institution));
720 fwrite ($bf,full_tag("DEPARTMENT",4,false,$user_data->department));
721 fwrite ($bf,full_tag("ADDRESS",4,false,$user_data->address));
722 fwrite ($bf,full_tag("CITY",4,false,$user_data->city));
723 fwrite ($bf,full_tag("COUNTRY",4,false,$user_data->country));
724 fwrite ($bf,full_tag("LANG",4,false,$user_data->lang));
725 fwrite ($bf,full_tag("TIMEZONE",4,false,$user_data->timezone));
726 fwrite ($bf,full_tag("FIRSTACCESS",4,false,$user_data->firstaccess));
727 fwrite ($bf,full_tag("LASTACCESS",4,false,$user_data->lastaccess));
728 fwrite ($bf,full_tag("LASTLOGIN",4,false,$user_data->lastlogin));
729 fwrite ($bf,full_tag("CURRENTLOGIN",4,false,$user_data->currentlogin));
730 fwrite ($bf,full_tag("LASTIP",4,false,$user_data->lastIP));
731 fwrite ($bf,full_tag("SECRET",4,false,$user_data->secret));
732 fwrite ($bf,full_tag("PICTURE",4,false,$user_data->picture));
733 fwrite ($bf,full_tag("URL",4,false,$user_data->url));
734 fwrite ($bf,full_tag("DESCRIPTION",4,false,$user_data->description));
735 fwrite ($bf,full_tag("MAILFORMAT",4,false,$user_data->mailformat));
736 fwrite ($bf,full_tag("MAILDISPLAY",4,false,$user_data->maildisplay));
737 fwrite ($bf,full_tag("HTMLEDITOR",4,false,$user_data->htmleditor));
738 fwrite ($bf,full_tag("AUTOSUBSCRIBE",4,false,$user_data->autosubscribe));
739 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$user_data->timemodified));
741 //Output every user role (with its associated info)
742 $user->isadmin = strpos($user->info,"admin");
743 $user->iscoursecreator = strpos($user->info,"coursecreator");
744 $user->isteacher = strpos($user->info,"teacher");
745 $user->isstudent = strpos($user->info,"student");
746 $user->isneeded = strpos($user->info,"needed");
747 if ($user->isadmin!==false or
748 $user->iscoursecreator!==false or
749 $user->isteacher!==false or
750 $user->isstudent!==false or
751 $user->isneeded!==false) {
752 //Begin ROLES tag
753 fwrite ($bf,start_tag("ROLES",4,true));
754 //PRINT ROLE INFO
755 //Admins
756 if ($user->isadmin!==false) {
757 //Print ROLE start
758 fwrite ($bf,start_tag("ROLE",5,true));
759 //Print Role info
760 fwrite ($bf,full_tag("TYPE",6,false,"admin"));
761 //Print ROLE end
762 fwrite ($bf,end_tag("ROLE",5,true));
764 //CourseCreator
765 if ($user->iscoursecreator!==false) {
766 //Print ROLE start
767 fwrite ($bf,start_tag("ROLE",5,true));
768 //Print Role info
769 fwrite ($bf,full_tag("TYPE",6,false,"coursecreator"));
770 //Print ROLE end
771 fwrite ($bf,end_tag("ROLE",5,true));
773 //Teacher
774 if ($user->isteacher!==false) {
775 //Print ROLE start
776 fwrite ($bf,start_tag("ROLE",5,true));
777 //Print Role info
778 fwrite ($bf,full_tag("TYPE",6,false,"teacher"));
779 //Get specific info for teachers
780 $tea = get_record("user_teachers","userid",$user->old_id,"course",$preferences->backup_course);
781 fwrite ($bf,full_tag("AUTHORITY",6,false,$tea->authority));
782 fwrite ($bf,full_tag("TEA_ROLE",6,false,$tea->role));
783 fwrite ($bf,full_tag("EDITALL",6,false,$tea->editall));
784 fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$tea->timemodified));
785 fwrite ($bf,full_tag("TIMEACCESS",6,false,$tea->timeaccess));
786 //Print ROLE end
787 fwrite ($bf,end_tag("ROLE",5,true));
789 //Student
790 if ($user->isstudent!==false) {
791 //Print ROLE start
792 fwrite ($bf,start_tag("ROLE",5,true));
793 //Print Role info
794 fwrite ($bf,full_tag("TYPE",6,false,"student"));
795 //Get specific info for students
796 $stu = get_record("user_students","userid",$user->old_id,"course",$preferences->backup_course);
797 fwrite ($bf,full_tag("TIMESTART",6,false,$stu->timestart));
798 fwrite ($bf,full_tag("TIMEEND",6,false,$stu->timeend));
799 fwrite ($bf,full_tag("TIME",6,false,$stu->time));
800 fwrite ($bf,full_tag("TIMEACCESS",6,false,$stu->timeaccess));
801 //Print ROLE end
802 fwrite ($bf,end_tag("ROLE",5,true));
804 //Needed
805 if ($user->isneeded!==false) {
806 //Print ROLE start
807 fwrite ($bf,start_tag("ROLE",5,true));
808 //Print Role info
809 fwrite ($bf,full_tag("TYPE",6,false,"needed"));
810 //Print ROLE end
811 fwrite ($bf,end_tag("ROLE",5,true));
814 //End ROLES tag
815 fwrite ($bf,end_tag("ROLES",4,true));
817 //Check if we have user_preferences to backup
818 if ($preferences_data = get_records("user_preferences","userid",$user->old_id)) {
819 //Start USER_PREFERENCES tag
820 fwrite ($bf,start_tag("USER_PREFERENCES",4,true));
821 //Write each user_preference
822 foreach ($preferences_data as $user_preference) {
823 fwrite ($bf,start_tag("USER_PREFERENCE",5,true));
824 fwrite ($bf,full_tag("NAME",6,false,$user_preference->name));
825 fwrite ($bf,full_tag("VALUE",6,false,$user_preference->value));
826 fwrite ($bf,end_tag("USER_PREFERENCE",5,true));
828 //End USER_PREFERENCES tag
829 fwrite ($bf,end_tag("USER_PREFERENCES",4,true));
833 //End User tag
834 fwrite ($bf,end_tag("USER",3,true));
835 //Do some output
836 $counter++;
837 if ($counter % 10 == 0) {
838 echo ".";
839 if ($counter % 200 == 0) {
840 echo "<br>";
842 backup_flush(300);
845 //End Users tag
846 fwrite ($bf,end_tag("USERS",2,true));
847 } else {
848 // There aren't any users.
849 $status = true;
852 return $status;
855 //Backup log info (time ordered)
856 function backup_log_info($bf,$preferences) {
858 global $CFG;
860 //Number of records to get in every chunk
861 $recordset_size = 1000;
863 $status = true;
865 //Counter, points to current record
866 $counter = 0;
868 //Count records
869 $count_logs = count_records("log","course",$preferences->backup_course);
871 //Pring logs header
872 if ($count_logs > 0 ) {
873 fwrite ($bf,start_tag("LOGS",2,true));
875 while ($counter < $count_logs) {
876 //Get a chunk of records
877 $logs = get_records ("log","course",$preferences->backup_course,"time","*",$counter,$recordset_size);
879 //We have logs
880 if ($logs) {
881 //Iterate
882 foreach ($logs as $log) {
883 //See if it is a valid module to backup
884 if ($log->module == "course" or
885 $log->module == "user" or
886 $preferences->mods[$log->module]->backup == 1) {
887 //Begin log tag
888 fwrite ($bf,start_tag("LOG",3,true));
890 //Output log tag
891 fwrite ($bf,full_tag("ID",4,false,$log->id));
892 fwrite ($bf,full_tag("TIME",4,false,$log->time));
893 fwrite ($bf,full_tag("USERID",4,false,$log->userid));
894 fwrite ($bf,full_tag("IP",4,false,$log->ip));
895 fwrite ($bf,full_tag("MODULE",4,false,$log->module));
896 fwrite ($bf,full_tag("CMID",4,false,$log->cmid));
897 fwrite ($bf,full_tag("ACTION",4,false,$log->action));
898 fwrite ($bf,full_tag("URL",4,false,$log->url));
899 fwrite ($bf,full_tag("INFO",4,false,$log->info));
901 //End log tag
902 fwrite ($bf,end_tag("LOG",3,true));
904 //Do some output
905 $counter++;
906 if ($counter % 10 == 0) {
907 echo ".";
908 if ($counter % 200 == 0) {
909 echo "<br>";
911 backup_flush(300);
916 //End logs tag
917 if ($count_logs > 0 ) {
918 $status = fwrite ($bf,end_tag("LOGS",2,true));
920 return $status;
924 //Backup scales info (common and course scales)
925 function backup_scales_info($bf,$preferences) {
927 global $CFG;
929 $status = true;
931 //Counter, points to current record
932 $counter = 0;
934 //Get scales (common and course scales)
935 $scales = get_records_sql("SELECT id, courseid, userid, name, scale, description, timemodified
936 FROM {$CFG->prefix}scale
937 WHERE courseid = '0' or courseid = $preferences->backup_course");
939 //Pring scales header
940 if ($scales) {
941 //Pring scales header
942 fwrite ($bf,start_tag("SCALES",2,true));
943 //Iterate
944 foreach ($scales as $scale) {
945 //Begin scale tag
946 fwrite ($bf,start_tag("SCALE",3,true));
947 //Output scale tag
948 fwrite ($bf,full_tag("ID",4,false,$scale->id));
949 fwrite ($bf,full_tag("COURSEID",4,false,$scale->courseid));
950 fwrite ($bf,full_tag("USERID",4,false,$scale->userid));
951 fwrite ($bf,full_tag("NAME",4,false,$scale->name));
952 fwrite ($bf,full_tag("SCALETEXT",4,false,$scale->scale));
953 fwrite ($bf,full_tag("DESCRIPTION",4,false,$scale->description));
954 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$scale->timemodified));
955 //End scale tag
956 fwrite ($bf,end_tag("SCALE",3,true));
958 //End scales tag
959 $status = fwrite ($bf,end_tag("SCALES",2,true));
961 return $status;
964 //Backup events info (course events)
965 function backup_events_info($bf,$preferences) {
967 global $CFG;
969 $status = true;
971 //Counter, points to current record
972 $counter = 0;
974 //Get events (course events)
975 $events = get_records_select("event","courseid='$preferences->backup_course' AND instance='0'","id");
977 //Pring events header
978 if ($events) {
979 //Pring events header
980 fwrite ($bf,start_tag("EVENTS",2,true));
981 //Iterate
982 foreach ($events as $event) {
983 //Begin event tag
984 fwrite ($bf,start_tag("EVENT",3,true));
985 //Output event tag
986 fwrite ($bf,full_tag("ID",4,false,$event->id));
987 fwrite ($bf,full_tag("NAME",4,false,$event->name));
988 fwrite ($bf,full_tag("DESCRIPTION",4,false,$event->description));
989 fwrite ($bf,full_tag("GROUPID",4,false,$event->groupid));
990 fwrite ($bf,full_tag("USERID",4,false,$event->userid));
991 fwrite ($bf,full_tag("EVENTTYPE",4,false,$event->eventtype));
992 fwrite ($bf,full_tag("TIMESTART",4,false,$event->timestart));
993 fwrite ($bf,full_tag("TIMEDURATION",4,false,$event->timeduration));
994 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$event->timemodified));
995 //End event tag
996 fwrite ($bf,end_tag("EVENT",3,true));
998 //End events tag
999 $status = fwrite ($bf,end_tag("EVENTS",2,true));
1001 return $status;
1004 //Backup groups info
1005 function backup_groups_info($bf,$preferences) {
1007 global $CFG;
1009 $status = true;
1010 $status2 = true;
1012 //Get groups
1013 $groups = get_records("groups","courseid",$preferences->backup_course);
1015 //Pring groups header
1016 if ($groups) {
1017 //Pring groups header
1018 fwrite ($bf,start_tag("GROUPS",2,true));
1019 //Iterate
1020 foreach ($groups as $group) {
1021 //Begin group tag
1022 fwrite ($bf,start_tag("GROUP",3,true));
1023 //Output group contents
1024 fwrite ($bf,full_tag("ID",4,false,$group->id));
1025 fwrite ($bf,full_tag("COURSEID",4,false,$group->courseid));
1026 fwrite ($bf,full_tag("NAME",4,false,$group->name));
1027 fwrite ($bf,full_tag("DESCRIPTION",4,false,$group->description));
1028 fwrite ($bf,full_tag("LANG",4,false,$group->lang));
1029 fwrite ($bf,full_tag("PICTURE",4,false,$group->picture));
1030 fwrite ($bf,full_tag("HIDEPICTURE",4,false,$group->hidepicture));
1031 fwrite ($bf,full_tag("TIMECREATED",4,false,$group->timecreated));
1032 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$group->timemodified));
1034 //Now, backup groups_members
1035 $status2 = backup_groups_members_info($bf,$preferences,$group->id);
1037 //End group tag
1038 fwrite ($bf,end_tag("GROUP",3,true));
1040 //End groups tag
1041 $status = fwrite ($bf,end_tag("GROUPS",2,true));
1043 return ($status && $status2);
1046 //Backup groups_members info
1047 function backup_groups_members_info($bf,$preferences,$groupid) {
1049 global $CFG;
1051 $status = true;
1053 //Get groups_members
1054 $groups_members = get_records("groups_members","groupid",$groupid);
1056 //Pring groups_members header
1057 if ($groups_members) {
1058 //Pring groups_members header
1059 fwrite ($bf,start_tag("MEMBERS",4,true));
1060 //Iterate
1061 foreach ($groups_members as $group_member) {
1062 //Begin group_member tag
1063 fwrite ($bf,start_tag("MEMBER",5,true));
1064 //Output group_member contents
1065 fwrite ($bf,full_tag("USERID",6,false,$group_member->userid));
1066 fwrite ($bf,full_tag("TIMEADDED",6,false,$group_member->timeadded));
1067 //End group_member tag
1068 fwrite ($bf,end_tag("MEMBER",5,true));
1070 //End groups_members tag
1071 $status = fwrite ($bf,end_tag("MEMBERS",4,true));
1073 return $status;
1076 //Start the modules tag
1077 function backup_modules_start ($bf,$preferences) {
1079 return fwrite ($bf,start_tag("MODULES",2,true));
1082 //End the modules tag
1083 function backup_modules_end ($bf,$preferences) {
1085 return fwrite ($bf,end_tag("MODULES",2,true));
1088 //This function makes all the necesary calls to every mod
1089 //to export itself and its files !!!
1090 function backup_module($bf,$preferences,$module) {
1092 global $CFG;
1094 $status = true;
1096 //First, re-check if necessary functions exists
1097 $modbackup = $module."_backup_mods";
1098 if (function_exists($modbackup)) {
1099 //Call the function
1100 $status = $modbackup($bf,$preferences);
1101 } else {
1102 //Something was wrong. Function should exist.
1103 $status = false;
1106 return $status;
1110 //This function copies all the needed files under the "users" directory to the "user_files"
1111 //directory under temp/backup
1112 function backup_copy_user_files ($preferences) {
1114 global $CFG;
1116 $status = true;
1118 //First we check to "user_files" exists and create it as necessary
1119 //in temp/backup/$backup_code dir
1120 $status = check_and_create_user_files_dir($preferences->backup_unique_code);
1122 //Now iterate over directories under "users" to check if that user must be
1123 //copied to backup
1125 $rootdir = $CFG->dataroot."/users";
1126 //Check if directory exists
1127 if (is_dir($rootdir)) {
1128 $list = list_directories ($rootdir);
1129 if ($list) {
1130 //Iterate
1131 foreach ($list as $dir) {
1132 //Look for dir like username in backup_ids
1133 $data = get_record ("backup_ids","backup_code",$preferences->backup_unique_code,
1134 "table_name","user",
1135 "old_id",$dir);
1136 //If exists, copy it
1137 if ($data) {
1138 $status = backup_copy_file($rootdir."/".$dir,
1139 $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/user_files/".$dir);
1144 return $status;
1147 //This function copies all the course files under the course directory (except the moddata
1148 //directory to the "course_files" directory under temp/backup
1149 function backup_copy_course_files ($preferences) {
1151 global $CFG;
1153 $status = true;
1155 //First we check to "course_files" exists and create it as necessary
1156 //in temp/backup/$backup_code dir
1157 $status = check_and_create_course_files_dir($preferences->backup_unique_code);
1159 //Now iterate over files and directories except $CFG->moddata and backupdata to be
1160 //copied to backup
1162 $rootdir = $CFG->dataroot."/".$preferences->backup_course;
1164 $name_moddata = $CFG->moddata;
1165 $name_backupdata = "backupdata";
1166 //Check if directory exists
1167 if (is_dir($rootdir)) {
1168 $list = list_directories_and_files ($rootdir);
1169 if ($list) {
1170 //Iterate
1171 foreach ($list as $dir) {
1172 if ($dir !== $name_moddata and $dir !== $name_backupdata) {
1173 $status = backup_copy_file($rootdir."/".$dir,
1174 $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/course_files/".$dir);
1179 return $status;
1182 //This function creates the zip file containing all the backup info
1183 //moodle.xml, moddata, user_files, course_files.
1184 //The zipped file is created in the backup directory and named with
1185 //the "oficial" name of the backup
1186 //It uses "pclzip" if available or system "zip" (unix only)
1187 function backup_zip ($preferences) {
1189 global $CFG;
1191 $status = true;
1193 //Base dir where everything happens
1194 $basedir = $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code;
1195 //Backup zip file name
1196 $name = $preferences->backup_name;
1197 //List base_dir files and directories
1198 $filelist = list_directories_and_files ($basedir);
1200 if (empty($CFG->zip)) { // Use built-in php-based zip function
1201 //echo "<br>Using pclzip"; //Debug
1202 $files = array();
1203 foreach ($filelist as $file) {
1204 //If directory, append "/"
1205 //Commented. Not needed wit version 2.0 of pclzip !!
1206 //if (is_dir($basedir."/".$file)) {
1207 // $file = $file."/";
1209 //Include into array
1210 //echo "<br>Adding file/dir ".$file; //Debug
1211 $files[] = $basedir."/".$file;
1213 include_once("$CFG->dirroot/lib/pclzip/pclzip.lib.php");
1214 //include_once("$CFG->dirroot/lib/pclzip/pclerror.lib.php"); //Debug
1215 //include_once("$CFG->dirroot/lib/pclzip/pcltrace.lib.php"); //Debug
1216 //PclTraceOn(2); //Debug
1217 $archive = new PclZip("$basedir/$name");
1218 if (($list = $archive->create($files,PCLZIP_OPT_REMOVE_PATH,$basedir)) == 0) {
1219 error($archive->errorInfo(true));
1220 $status = false;
1222 //PclTraceDisplay(); //Debug
1223 //PclTraceOff(); //Debug
1224 } else { // Use external zip program
1225 //echo "<br>Using external zip"; //Debug
1226 $files = "";
1227 foreach ($filelist as $file) {
1228 $files .= basename($file);
1229 $files .= " ";
1231 $command = "cd $basedir ; $CFG->zip -r $name $files";
1232 //echo "<br>Executing command: ".$command; //Debug
1233 $status = Exec($command);
1236 //echo "<br>Status: ".$status; //Debug
1237 return $status;
1241 //This function copies the final zip to the course dir
1242 function copy_zip_to_course_dir ($preferences) {
1244 global $CFG;
1246 $status = true;
1248 //Define zip location (from)
1249 $from_zip_file = $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/".$preferences->backup_name;
1251 //Initialise $to_zip_file
1252 $to_zip_file="";
1254 //If $preferences->backup_destination isn't empty, then copy to custom directory
1255 if (!empty($preferences->backup_destination)) {
1256 $to_zip_file = $preferences->backup_destination."/".$preferences->backup_name;
1257 } else {
1258 //Define zip destination (course dir)
1259 $to_zip_file = $CFG->dataroot."/".$preferences->backup_course;
1261 //echo "<p>From: ".$from_zip_file."<br>"; //Debug
1263 //echo "<p>Checking: ".$to_zip_file."<br>"; //Debug
1265 //Checks course dir exists
1266 $status = check_dir_exists($to_zip_file,true);
1268 //Define zip destination (backup dir)
1269 $to_zip_file = $to_zip_file."/backupdata";
1271 //echo "<p>Checking: ".$to_zip_file."<br>"; //Debug
1273 //Checks backup dir exists
1274 $status = check_dir_exists($to_zip_file,true);
1276 //Define zip destination (zip file)
1277 $to_zip_file = $to_zip_file."/".$preferences->backup_name;
1280 //echo "<p>To: ".$to_zip_file."<br>"; //Debug
1282 //Copy zip file
1283 if ($status) {
1284 $status = backup_copy_file ($from_zip_file,$to_zip_file);
1287 return $status;