Added support for timestart and timeend (user_teachers table) and
[moodle.git] / backup / backuplib.php
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;
20     }
21     
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;
29     }
30  
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)
36         //              2-->none
38         global $CFG;
39         global $db;
41         $count_users = 0;
43         //If we've selected none, simply return 0
44         if ($backup_users == 0 or $backup_users == 1) {
45         
46             //Calculate needed users (calling every xxxx_get_participants function + scales users)
47             $needed_users = backup_get_needed_users($course);
49             //Calculate enrolled users (students + teachers)
50             $enrolled_users = backup_get_enrolled_users($course);
52             //Calculate all users (every record in users table)
53             $all_users = backup_get_all_users();
55             //Calculate course users (needed + enrolled)
56             //First, needed
57             $course_users = $needed_users;
58         
59             //Now, enrolled
60             if ($enrolled_users) {
61                 foreach ($enrolled_users as $enrolled_user) {
62                     $course_users[$enrolled_user->id]->id = $enrolled_user->id; 
63                 }
64             }
65        
66             //Now, depending of parameters, create $backupable_users
67             if ($backup_users == 0) {
68                 $backupable_users = $all_users;
69             } else {
70                 $backupable_users = $course_users;
71             }
73             //If we have backupable users
74             if ($backupable_users) {
75                 //Iterate over users putting their roles
76                 foreach ($backupable_users as $backupable_user) {
77                     $backupable_user->info = "";
78                     //Is Admin in tables (not is_admin()) !!
79                     if (record_exists("user_admins","userid",$backupable_user->id)) {
80                         $backupable_user->info .= "admin";
81                     }
82                     //Is Course Creator in tables (not is_coursecreator()) !!
83                     if (record_exists("user_coursecreators","userid",$backupable_user->id)) {
84                         $backupable_user->info .= "coursecreator";
85                     }
86                     //Is Teacher in tables (not is_teacher()) !!
87                     if (record_exists("user_teachers","course",$course,"userid",$backupable_user->id)) {
88                         $backupable_user->info .= "teacher";
89                     }
90                     //Is Student in tables (not is_student()) !!
91                     if (record_exists("user_students","course",$course,"userid",$backupable_user->id)) {
92                         $backupable_user->info .= "student";
93                     }
94                     //Is needed user (exists in needed_users) 
95                     if (isset($needed_users[$backupable_user->id])) {
96                         $backupable_user->info .= "needed";
97                     }
98                     //Now create the backup_id record
99                     $backupids_rec->backup_code = $backup_unique_code;
100                     $backupids_rec->table_name = "user";
101                     $backupids_rec->old_id = $backupable_user->id;
102                     $backupids_rec->info = $backupable_user->info;
103         
104                     //Insert the record id. backup_users decide it.
105                     //When all users
106                     $status = insert_record("backup_ids",$backupids_rec,false,"backup_code");
107                     $count_users++;
108                 }
109                 //Do some output     
110                 backup_flush(30);
111             }
112         }
114         //Prepare Info
115         //Gets the user data
116         $info[0][0] = get_string("users");
117         $info[0][1] = $count_users;
119         return $info;
120     }
122     //Returns every needed user (participant) in a course
123     //It uses the xxxx_get_participants() function
124     //plus users needed to backup scales.
125     //WARNING: It returns only NEEDED users, not every 
126     //   every student and teacher in the course, so it
127     //must be merged with backup_get_enrrolled_users !!
129     function backup_get_needed_users ($courseid) {
130         
131         global $CFG, $THEME;
133         $result = false;
135         $course_modules = get_records_sql ("SELECT cm.id, m.name, cm.instance
136                                             FROM {$CFG->prefix}modules m,
137                                                  {$CFG->prefix}course_modules cm
138                                             WHERE m.id = cm.module and
139                                                   cm.course = '$courseid'");
141         if ($course_modules) {
142             //Iterate over each module
143             foreach ($course_modules as $course_module) {
144                 $modlib = "$CFG->dirroot/mod/$course_module->name/lib.php";
145                 $modgetparticipants = $course_module->name."_get_participants";
146                 if (file_exists($modlib)) {
147                     include_once($modlib);
148                     if (function_exists($modgetparticipants)) {
149                         $module_participants = $modgetparticipants($course_module->instance);
150                         //Add them to result
151                         if ($module_participants) {
152                             foreach ($module_participants as $module_participant) {
153                                 $result[$module_participant->id]->id = $module_participant->id; 
154                             }
155                         }
156                     }
157                  }            
158             }
159         }
161         //Now, add scales users (from site and course scales)
162         //Get users
163         $scaleusers = get_records_sql("SELECT DISTINCT userid,userid
164                                        FROM {$CFG->prefix}scale
165                                        WHERE courseid = '0' or courseid = '$courseid'");
166         //Add scale users to results
167         if ($scaleusers) {
168             foreach ($scaleusers as $scaleuser) {
169                 //If userid != 0
170                 if ($scaleuser->userid != 0) {
171                     $result[$scaleuser->userid]->id = $scaleuser->userid;
172                 }
173             }
174         }
175     
176         return $result;
178     }
180     //Returns every enrolled user (student and teacher) in a course
182     function backup_get_enrolled_users ($courseid) {
184         global $CFG;
186         $result = false;
187         
188         //Get teachers
189         $teachers = get_records_sql("SELECT DISTINCT userid,userid
190                      FROM {$CFG->prefix}user_teachers
191                      WHERE course = '$courseid'");
192         //Get students
193         $students = get_records_sql("SELECT DISTINCT userid,userid
194                      FROM {$CFG->prefix}user_students
195                      WHERE course = '$courseid'");
196         //Add teachers
197         if ($teachers) {
198             foreach ($teachers as $teacher) {
199                 $result[$teacher->userid]->id = $teacher->userid;
200             }
201         }
202         //Add students
203         if ($students) {
204             foreach ($students as $student) {
205                 $result[$student->userid]->id = $student->userid;
206             }
207         }
209         return $result;
210     }
212     //Returns all users (every record in users table)
214     function backup_get_all_users() {
216         global $CFG;
218         $result = false;
220         //Get users
221         $users = get_records_sql("SELECT DISTINCT id,id
222                                   FROM {$CFG->prefix}user");
223         //Add users
224         if ($users) {
225             foreach ($users as $user) {
226                 $result[$user->id]->id = $user->id;
227             }
228         }
230         return $result;
231     }
233     //Calculate the number of log entries to backup
234     //Return an array of info (name,value)
235     function log_check_backup($course) {
237         global $CFG;
239         //Now execute the count
240         $ids = count_records("log","course",$course);
242         //Gets the user data
243         $info[0][0] = get_string("logs");
244         if ($ids) {
245             $info[0][1] = $ids;
246         } else {
247             $info[0][1] = 0;
248         }
250         return $info;
251     }
253     //Calculate the number of user files to backup
254     //Under $CFG->dataroot/users
255     //and put them (their path) in backup_ids
256     //Return an array of info (name,value)
257     function user_files_check_backup($course,$backup_unique_code) {
259         global $CFG;
261         $rootdir = $CFG->dataroot."/users";
262         //Check if directory exists
263         if (is_dir($rootdir)) {
264             $coursedirs = get_directory_list($rootdir);
265             foreach ($coursedirs as $dir) {
266                 //Extracts user id from file path
267                 $tok = strtok($dir,"/");
268                 if ($tok) {
269                    $userid = $tok;
270                 } else {
271                    $tok = "";
272                 }
273                 //Look it is a backupable user
274                 $data = get_record ("backup_ids","backup_code","$backup_unique_code",
275                                                  "table_name","user",
276                                                  "old_id",$userid);
277                 if ($data) {
278                     //Insert them into backup_files
279                     $status = execute_sql("INSERT INTO {$CFG->prefix}backup_files
280                                                (backup_code, file_type, path, old_id)
281                                            VALUES
282                                                ('$backup_unique_code','user','$dir','$userid')",false);
283                 }
284                 //Do some output
285                 backup_flush(30);
286             }
287         }
289         //Now execute the select
290         $ids = get_records_sql("SELECT DISTINCT b.path, b.old_id
291                                 FROM {$CFG->prefix}backup_files b
292                                 WHERE backup_code = '$backup_unique_code' AND
293                                       file_type = 'user'");
294         //Gets the user data
295         $info[0][0] = get_string("files");
296         if ($ids) {
297             $info[0][1] = count($ids);
298         } else {
299             $info[0][1] = 0;
300         }
302         return $info;  
303     }
305     //Calculate the number of course files to backup
306     //under $CFG->dataroot/$course, except $CFG->moddata, and backupdata
307     //and put them (their path) in backup_ids
308     //Return an array of info (name,value)
309     function course_files_check_backup($course,$backup_unique_code) {
311         global $CFG;
313         $rootdir = $CFG->dataroot."/$course";
314         //Check if directory exists
315         if (is_dir($rootdir)) {
316             $coursedirs = get_directory_list($rootdir,$CFG->moddata);
317             $backupdata_dir = "backupdata";
318             foreach ($coursedirs as $dir) {
319                 //Check it isn't backupdata_dir
320                 if (strpos($dir,$backupdata_dir)!==0) {
321                     //Insert them into backup_files
322                     $status = execute_sql("INSERT INTO {$CFG->prefix}backup_files
323                                                   (backup_code, file_type, path)
324                                            VALUES
325                                               ('$backup_unique_code','course','$dir')",false);
326                 }
327             //Do some output
328             backup_flush(30);
329             }
330         }
332         //Now execute the select
333         $ids = get_records_sql("SELECT DISTINCT b.path, b.old_id
334                                 FROM {$CFG->prefix}backup_files b
335                                 WHERE backup_code = '$backup_unique_code' AND
336                                       file_type = 'course'");
337         //Gets the user data
338         $info[0][0] = get_string("files");
339         if ($ids) {
340             $info[0][1] = count($ids);
341         } else {
342             $info[0][1] = 0;
343         }
345         return $info; 
346     }
347    
348     //Function to check and create the needed moddata dir to
349     //save all the mod backup files. We always name it moddata
350     //to be able to restore it, but in restore we check for
351     //$CFG->moddata !!
352     function check_and_create_moddata_dir($backup_unique_code) {
353   
354         global $CFG;
356             $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/moddata",true);
358         return $status;
359     }
361     //Function to check and create the "user_files" dir to
362     //save all the user files we need from "users" dir
363     function check_and_create_user_files_dir($backup_unique_code) {
364  
365         global $CFG;
367             $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/user_files",true);
369         return $status;
370     }
372     //Function to check and create the "course_files" dir to
373     //save all the course files we need from "CFG->datadir/course" dir
374     function check_and_create_course_files_dir($backup_unique_code) {
376         global $CFG;
378             $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/course_files",true);
380         return $status;
381     }
383     //Function to create, open and write header of the xml file
384     function backup_open_xml($backup_unique_code) {
386         global $CFG;
387         
388         $status = true;
390         //Open for writing
392         $file = $CFG->dataroot."/temp/backup/".$backup_unique_code."/moodle.xml";
393         $backup_file = fopen($file,"w");
394         //Writes the header
395         $status = fwrite ($backup_file,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
396         if ($status) {
397             $status = fwrite ($backup_file,start_tag("MOODLE_BACKUP",0,true));
398         }
399         if ($status) {
400             return $backup_file;
401         } else {
402             return false;
403         }
404     }
406     //Close the file
407     function backup_close_xml($backup_file) {
408         $status = fwrite ($backup_file,end_tag("MOODLE_BACKUP",0,true));
409         return fclose($backup_file);
410     }
412     //Return the xml start tag 
413     function start_tag($tag,$level=0,$endline=false) {
414         if ($endline) {
415            $endchar = "\n";
416         } else {
417            $endchar = "";
418         }
419         return str_repeat(" ",$level*2)."<".strtoupper($tag).">".$endchar;
420     }
421     
422     //Return the xml end tag 
423     function end_tag($tag,$level=0,$endline=true) {
424         if ($endline) {
425            $endchar = "\n";
426         } else {
427            $endchar = "";
428         }
429         return str_repeat(" ",$level*2)."</".strtoupper($tag).">".$endchar;
430     }
431     
432     //Return the start tag, the contents and the end tag
433     function full_tag($tag,$level=0,$endline=true,$content,$to_utf=true) {
434         //Here we encode absolute links
435         $content = backup_encode_absolute_links($content);
436         $st = start_tag($tag,$level,$endline);
437         $co="";
438         if ($to_utf) {
439             $co = preg_replace("/\r\n|\r/", "\n", utf8_encode(htmlspecialchars($content)));
440         } else {
441             $co = preg_replace("/\r\n|\r/", "\n", htmlspecialchars($content));
442         }
443         $et = end_tag($tag,0,true);
444         return $st.$co.$et;
445     }
447     //Prints General info about the course
448     //name, moodle_version (internal and release), backup_version, date, info in file...
449     function backup_general_info ($bf,$preferences) {
450     
451         global $CFG;
452         
453         fwrite ($bf,start_tag("INFO",1,true));
455         //The name of the backup
456         fwrite ($bf,full_tag("NAME",2,false,$preferences->backup_name));
457         //The moodle_version
458         fwrite ($bf,full_tag("MOODLE_VERSION",2,false,$preferences->moodle_version));
459         fwrite ($bf,full_tag("MOODLE_RELEASE",2,false,$preferences->moodle_release));
460         //The backup_version
461         fwrite ($bf,full_tag("BACKUP_VERSION",2,false,$preferences->backup_version));
462         fwrite ($bf,full_tag("BACKUP_RELEASE",2,false,$preferences->backup_release));
463         //The date
464         fwrite ($bf,full_tag("DATE",2,false,$preferences->backup_unique_code));
465         //The original site wwwroot
466         fwrite ($bf,full_tag("ORIGINAL_WWWROOT",2,false,$CFG->wwwroot));
467         //Te includes tag
468         fwrite ($bf,start_tag("DETAILS",2,true));
469         //Now, go to mod element of preferences to print its status
470         foreach ($preferences->mods as $element) {
471             //Calculate info
472             $included = "false";
473             $userinfo = "false";
474             if ($element->backup) {
475                 $included = "true";
476                 if ($element->userinfo) {
477                     $userinfo = "true";
478                 }
479             }
480             //Prints the mod start
481             fwrite ($bf,start_tag("MOD",3,true));
482             fwrite ($bf,full_tag("NAME",4,false,$element->name));
483             fwrite ($bf,full_tag("INCLUDED",4,false,$included));
484             fwrite ($bf,full_tag("USERINFO",4,false,$userinfo));
485                  
486             //Print the end
487             fwrite ($bf,end_tag("MOD",3,true));
488         }
489         //The user in backup
490         if ($preferences->backup_users == 1) {
491             fwrite ($bf,full_tag("USERS",3,false,"course"));
492         } else if ($preferences->backup_users == 0) {
493             fwrite ($bf,full_tag("USERS",3,false,"all"));
494         } else {
495             fwrite ($bf,full_tag("USERS",3,false,"none"));
496         }
497         //The logs in backup
498         if ($preferences->backup_logs == 1) {
499             fwrite ($bf,full_tag("LOGS",3,false,"true"));
500         } else {
501             fwrite ($bf,full_tag("LOGS",3,false,"false"));
502         }
503         //The user files
504         if ($preferences->backup_user_files == 1) {
505             fwrite ($bf,full_tag("USERFILES",3,false,"true"));
506         } else {
507             fwrite ($bf,full_tag("USERFILES",3,false,"false"));
508         }
509         //The course files
510         if ($preferences->backup_course_files == 1) {
511             fwrite ($bf,full_tag("COURSEFILES",3,false,"true"));
512         } else {
513             fwrite ($bf,full_tag("COURSEFILES",3,false,"false"));
514         }
516         fwrite ($bf,end_tag("DETAILS",2,true));
519         $status = fwrite ($bf,end_tag("INFO",1,true)); 
521         return $status;
522     }
523     
524     //Prints course's general info (table course)
525     function backup_course_start ($bf,$preferences) {
527         global $CFG;
529         $status = true;
530         
531         //Course open tag
532         fwrite ($bf,start_tag("COURSE",1,true));
533         //Header open tag
534         fwrite ($bf,start_tag("HEADER",2,true));
536         //Get info from course
537         $course=false;
538         if ($courses = get_records("course","id",$preferences->backup_course)) {
539             $course = $courses[$preferences->backup_course];
540         }
541         if ($course) {
542             //Prints course info
543             fwrite ($bf,full_tag("ID",3,false,$course->id));
544             //Obtain the category
545             $category = false;
546             if ($categories = get_records("course_categories","id","$course->category")) {
547                 $category = $categories[$course->category];
548             }
549             if ($category) {
550                 //Prints category info
551                 fwrite ($bf,start_tag("CATEGORY",3,true));
552                 fwrite ($bf,full_tag("ID",4,false,$course->category));
553                 fwrite ($bf,full_tag("NAME",4,false,$category->name));
554                 fwrite ($bf,end_tag("CATEGORY",3,true));
555             }
556             //Continues with the course
557             fwrite ($bf,full_tag("PASSWORD",3,false,$course->password));
558             fwrite ($bf,full_tag("FULLNAME",3,false,$course->fullname));
559             fwrite ($bf,full_tag("SHORTNAME",3,false,$course->shortname));
560             fwrite ($bf,full_tag("IDNUMBER",3,false,$course->idnumber));
561             fwrite ($bf,full_tag("SUMMARY",3,false,$course->summary));
562             fwrite ($bf,full_tag("FORMAT",3,false,$course->format));
563             fwrite ($bf,full_tag("SHOWGRADES",3,false,$course->showgrades));
564             fwrite ($bf,full_tag("BLOCKINFO",3,false,blocks_get_block_names($course->blockinfo)));
565             fwrite ($bf,full_tag("NEWSITEMS",3,false,$course->newsitems));
566             fwrite ($bf,full_tag("TEACHER",3,false,$course->teacher));
567             fwrite ($bf,full_tag("TEACHERS",3,false,$course->teachers));
568             fwrite ($bf,full_tag("STUDENT",3,false,$course->student));
569             fwrite ($bf,full_tag("STUDENTS",3,false,$course->students));
570             fwrite ($bf,full_tag("GUEST",3,false,$course->guest));
571             fwrite ($bf,full_tag("STARTDATE",3,false,$course->startdate));
572             fwrite ($bf,full_tag("NUMSECTIONS",3,false,$course->numsections));
573             //fwrite ($bf,full_tag("SHOWRECENT",3,false,$course->showrecent));    INFO: This is out in 1.3
574             fwrite ($bf,full_tag("MAXBYTES",3,false,$course->maxbytes));
575             fwrite ($bf,full_tag("SHOWREPORTS",3,false,$course->showreports));
576             fwrite ($bf,full_tag("GROUPMODE",3,false,$course->groupmode));
577             fwrite ($bf,full_tag("GROUPMODEFORCE",3,false,$course->groupmodeforce));
578             fwrite ($bf,full_tag("LANG",3,false,$course->lang));
579             fwrite ($bf,full_tag("MARKER",3,false,$course->marker));
580             fwrite ($bf,full_tag("VISIBLE",3,false,$course->visible));
581             fwrite ($bf,full_tag("HIDDENSECTIONS",3,false,$course->hiddensections));
582             fwrite ($bf,full_tag("TIMECREATED",3,false,$course->timecreated));
583             $status = fwrite ($bf,full_tag("TIMEMODIFIED",3,false,$course->timemodified));
584             //Print header end
585             fwrite ($bf,end_tag("HEADER",2,true));
586         } else { 
587            $status = false;
588         } 
590        return $status;
591     }
593     //Prints course's end tag
594     function backup_course_end ($bf,$preferences) {
596         //Course end tag
597         $status = fwrite ($bf,end_tag("COURSE",1,true)); 
598     
599         return $status;
601     }
603     //Prints course's sections info (table course_sections)
604     function backup_course_sections ($bf,$preferences) {
606         global $CFG;
608         $status = true;
611         //Get info from sections
612         $section=false;
613         if ($sections = get_records("course_sections","course",$preferences->backup_course,"section")) {
614             //Section open tag
615             fwrite ($bf,start_tag("SECTIONS",2,true));
616             //Iterate over every section (ordered by section)     
617             foreach ($sections as $section) {
618                 //Begin Section
619                 fwrite ($bf,start_tag("SECTION",3,true));
620                 fwrite ($bf,full_tag("ID",4,false,$section->id));
621                 fwrite ($bf,full_tag("NUMBER",4,false,$section->section));
622                 fwrite ($bf,full_tag("SUMMARY",4,false,$section->summary));
623                 fwrite ($bf,full_tag("VISIBLE",4,false,$section->visible));
624                 //Now print the mods in section 
625                 backup_course_modules ($bf,$preferences,$section);
626                 //End section
627                 fwrite ($bf,end_tag("SECTION",3,true));
628             }
629             //Section close tag
630             $status = fwrite ($bf,end_tag("SECTIONS",2,true));
631         }
633         return $status;
635     }
637     //Prints course's modules info (table course_modules)
638     //Only for selected mods in preferences
639     function backup_course_modules ($bf,$preferences,$section) {
641         global $CFG;
643         $status = true;
645         $first_record = true;
647         //Now print the mods in section
648         //Extracts mod id from sequence
649         $tok = strtok($section->sequence,",");
650         while ($tok) {
651            //Get module's type
652            $moduletype = get_module_type ($preferences->backup_course,$tok);
653            //Check if we've selected to backup that type
654            if ($moduletype and $preferences->mods[$moduletype]->backup) {
655                $selected = true;
656            } else {
657                $selected = false;
658            }
660            if ($selected) {
661                //Gets course_module data from db
662                $course_module = get_records ("course_modules","id",$tok);
663                //If it's the first, pring MODS tag
664                if ($first_record) {
665                    fwrite ($bf,start_tag("MODS",4,true));
666                    $first_record = false;
667                }
668                //Print mod info from course_modules
669                fwrite ($bf,start_tag("MOD",5,true));
670                //Save neccesary info to backup_ids
671                fwrite ($bf,full_tag("ID",6,false,$tok));
672                fwrite ($bf,full_tag("TYPE",6,false,$moduletype));
673                fwrite ($bf,full_tag("INSTANCE",6,false,$course_module[$tok]->instance));
674                fwrite ($bf,full_tag("ADDED",6,false,$course_module[$tok]->added));
675                fwrite ($bf,full_tag("DELETED",6,false,$course_module[$tok]->deleted));
676                fwrite ($bf,full_tag("SCORE",6,false,$course_module[$tok]->score));
677                fwrite ($bf,full_tag("INDENT",6,false,$course_module[$tok]->indent));
678                fwrite ($bf,full_tag("VISIBLE",6,false,$course_module[$tok]->visible));
679                fwrite ($bf,full_tag("GROUPMODE",6,false,$course_module[$tok]->groupmode));
680                fwrite ($bf,end_tag("MOD",5,true));
681             }
682            //check for next
683            $tok = strtok(",");
684         }
686         //Si ha habido modulos, final de MODS
687         if (!$first_record) {
688             $status =fwrite ($bf,end_tag("MODS",4,true));
689         }
691         return $status;
692     }
694     //Print users to xml
695     //Only users previously calculated in backup_ids will output
696     //
697     function backup_user_info ($bf,$preferences) {
698     
699         global $CFG;
701         $status = true;
703         $users = get_records_sql("SELECT u.old_id, u.table_name,u.info
704                               FROM {$CFG->prefix}backup_ids u
705                               WHERE u.backup_code = '$preferences->backup_unique_code' AND
706                                     u.table_name = 'user'");
708         //If we have users to backup
709         if ($users) {
710             //Begin Users tag
711             fwrite ($bf,start_tag("USERS",2,true));
712             $counter = 0;
713             //With every user
714             foreach ($users as $user) {
715                 //Get user data from table
716                 $user_data = get_record("user","id",$user->old_id);
717                 //Begin User tag
718                 fwrite ($bf,start_tag("USER",3,true));
719                 //Output all user data
720                 fwrite ($bf,full_tag("ID",4,false,$user_data->id));
721                 fwrite ($bf,full_tag("CONFIRMED",4,false,$user_data->confirmed));
722                 fwrite ($bf,full_tag("DELETED",4,false,$user_data->deleted));
723                 fwrite ($bf,full_tag("USERNAME",4,false,$user_data->username));
724                 fwrite ($bf,full_tag("PASSWORD",4,false,$user_data->password));
725                 fwrite ($bf,full_tag("IDNUMBER",4,false,$user_data->idnumber));
726                 fwrite ($bf,full_tag("FIRSTNAME",4,false,$user_data->firstname));
727                 fwrite ($bf,full_tag("LASTNAME",4,false,$user_data->lastname));
728                 fwrite ($bf,full_tag("EMAIL",4,false,$user_data->email));
729                 fwrite ($bf,full_tag("EMAILSTOP",4,false,$user_data->emailstop));
730                 fwrite ($bf,full_tag("ICQ",4,false,$user_data->icq));
731                 fwrite ($bf,full_tag("PHONE1",4,false,$user_data->phone1));
732                 fwrite ($bf,full_tag("PHONE2",4,false,$user_data->phone2));
733                 fwrite ($bf,full_tag("INSTITUTION",4,false,$user_data->institution));
734                 fwrite ($bf,full_tag("DEPARTMENT",4,false,$user_data->department));
735                 fwrite ($bf,full_tag("ADDRESS",4,false,$user_data->address));
736                 fwrite ($bf,full_tag("CITY",4,false,$user_data->city));
737                 fwrite ($bf,full_tag("COUNTRY",4,false,$user_data->country));
738                 fwrite ($bf,full_tag("LANG",4,false,$user_data->lang));
739                 fwrite ($bf,full_tag("TIMEZONE",4,false,$user_data->timezone));
740                 fwrite ($bf,full_tag("FIRSTACCESS",4,false,$user_data->firstaccess));
741                 fwrite ($bf,full_tag("LASTACCESS",4,false,$user_data->lastaccess));
742                 fwrite ($bf,full_tag("LASTLOGIN",4,false,$user_data->lastlogin));
743                 fwrite ($bf,full_tag("CURRENTLOGIN",4,false,$user_data->currentlogin));
744                 fwrite ($bf,full_tag("LASTIP",4,false,$user_data->lastIP));
745                 fwrite ($bf,full_tag("SECRET",4,false,$user_data->secret));
746                 fwrite ($bf,full_tag("PICTURE",4,false,$user_data->picture));
747                 fwrite ($bf,full_tag("URL",4,false,$user_data->url));
748                 fwrite ($bf,full_tag("DESCRIPTION",4,false,$user_data->description));
749                 fwrite ($bf,full_tag("MAILFORMAT",4,false,$user_data->mailformat));
750                 fwrite ($bf,full_tag("MAILDISPLAY",4,false,$user_data->maildisplay));
751                 fwrite ($bf,full_tag("HTMLEDITOR",4,false,$user_data->htmleditor));
752                 fwrite ($bf,full_tag("AUTOSUBSCRIBE",4,false,$user_data->autosubscribe));
753                 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$user_data->timemodified));
755                 //Output every user role (with its associated info) 
756                 $user->isadmin = strpos($user->info,"admin");
757                 $user->iscoursecreator = strpos($user->info,"coursecreator");
758                 $user->isteacher = strpos($user->info,"teacher");
759                 $user->isstudent = strpos($user->info,"student");
760                 $user->isneeded = strpos($user->info,"needed");
761                 if ($user->isadmin!==false or 
762                     $user->iscoursecreator!==false or 
763                     $user->isteacher!==false or 
764                     $user->isstudent!==false or
765                     $user->isneeded!==false) {
766                     //Begin ROLES tag
767                     fwrite ($bf,start_tag("ROLES",4,true));
768                     //PRINT ROLE INFO
769                     //Admins
770                     if ($user->isadmin!==false) {
771                         //Print ROLE start
772                         fwrite ($bf,start_tag("ROLE",5,true));
773                         //Print Role info
774                         fwrite ($bf,full_tag("TYPE",6,false,"admin"));
775                         //Print ROLE end
776                         fwrite ($bf,end_tag("ROLE",5,true));
777                     }
778                     //CourseCreator
779                     if ($user->iscoursecreator!==false) {
780                         //Print ROLE start 
781                         fwrite ($bf,start_tag("ROLE",5,true)); 
782                         //Print Role info 
783                         fwrite ($bf,full_tag("TYPE",6,false,"coursecreator"));
784                         //Print ROLE end
785                         fwrite ($bf,end_tag("ROLE",5,true));   
786                     }
787                     //Teacher
788                     if ($user->isteacher!==false) {
789                         //Print ROLE start 
790                         fwrite ($bf,start_tag("ROLE",5,true)); 
791                         //Print Role info 
792                         fwrite ($bf,full_tag("TYPE",6,false,"teacher"));
793                         //Get specific info for teachers
794                         $tea = get_record("user_teachers","userid",$user->old_id,"course",$preferences->backup_course);
795                         fwrite ($bf,full_tag("AUTHORITY",6,false,$tea->authority));
796                         fwrite ($bf,full_tag("TEA_ROLE",6,false,$tea->role));
797                         fwrite ($bf,full_tag("EDITALL",6,false,$tea->editall));
798                         fwrite ($bf,full_tag("TIMESTART",6,false,$tea->timestart));
799                         fwrite ($bf,full_tag("TIMEEND",6,false,$tea->timeend));
800                         fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$tea->timemodified));
801                         fwrite ($bf,full_tag("TIMEACCESS",6,false,$tea->timeaccess));
802                         //Print ROLE end
803                         fwrite ($bf,end_tag("ROLE",5,true));   
804                     }
805                     //Student
806                     if ($user->isstudent!==false) {
807                         //Print ROLE start 
808                         fwrite ($bf,start_tag("ROLE",5,true)); 
809                         //Print Role info 
810                         fwrite ($bf,full_tag("TYPE",6,false,"student"));
811                         //Get specific info for students
812                         $stu = get_record("user_students","userid",$user->old_id,"course",$preferences->backup_course);
813                         fwrite ($bf,full_tag("TIMESTART",6,false,$stu->timestart));
814                         fwrite ($bf,full_tag("TIMEEND",6,false,$stu->timeend));
815                         fwrite ($bf,full_tag("TIME",6,false,$stu->time));
816                         fwrite ($bf,full_tag("TIMEACCESS",6,false,$stu->timeaccess));
817                         //Print ROLE end
818                         fwrite ($bf,end_tag("ROLE",5,true));   
819                     }
820                     //Needed
821                     if ($user->isneeded!==false) {
822                         //Print ROLE start
823                         fwrite ($bf,start_tag("ROLE",5,true));
824                         //Print Role info
825                         fwrite ($bf,full_tag("TYPE",6,false,"needed"));
826                         //Print ROLE end
827                         fwrite ($bf,end_tag("ROLE",5,true));
828                     }
830                     //End ROLES tag
831                     fwrite ($bf,end_tag("ROLES",4,true));
832  
833                     //Check if we have user_preferences to backup
834                     if ($preferences_data = get_records("user_preferences","userid",$user->old_id)) {
835                         //Start USER_PREFERENCES tag
836                         fwrite ($bf,start_tag("USER_PREFERENCES",4,true));
837                         //Write each user_preference
838                         foreach ($preferences_data as $user_preference) {
839                             fwrite ($bf,start_tag("USER_PREFERENCE",5,true));
840                             fwrite ($bf,full_tag("NAME",6,false,$user_preference->name));
841                             fwrite ($bf,full_tag("VALUE",6,false,$user_preference->value));
842                             fwrite ($bf,end_tag("USER_PREFERENCE",5,true));
843                         }
844                         //End USER_PREFERENCES tag
845                         fwrite ($bf,end_tag("USER_PREFERENCES",4,true));
846                     }
847                     
848                 }
849                 //End User tag
850                 fwrite ($bf,end_tag("USER",3,true));
851                 //Do some output
852                 $counter++;
853                 if ($counter % 10 == 0) {
854                     echo ".";   
855                     if ($counter % 200 == 0) {
856                         echo "<br>";
857                     }
858                     backup_flush(300);
859                 }
860             }
861             //End Users tag
862             fwrite ($bf,end_tag("USERS",2,true));
863         } else {
864             // There aren't any users.
865             $status = true;
866         }
868         return $status;
869     }
871     //Backup log info (time ordered)
872     function backup_log_info($bf,$preferences) {
874         global $CFG;
876         //Number of records to get in every chunk
877         $recordset_size = 1000;
878   
879         $status = true;
880  
881         //Counter, points to current record
882         $counter = 0;
884         //Count records
885         $count_logs = count_records("log","course",$preferences->backup_course);
887         //Pring logs header
888         if ($count_logs > 0 ) {
889             fwrite ($bf,start_tag("LOGS",2,true));
890         }
891         while ($counter < $count_logs) {
892             //Get a chunk of records
893             $logs = get_records ("log","course",$preferences->backup_course,"time","*",$counter,$recordset_size);
895             //We have logs
896             if ($logs) {
897                 //Iterate 
898                 foreach ($logs as $log) {
899                     //See if it is a valid module to backup
900                     if ($log->module == "course" or 
901                         $log->module == "user" or
902                         $preferences->mods[$log->module]->backup == 1) {
903                         //Begin log tag
904                          fwrite ($bf,start_tag("LOG",3,true));
905     
906                         //Output log tag
907                         fwrite ($bf,full_tag("ID",4,false,$log->id));
908                         fwrite ($bf,full_tag("TIME",4,false,$log->time));
909                         fwrite ($bf,full_tag("USERID",4,false,$log->userid));
910                         fwrite ($bf,full_tag("IP",4,false,$log->ip));
911                         fwrite ($bf,full_tag("MODULE",4,false,$log->module));
912                         fwrite ($bf,full_tag("CMID",4,false,$log->cmid));
913                         fwrite ($bf,full_tag("ACTION",4,false,$log->action));
914                         fwrite ($bf,full_tag("URL",4,false,$log->url));
915                         fwrite ($bf,full_tag("INFO",4,false,$log->info));
916     
917                         //End log tag
918                          fwrite ($bf,end_tag("LOG",3,true));
919                     }
920                     //Do some output
921                     $counter++;
922                     if ($counter % 10 == 0) {
923                         echo ".";
924                         if ($counter % 200 == 0) {
925                             echo "<br>";
926                         }
927                         backup_flush(300);
928                     }
929                 }
930             }
931         }
932         //End logs tag
933         if ($count_logs > 0 ) {
934             $status = fwrite ($bf,end_tag("LOGS",2,true));
935         }
936         return $status;
937     }
940     //Backup scales info (common and course scales)
941     function backup_scales_info($bf,$preferences) {
943         global $CFG;
945         $status = true;
947         //Counter, points to current record
948         $counter = 0;
950         //Get scales (common and course scales)
951         $scales = get_records_sql("SELECT id, courseid, userid, name, scale, description, timemodified
952                                    FROM {$CFG->prefix}scale
953                                    WHERE courseid = '0' or courseid = $preferences->backup_course");
955         //Copy only used scales to $backupscales. They will be in backup (unused no). See Bug 1223.
956         $backupscales = array();
957         if ($scales) {
958             foreach ($scales as $scale) {
959                 if (course_scale_used($preferences->backup_course, $scale->id)) {
960                     $backupscales[] = $scale;
961                 }
962             }
963         }
965         //Pring scales header
966         if ($backupscales) {
967             //Pring scales header
968             fwrite ($bf,start_tag("SCALES",2,true));
969             //Iterate
970             foreach ($backupscales as $scale) {
971                 //Begin scale tag
972                 fwrite ($bf,start_tag("SCALE",3,true));
973                 //Output scale tag
974                 fwrite ($bf,full_tag("ID",4,false,$scale->id));
975                 fwrite ($bf,full_tag("COURSEID",4,false,$scale->courseid));
976                 fwrite ($bf,full_tag("USERID",4,false,$scale->userid));
977                 fwrite ($bf,full_tag("NAME",4,false,$scale->name));
978                 fwrite ($bf,full_tag("SCALETEXT",4,false,$scale->scale));
979                 fwrite ($bf,full_tag("DESCRIPTION",4,false,$scale->description));
980                 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$scale->timemodified));
981                 //End scale tag
982                 fwrite ($bf,end_tag("SCALE",3,true));
983             }
984             //End scales tag
985             $status = fwrite ($bf,end_tag("SCALES",2,true));
986         }
987         return $status;
988     }
990     //Backup events info (course events)
991     function backup_events_info($bf,$preferences) {
993         global $CFG;
995         $status = true;
997         //Counter, points to current record
998         $counter = 0;
1000         //Get events (course events)
1001         $events = get_records_select("event","courseid='$preferences->backup_course' AND instance='0'","id");
1003         //Pring events header
1004         if ($events) {
1005             //Pring events header
1006             fwrite ($bf,start_tag("EVENTS",2,true));
1007             //Iterate
1008             foreach ($events as $event) {
1009                 //Begin event tag
1010                 fwrite ($bf,start_tag("EVENT",3,true));
1011                 //Output event tag
1012                 fwrite ($bf,full_tag("ID",4,false,$event->id));
1013                 fwrite ($bf,full_tag("NAME",4,false,$event->name));
1014                 fwrite ($bf,full_tag("DESCRIPTION",4,false,$event->description));
1015                 fwrite ($bf,full_tag("FORMAT",4,false,$event->format));
1016                 fwrite ($bf,full_tag("GROUPID",4,false,$event->groupid));
1017                 fwrite ($bf,full_tag("USERID",4,false,$event->userid));
1018                 fwrite ($bf,full_tag("EVENTTYPE",4,false,$event->eventtype));
1019                 fwrite ($bf,full_tag("TIMESTART",4,false,$event->timestart));
1020                 fwrite ($bf,full_tag("TIMEDURATION",4,false,$event->timeduration));
1021                 fwrite ($bf,full_tag("VISIBLE",4,false,$event->visible));
1022                 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$event->timemodified));
1023                 //End event tag
1024                 fwrite ($bf,end_tag("EVENT",3,true));
1025             }
1026             //End events tag
1027             $status = fwrite ($bf,end_tag("EVENTS",2,true));
1028         }
1029         return $status;
1030     }
1032     //Backup groups info
1033     function backup_groups_info($bf,$preferences) {
1034     
1035         global $CFG;
1037         $status = true;
1038         $status2 = true;
1040         //Get groups 
1041         $groups = get_records("groups","courseid",$preferences->backup_course);
1043         //Pring groups header
1044         if ($groups) {
1045             //Pring groups header
1046             fwrite ($bf,start_tag("GROUPS",2,true));
1047             //Iterate
1048             foreach ($groups as $group) {
1049                 //Begin group tag
1050                 fwrite ($bf,start_tag("GROUP",3,true));
1051                 //Output group contents
1052                 fwrite ($bf,full_tag("ID",4,false,$group->id));
1053                 fwrite ($bf,full_tag("COURSEID",4,false,$group->courseid));
1054                 fwrite ($bf,full_tag("NAME",4,false,$group->name));
1055                 fwrite ($bf,full_tag("DESCRIPTION",4,false,$group->description));
1056                 fwrite ($bf,full_tag("LANG",4,false,$group->lang));
1057                 fwrite ($bf,full_tag("PICTURE",4,false,$group->picture));
1058                 fwrite ($bf,full_tag("HIDEPICTURE",4,false,$group->hidepicture));
1059                 fwrite ($bf,full_tag("TIMECREATED",4,false,$group->timecreated));
1060                 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$group->timemodified));
1061                 
1062                 //Now, backup groups_members
1063                 $status2 = backup_groups_members_info($bf,$preferences,$group->id);
1065                 //End group tag
1066                 fwrite ($bf,end_tag("GROUP",3,true));
1067             }
1068             //End groups tag
1069             $status = fwrite ($bf,end_tag("GROUPS",2,true));
1070         }
1071         return ($status && $status2);
1072     }
1074     //Backup groups_members info
1075     function backup_groups_members_info($bf,$preferences,$groupid) {
1076   
1077         global $CFG;
1078         
1079         $status = true;
1081         //Get groups_members
1082         $groups_members = get_records("groups_members","groupid",$groupid);
1083         
1084         //Pring groups_members header
1085         if ($groups_members) {
1086             //Pring groups_members header
1087             fwrite ($bf,start_tag("MEMBERS",4,true));
1088             //Iterate
1089             foreach ($groups_members as $group_member) {
1090                 //Begin group_member tag
1091                 fwrite ($bf,start_tag("MEMBER",5,true));
1092                 //Output group_member contents
1093                 fwrite ($bf,full_tag("USERID",6,false,$group_member->userid));
1094                 fwrite ($bf,full_tag("TIMEADDED",6,false,$group_member->timeadded));
1095                 //End group_member tag
1096                 fwrite ($bf,end_tag("MEMBER",5,true));
1097             }
1098             //End groups_members tag
1099             $status = fwrite ($bf,end_tag("MEMBERS",4,true));
1100         }
1101         return $status;
1102     }
1104     //Start the modules tag
1105     function backup_modules_start ($bf,$preferences) {
1106       
1107         return fwrite ($bf,start_tag("MODULES",2,true));
1108     }
1110     //End the modules tag
1111     function backup_modules_end ($bf,$preferences) {
1113         return fwrite ($bf,end_tag("MODULES",2,true));
1114     }
1116     //This function makes all the necesary calls to every mod
1117     //to export itself and its files !!!
1118     function backup_module($bf,$preferences,$module) {
1119          
1120         global $CFG;
1122         $status = true;
1124         //First, re-check if necessary functions exists
1125         $modbackup = $module."_backup_mods";
1126         if (function_exists($modbackup)) {
1127             //Call the function
1128             $status = $modbackup($bf,$preferences);
1129         } else {
1130             //Something was wrong. Function should exist.
1131             $status = false;
1132         }
1133    
1134         return $status; 
1135         
1136     }
1138     //This function encode things to make backup multi-site fully functional
1139     //It does this conversions:
1140     //    - $CFG->wwwroot/file.php/courseid ----------------------> $@FILEPHP@$
1141     //    - Links to forums everywhere (DB) are encoded.
1142     //
1143     function backup_encode_absolute_links($content) {
1145         global $CFG,$preferences;
1147         //Check if preferences is ok. If it isn't set, we are 
1148         //in a scheduled_backup to we are able to get a copy
1149         //from CFG->backup_preferences
1150         if (!isset($preferences)) {
1151             $mypreferences = $CFG->backup_preferences;
1152         } else {
1153             //We are in manual backups so global preferences must exist!!
1154             $mypreferences = $preferences;
1155         }
1157         //First, we check for every call to file.php inside the course
1158         $search = array($CFG->wwwroot."/file.php/".$mypreferences->backup_course);
1160         $replace = array("$@FILEPHP@$");
1162         $result = str_replace($search,$replace,$content);
1164         foreach ($mypreferences->mods as $name => $info) {
1165             //Check if the xxxx_encode_content_links exists
1166             $function_name = $name."_encode_content_links";
1167             if (function_exists($function_name)) {
1168                 $result = $function_name($result,$mypreferences);
1169             }
1170         }
1172         if ($result != $content && $CFG->debug>7) {                                  //Debug
1173             echo "<br><hr>".$content."<br>changed to<br>".$result."<hr><br>";        //Debug
1174         }                                                                            //Debug
1176         return $result;
1177     }
1179     //This function copies all the needed files under the "users" directory to the "user_files"
1180     //directory under temp/backup
1181     function backup_copy_user_files ($preferences) {
1183         global $CFG;
1185         $status = true;
1187         //First we check to "user_files" exists and create it as necessary
1188         //in temp/backup/$backup_code  dir
1189         $status = check_and_create_user_files_dir($preferences->backup_unique_code);
1190  
1191         //Now iterate over directories under "users" to check if that user must be 
1192         //copied to backup
1193         
1194         $rootdir = $CFG->dataroot."/users";
1195         //Check if directory exists
1196         if (is_dir($rootdir)) {
1197             $list = list_directories ($rootdir);
1198             if ($list) {
1199                 //Iterate
1200                 foreach ($list as $dir) {
1201                     //Look for dir like username in backup_ids
1202                     $data = get_record ("backup_ids","backup_code",$preferences->backup_unique_code,
1203                                                      "table_name","user", 
1204                                                      "old_id",$dir);
1205                     //If exists, copy it
1206                     if ($data) {
1207                         $status = backup_copy_file($rootdir."/".$dir,
1208                                        $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/user_files/".$dir);
1209                     }
1210                 }
1211             }
1212         }
1213         return $status;
1214     }
1216     //This function copies all the course files under the course directory (except the moddata
1217     //directory to the "course_files" directory under temp/backup
1218     function backup_copy_course_files ($preferences) {
1220         global $CFG;
1222         $status = true;
1224         //First we check to "course_files" exists and create it as necessary
1225         //in temp/backup/$backup_code  dir
1226         $status = check_and_create_course_files_dir($preferences->backup_unique_code);
1228         //Now iterate over files and directories except $CFG->moddata and backupdata to be
1229         //copied to backup
1231         $rootdir = $CFG->dataroot."/".$preferences->backup_course;
1233         $name_moddata = $CFG->moddata;
1234         $name_backupdata = "backupdata";
1235         //Check if directory exists
1236         if (is_dir($rootdir)) {
1237             $list = list_directories_and_files ($rootdir);
1238             if ($list) {
1239                 //Iterate
1240                 foreach ($list as $dir) {
1241                     if ($dir !== $name_moddata and $dir !== $name_backupdata) {
1242                         $status = backup_copy_file($rootdir."/".$dir,
1243                                        $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/course_files/".$dir);
1244                     }
1245                 }
1246             }
1247         }
1248         return $status;
1249     }
1251     //This function creates the zip file containing all the backup info
1252     //moodle.xml, moddata, user_files, course_files.
1253     //The zipped file is created in the backup directory and named with
1254     //the "oficial" name of the backup
1255     //It uses "pclzip" if available or system "zip" (unix only)
1256     function backup_zip ($preferences) {
1257     
1258         global $CFG;
1260         $status = true;
1262         //Base dir where everything happens
1263         $basedir = $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code;
1264         //Backup zip file name
1265         $name = $preferences->backup_name;
1266         //List base_dir files and directories
1267         $filelist = list_directories_and_files ($basedir);
1269         if (empty($CFG->zip)) {    // Use built-in php-based zip function
1270             //echo "<br>Using pclzip";                                    //Debug
1271             $files = array();
1272             foreach ($filelist as $file) {
1273                 //If directory, append "/"
1274                 //Commented. Not needed wit version 2.0 of pclzip !!
1275                 //if (is_dir($basedir."/".$file)) {
1276                 //    $file = $file."/";
1277                 //}
1278                 //Include into array
1279                 //echo "<br>Adding file/dir ".$file;                       //Debug
1280                 $files[] = $basedir."/".$file;
1281             }
1282             include_once("$CFG->dirroot/lib/pclzip/pclzip.lib.php");
1283             //include_once("$CFG->dirroot/lib/pclzip/pclerror.lib.php");   //Debug
1284             //include_once("$CFG->dirroot/lib/pclzip/pcltrace.lib.php");   //Debug
1285             //PclTraceOn(2);                                               //Debug
1286             $archive = new PclZip("$basedir/$name");
1287             if (($list = $archive->create($files,PCLZIP_OPT_REMOVE_PATH,$basedir)) == 0) {
1288                 error($archive->errorInfo(true));
1289                 $status = false;
1290             } 
1291             //PclTraceDisplay();                                           //Debug
1292             //PclTraceOff();                                               //Debug
1293         } else {                   // Use external zip program
1294             //echo "<br>Using external zip";                               //Debug
1295             $files = "";
1296             foreach ($filelist as $file) {
1297                 $files .= basename($file);
1298                 $files .= " ";
1299             }
1300             $command = "cd $basedir ; $CFG->zip -r $name $files";
1301             //echo "<br>Executing command: ".$command;                     //Debug
1302             $status = Exec($command);
1303         }
1305         //echo "<br>Status: ".$status;                                     //Debug
1306         return $status;
1308     } 
1310     //This function copies the final zip to the course dir
1311     function copy_zip_to_course_dir ($preferences) {
1312     
1313         global $CFG;
1315         $status = true;
1317         //Define zip location (from)
1318         $from_zip_file = $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/".$preferences->backup_name;
1320         //Initialise $to_zip_file
1321         $to_zip_file="";
1323         //If $preferences->backup_destination isn't empty, then copy to custom directory
1324         if (!empty($preferences->backup_destination)) {
1325             $to_zip_file = $preferences->backup_destination."/".$preferences->backup_name;
1326         } else {
1327             //Define zip destination (course dir)
1328             $to_zip_file = $CFG->dataroot."/".$preferences->backup_course;
1329     
1330             //echo "<p>From: ".$from_zip_file."<br>";                                              //Debug
1331     
1332             //echo "<p>Checking: ".$to_zip_file."<br>";                                          //Debug
1333     
1334             //Checks course dir exists
1335             $status = check_dir_exists($to_zip_file,true);
1336     
1337             //Define zip destination (backup dir)
1338             $to_zip_file = $to_zip_file."/backupdata";
1339     
1340             //echo "<p>Checking: ".$to_zip_file."<br>";                                          //Debug
1341     
1342             //Checks backup dir exists
1343             $status = check_dir_exists($to_zip_file,true);
1345             //Define zip destination (zip file)
1346             $to_zip_file = $to_zip_file."/".$preferences->backup_name;
1347         }
1349         //echo "<p>To: ".$to_zip_file."<br>";                                              //Debug
1351         //Copy zip file
1352         if ($status) {
1353             $status = backup_copy_file ($from_zip_file,$to_zip_file);
1354         }
1356         return $status;
1357     }
1358 ?>