2 //This file contains all the code needed to execute scheduled backups
4 //This function is executed via moodle cron
5 //It prepares all the info and execute backups as necessary
6 function schedule_backup_cron() {
12 $emailpending = false;
14 //Check for required functions...
15 if(!function_exists('utf8_encode')) {
16 mtrace(" ERROR: You need to add XML support to your PHP installation!");
23 //First of all, we have to see if the scheduled is active and detect
24 //that there isn't another cron running
25 mtrace(" Checking backup status",'...');
26 $backup_config = backup_get_config();
27 if(!isset($backup_config->backup_sche_active
) ||
!$backup_config->backup_sche_active
) {
30 } else if (isset($backup_config->backup_sche_running
) && $backup_config->backup_sche_running
) {
32 //Now check if it's a really running task or something very old looking
33 //for info in backup_logs to unlock status as necessary
34 $timetosee = 1800; //Half an hour looking for activity
35 $timeafter = time() - $timetosee;
36 $numofrec = count_records_select ("backup_log","time > $timeafter");
38 $timetoseemin = $timetosee/60;
39 mtrace(" No activity in last ".$timetoseemin." minutes. Unlocking status");
41 mtrace(" Scheduled backup seems to be running. Execution delayed");
46 //Mark backup_sche_running
47 backup_set_config("backup_sche_running","1");
50 //Now we get the main admin user (we'll use his timezone, mail...)
51 mtrace(" Getting admin info");
57 //Delete old_entries from backup tables
59 mtrace(" Deleting old data");
60 $status = backup_delete_old_data();
63 //Now we get a list of courses in the server
65 mtrace(" Checking courses");
66 //First of all, we delete everything from backup tables related to deleted courses
67 mtrace(" Skipping deleted courses");
69 if ($bckcourses = get_records('backup_courses')) {
70 foreach($bckcourses as $bckcourse) {
72 if (!$exists = get_record('course', 'id', "$bckcourse->courseid")) {
73 //Doesn't exist, so delete from backup tables
74 delete_records('backup_courses', 'courseid', "$bckcourse->courseid");
75 delete_records('backup_log', 'courseid', "$bckcourse->courseid");
80 mtrace(" $skipped courses");
81 //Now process existing courses
82 $courses = get_records("course");
83 //For each course, we check (insert, update) the backup_course table
85 foreach ($courses as $course) {
87 mtrace(" $course->fullname");
88 //We check if the course exists in backup_course
89 $backup_course = get_record("backup_courses","courseid",$course->id
);
90 //If it doesn't exist, create
91 if (!$backup_course) {
92 $temp_backup_course->courseid
= $course->id
;
93 $newid = insert_record("backup_courses",$temp_backup_course);
95 $backup_course = get_record("backup_courses","id",$newid);
97 //If it doesn't exist now, error
98 if (!$backup_course) {
99 mtrace(" ERROR (in backup_courses detection)");
103 // Skip backup of unavailable courses that have remained unmodified in a month
105 if (!$course->visible
&& ($now - $course->timemodified
) > 31*24*60*60) { //Hidden + unmodified last month
106 mtrace(" SKIPPING - hidden+unmodified");
107 set_field("backup_courses","laststatus","3","courseid",$backup_course->courseid
);
110 //Now we backup every non skipped course with nextstarttime < now
111 if (!$skipped && $backup_course->nextstarttime
> 0 && $backup_course->nextstarttime
< $now) {
112 //We have to send a email because we have included at least one backup
113 $emailpending = true;
114 //Only make the backup if laststatus isn't 2-UNFINISHED (uncontrolled error)
115 if ($backup_course->laststatus
!= 2) {
118 set_field("backup_courses","laststarttime",$starttime,"courseid",$backup_course->courseid
);
119 //Set course status to unfinished, the process will reset it
120 set_field("backup_courses","laststatus","2","courseid",$backup_course->courseid
);
122 $course_status = schedule_backup_launch_backup($course,$starttime);
124 set_field("backup_courses","lastendtime",time(),"courseid",$backup_course->courseid
);
126 if ($course_status) {
127 set_field("backup_courses","laststatus","1","courseid",$backup_course->courseid
);
129 set_field("backup_courses","laststatus","0","courseid",$backup_course->courseid
);
134 //Now, calculate next execution of the course
135 $nextstarttime = schedule_backup_next_execution ($backup_course,$backup_config,$now,$admin->timezone
);
137 set_field("backup_courses","nextstarttime",$nextstarttime,"courseid",$backup_course->courseid
);
138 //Print it to screen as necessary
139 $showtime = "undefined";
140 if ($nextstarttime > 0) {
141 $showtime = userdate($nextstarttime,"",$admin->timezone
);
143 mtrace(" Next execution: $showtime");
149 if (!empty($CFG->loglifetime
)) {
150 mtrace(" Deleting old logs");
151 $loglifetime = $now - ($CFG->loglifetime
* 86400);
152 delete_records_select("backup_log", "laststarttime < '$loglifetime'");
155 //Send email to admin if necessary
157 mtrace(" Sending email to admin");
160 //Get info about the status of courses
161 $count_all = count_records('backup_courses');
162 $count_ok = count_records('backup_courses','laststatus','1');
163 $count_error = count_records('backup_courses','laststatus','0');
164 $count_unfinished = count_records('backup_courses','laststatus','2');
165 $count_skipped = count_records('backup_courses','laststatus','3');
167 //Build the message text
169 $message .= get_string('summary')."\n";
170 $message .= "==================================================\n";
171 $message .= " ".get_string('courses').": ".$count_all."\n";
172 $message .= " ".get_string('ok').": ".$count_ok."\n";
173 $message .= " ".get_string('skipped').": ".$count_skipped."\n";
174 $message .= " ".get_string('error').": ".$count_error."\n";
175 $message .= " ".get_string('unfinished').": ".$count_unfinished."\n\n";
178 if ($count_error != 0 ||
$count_unfinished != 0) {
179 $message .= " ".get_string('backupfailed')."\n\n";
180 $dest_url = $CFG->wwwroot
.'/backup/log.php';
181 $message .= " ".get_string('backuptakealook','',$dest_url)."\n\n";
182 //Set message priority
183 $admin->priority
= 1;
184 //Reset unfinished to error
185 set_field('backup_courses','laststatus','0','laststatus','2');
187 $message .= " ".get_string('backupfinished')."\n";
190 //Build the message subject
192 $prefix = $site->shortname
.": ";
193 if ($count_error != 0 ||
$count_unfinished != 0) {
194 $prefix .= "[".strtoupper(get_string('error'))."] ";
196 $subject = $prefix.get_string("scheduledbackupstatus");
199 email_to_user($admin,$admin,$subject,$message);
203 //Everything is finished stop backup_sche_running
204 backup_set_config("backup_sche_running","0");
209 //This function executes the ENTIRE backup of a course (passed as parameter)
210 //using all the scheduled backup preferences
211 function schedule_backup_launch_backup($course,$starttime = 0) {
213 $preferences = false;
216 mtrace(" Executing backup");
217 schedule_backup_log($starttime,$course->id
,"Start backup course $course->fullname");
218 schedule_backup_log($starttime,$course->id
," Phase 1: Checking and counting:");
219 $preferences = schedule_backup_course_configure($course,$starttime);
222 schedule_backup_log($starttime,$course->id
," Phase 2: Executing and copying:");
223 $status = schedule_backup_course_execute($preferences,$starttime);
226 if ($status && $preferences) {
227 //Only if the backup_sche_keep is set
228 if ($preferences->backup_keep
) {
229 schedule_backup_log($starttime,$course->id
," Phase 3: Deleting old backup files:");
230 $status = schedule_backup_course_delete_old_files($preferences,$starttime);
234 if ($status && $preferences) {
235 mtrace(" End backup OK");
236 schedule_backup_log($starttime,$course->id
,"End backup course $course->fullname - OK");
238 mtrace(" End backup with ERROR");
239 schedule_backup_log($starttime,$course->id
,"End backup course $course->fullname - ERROR!!");
242 return $status && $preferences;
245 //This function saves to backup_log all the needed process info
246 //to use it later. NOTE: If $starttime = 0 no info in saved
247 function schedule_backup_log($starttime,$courseid,$message) {
250 $log->courseid
= $courseid;
252 $log->laststarttime
= $starttime;
253 $log->info
= addslashes($message);
255 insert_record ("backup_log",$log);
260 //This function returns the next future GMT time to execute the course based in the
261 //configuration of the scheduled backups
262 function schedule_backup_next_execution ($backup_course,$backup_config,$now,$timezone) {
266 //Get today's midnight GMT
267 $midnight = usergetmidnight($now,$timezone);
269 //Get today's day of week (0=Sunday...6=Saturday)
270 $date = usergetdate($now,$timezone);
271 $dayofweek = $date['wday'];
273 //Get number of days (from today) to execute backups
274 $scheduled_days = substr($backup_config->backup_sche_weekdays
,$dayofweek).
275 $backup_config->backup_sche_weekdays
;
276 $daysfromtoday = strpos($scheduled_days, "1");
278 //If some day has been found
279 if ($daysfromtoday !== false) {
281 $dist = ($daysfromtoday * 86400) +
//Days distance
282 ($backup_config->backup_sche_hour
*3600) +
//Hours distance
283 ($backup_config->backup_sche_minute
*60); //Minutes distance
284 $result = $midnight +
$dist;
287 //If that time is past, call the function recursively to obtain the next valid day
288 if ($result > 0 && $result < time()) {
289 $result = schedule_backup_next_execution ($backup_course,$backup_config,$now +
86400,$timezone);
297 //This function implements all the needed code to prepare a course
298 //to be in backup (insert temp info into backup temp tables).
299 function schedule_backup_course_configure($course,$starttime = 0) {
305 schedule_backup_log($starttime,$course->id
," checking parameters");
307 //Check the required variable
308 if (empty($course->id
)) {
311 //Get scheduled backup preferences
312 $backup_config = backup_get_config();
314 //Checks backup_config pairs exist
316 if (!isset($backup_config->backup_sche_modules
)) {
317 $backup_config->backup_sche_modules
= 1;
319 if (!isset($backup_config->backup_sche_withuserdata
)) {
320 $backup_config->backup_sche_withuserdata
= 1;
322 if (!isset($backup_config->backup_sche_metacourse
)) {
323 $backup_config->backup_sche_metacourse
= 1;
325 if (!isset($backup_config->backup_sche_users
)) {
326 $backup_config->backup_sche_users
= 1;
328 if (!isset($backup_config->backup_sche_logs
)) {
329 $backup_config->backup_sche_logs
= 0;
331 if (!isset($backup_config->backup_sche_userfiles
)) {
332 $backup_config->backup_sche_userfiles
= 1;
334 if (!isset($backup_config->backup_sche_coursefiles
)) {
335 $backup_config->backup_sche_coursefiles
= 1;
337 if (!isset($backup_config->backup_sche_sitefiles
)) {
338 $backup_config->backup_sche_sitefiles
= 1;
340 if (!isset($backup_config->backup_sche_messages
)) {
341 $backup_config->backup_sche_messages
= 0;
343 if (!isset($backup_config->backup_sche_active
)) {
344 $backup_config->backup_sche_active
= 0;
346 if (!isset($backup_config->backup_sche_weekdays
)) {
347 $backup_config->backup_sche_weekdays
= "0000000";
349 if (!isset($backup_config->backup_sche_hour
)) {
350 $backup_config->backup_sche_hour
= 00;
352 if (!isset($backup_config->backup_sche_minute
)) {
353 $backup_config->backup_sche_minute
= 00;
355 if (!isset($backup_config->backup_sche_destination
)) {
356 $backup_config->backup_sche_destination
= "";
358 if (!isset($backup_config->backup_sche_keep
)) {
359 $backup_config->backup_sche_keep
= 1;
364 //Checks for the required files/functions to backup every mod
365 //And check if there is data about it
367 if ($allmods = get_records("modules") ) {
368 foreach ($allmods as $mod) {
369 $modname = $mod->name
;
370 $modfile = "$CFG->dirroot/mod/$modname/backuplib.php";
371 $modbackup = $modname."_backup_mods";
372 $modcheckbackup = $modname."_check_backup_mods";
373 if (file_exists($modfile)) {
374 include_once($modfile);
375 if (function_exists($modbackup) and function_exists($modcheckbackup)) {
376 $var = "exists_".$modname;
380 // PENNY NOTES: I have moved from here to the closing brace inside
381 // by two sets of ifs()
382 // to avoid the backup failing on a non existant backup.
383 // If the file/function/whatever doesn't exist, we don't want to set this
384 // this module in backup preferences at all.
387 $var = "backup_".$modname;
389 $
$var = $backup_config->backup_sche_modules
;
391 //Now stores all the mods preferences into an array into preferences
392 $preferences->mods
[$modname]->backup
= $
$var;
394 //Check include user info
395 $var = "backup_user_info_".$modname;
397 $
$var = $backup_config->backup_sche_withuserdata
;
399 //Now stores all the mods preferences into an array into preferences
400 $preferences->mods
[$modname]->userinfo
= $
$var;
401 //And the name of the mod
402 $preferences->mods
[$modname]->name
= $modname;
408 if ($coursemods = get_course_mods($course->id
)) {
409 foreach ($coursemods as $mod) {
410 if (array_key_exists($mod->modname
,$preferences->mods
)) { // we are to backup this module
411 if (empty($preferences->mods
[$mod->modname
]->instances
)) {
412 $preferences->mods
[$mod->modname
]->instances
= array(); // avoid warnings
414 $preferences->mods
[$mod->modname
]->instances
[$mod->instance
]->backup
= $preferences->mods
[$mod->modname
]->backup
;
415 $preferences->mods
[$mod->modname
]->instances
[$mod->instance
]->userinfo
= $preferences->mods
[$mod->modname
]->userinfo
;
416 // there isn't really a nice way to do this...
417 $preferences->mods
[$mod->modname
]->instances
[$mod->instance
]->name
= get_field($mod->modname
,'name','id',$mod->instance
);
423 //Convert other parameters
425 $preferences->backup_metacourse
= $backup_config->backup_sche_metacourse
;
426 $preferences->backup_users
= $backup_config->backup_sche_users
;
427 $preferences->backup_logs
= $backup_config->backup_sche_logs
;
428 $preferences->backup_user_files
= $backup_config->backup_sche_userfiles
;
429 $preferences->backup_course_files
= $backup_config->backup_sche_coursefiles
;
430 $preferences->backup_site_files
= $backup_config->backup_sche_sitefiles
;
431 $preferences->backup_messages
= $backup_config->backup_sche_messages
;
432 $preferences->backup_course
= $course->id
;
433 $preferences->backup_destination
= $backup_config->backup_sche_destination
;
434 $preferences->backup_keep
= $backup_config->backup_sche_keep
;
437 //Calculate the backup string
439 schedule_backup_log($starttime,$course->id
," calculating backup name");
441 //Calculate the backup word
442 //Take off some characters in the filename !!
443 $takeoff = array(" ", ":", "/", "\\", "|");
444 $backup_word = str_replace($takeoff,"_",moodle_strtolower(get_string("backupfilename")));
445 //If non-translated, use "backup"
446 if (substr($backup_word,0,1) == "[") {
447 $backup_word= "backup";
450 //Calculate the date format string
451 $backup_date_format = str_replace(" ","_",get_string("backupnameformat"));
452 //If non-translated, use "%Y%m%d-%H%M"
453 if (substr($backup_date_format,0,1) == "[") {
454 $backup_date_format = "%%Y%%m%%d-%%H%%M";
457 //Calculate the shortname
458 $backup_shortname = clean_filename($course->shortname
);
459 if (empty($backup_shortname) or $backup_shortname == '_' ) {
460 $backup_shortname = $course->id
;
463 //Calculate the final backup filename
465 $backup_name = $backup_word."-";
467 $backup_name .= moodle_strtolower($backup_shortname)."-";
469 $backup_name .= userdate(time(),$backup_date_format,99,false);
471 $backup_name .= ".zip";
472 //And finally, clean everything
473 $backup_name = clean_filename($backup_name);
475 //Calculate the string to match the keep preference
476 $keep_name = $backup_word."-";
478 $keep_name .= moodle_strtolower($backup_shortname)."-";
479 //And finally, clean everything
480 $keep_name = clean_filename($keep_name);
482 $preferences->backup_name
= $backup_name;
483 $preferences->keep_name
= $keep_name;
486 //Calculate the backup unique code to allow simultaneus backups (to define
487 //the temp-directory name and records in backup temp tables
489 $backup_unique_code = time();
490 $preferences->backup_unique_code
= $backup_unique_code;
493 //Calculate necesary info to backup modules
495 schedule_backup_log($starttime,$course->id
," calculating modules data");
496 if ($allmods = get_records("modules") ) {
497 foreach ($allmods as $mod) {
498 $modname = $mod->name
;
499 $modbackup = $modname."_backup_mods";
500 //If exists the lib & function
501 $var = "exists_".$modname;
502 if (isset($
$var) && $
$var) {
504 $var = "backup_".$modname;
507 $var = "backup_user_info_".$modname;
508 //Call the check function to show more info
509 $modcheckbackup = $modname."_check_backup_mods";
510 schedule_backup_log($starttime,$course->id
," $modname");
511 $modcheckbackup($course->id
,$
$var,$backup_unique_code);
518 //Now calculate the users
520 schedule_backup_log($starttime,$course->id
," calculating users");
521 //Decide about include users with messages, based on SITEID
522 if ($preferences->backup_messages
&& $preferences->backup_course
== SITEID
) {
523 $include_message_users = true;
525 $include_message_users = false;
527 user_check_backup($course->id
,$backup_unique_code,$preferences->backup_users
,$include_message_users);
530 //Now calculate the logs
532 if ($preferences->backup_logs
) {
533 schedule_backup_log($starttime,$course->id
," calculating logs");
534 log_check_backup($course->id
);
538 //Now calculate the userfiles
540 if ($preferences->backup_user_files
) {
541 schedule_backup_log($starttime,$course->id
," calculating user files");
542 user_files_check_backup($course->id
,$preferences->backup_unique_code
);
546 //Now calculate the coursefiles
548 if ($preferences->backup_course_files
) {
549 schedule_backup_log($starttime,$course->id
," calculating course files");
550 course_files_check_backup($course->id
,$preferences->backup_unique_code
);
554 //Now calculate the sitefiles
556 if ($preferences->backup_site_files
) {
557 schedule_backup_log($starttime,$course->id
," calculating site files");
558 site_files_check_backup($course->id
,$preferences->backup_unique_code
);
562 //If everything is ok, return calculated preferences
564 $status = $preferences;
570 //This function implements all the needed code to backup a course
571 //copying it to the desired destination (default if not specified)
572 function schedule_backup_course_execute($preferences,$starttime = 0) {
578 //Another Info to add
579 $preferences->moodle_version
= $CFG->version
;
580 $preferences->moodle_release
= $CFG->release
;
581 $preferences->backup_version
= $CFG->backup_version
;
582 $preferences->backup_release
= $CFG->backup_release
;
584 //Some parts of the backup doesn't know about $preferences, so we
585 //put a copy of it inside that CFG (always global) to be able to
586 //use it. Then, when needed I search for preferences inside CFG
587 //Used to avoid some problems in full_tag() when preferences isn't
588 //set globally (i.e. in scheduled backups)
589 $CFG->backup_preferences
= $preferences;
591 //Check for temp and backup and backup_unique_code directory
592 //Create them as needed
593 schedule_backup_log($starttime,$preferences->backup_course
," checking temp structures");
594 $status = check_and_create_backup_dir($preferences->backup_unique_code
);
597 schedule_backup_log($starttime,$preferences->backup_course
," cleaning current dir");
598 $status = clear_backup_dir($preferences->backup_unique_code
);
601 //Create the moodle.xml file
603 schedule_backup_log($starttime,$preferences->backup_course
," creating backup file");
604 //Obtain the xml file (create and open) and print prolog information
605 $backup_file = backup_open_xml($preferences->backup_unique_code
);
606 //Prints general info about backup to file
608 schedule_backup_log($starttime,$preferences->backup_course
," general info");
609 $status = backup_general_info($backup_file,$preferences);
614 //Prints course start (tag and general info)
616 $status = backup_course_start($backup_file,$preferences);
619 //Metacourse information
620 if ($status && $preferences->backup_metacourse
) {
621 schedule_backup_log($starttime,$preferences->backup_course
," metacourse info");
622 $status = backup_course_metacourse($backup_file,$preferences);
627 schedule_backup_log($starttime,$preferences->backup_course
," blocks info");
628 $status = backup_course_blocks($backup_file,$preferences);
633 schedule_backup_log($starttime,$preferences->backup_course
," sections info");
634 $status = backup_course_sections($backup_file,$preferences);
639 schedule_backup_log($starttime,$preferences->backup_course
," user info");
640 $status = backup_user_info($backup_file,$preferences);
643 //If we have selected to backup messages and we are
644 //doing a SITE backup, let's do it
645 if ($status && $preferences->backup_messages
&& $preferences->backup_course
== SITEID
) {
646 schedule_backup_log($starttime,$preferences->backup_course
," messages");
647 if (!$status = backup_messages($backup_file,$preferences)) {
648 notify("An error occurred while backing up messages");
652 //If we have selected to backup quizzes, backup categories and
653 //questions structure (step 1). See notes on mod/quiz/backuplib.php
654 if ($status and $preferences->mods
['quiz']->backup
) {
655 schedule_backup_log($starttime,$preferences->backup_course
," categories & questions");
656 $status = backup_question_categories($backup_file,$preferences);
659 //Print logs if selected
661 if ($preferences->backup_logs
) {
662 schedule_backup_log($starttime,$preferences->backup_course
," logs");
663 $status = backup_log_info($backup_file,$preferences);
669 schedule_backup_log($starttime,$preferences->backup_course
," scales");
670 $status = backup_scales_info($backup_file,$preferences);
675 schedule_backup_log($starttime,$preferences->backup_course
," groups");
676 $status = backup_groups_info($backup_file,$preferences);
681 schedule_backup_log($starttime,$preferences->backup_course
," events");
682 $status = backup_events_info($backup_file,$preferences);
685 //Print gradebook info
687 schedule_backup_log($starttime,$preferences->backup_course
," gradebook");
688 $status = backup_gradebook_info($backup_file,$preferences);
691 //Module info, this unique function makes all the work!!
692 //db export and module fileis copy
694 $mods_to_backup = false;
695 //Check if we have any mod to backup
696 foreach ($preferences->mods
as $module) {
697 if ($module->backup
) {
698 $mods_to_backup = true;
701 //If we have to backup some module
702 if ($mods_to_backup) {
703 schedule_backup_log($starttime,$preferences->backup_course
," modules");
705 $status = backup_modules_start ($backup_file,$preferences);
706 //Iterate over modules and call backup
707 foreach ($preferences->mods
as $module) {
708 if ($module->backup
and $status) {
709 schedule_backup_log($starttime,$preferences->backup_course
," $module->name");
710 $status = backup_module($backup_file,$preferences,$module->name
);
714 $status = backup_modules_end ($backup_file,$preferences);
720 $status = backup_course_end($backup_file,$preferences);
723 //Close the xml file and xml data
725 backup_close_xml($backup_file);
729 //Now, if selected, copy user files
731 if ($preferences->backup_user_files
) {
732 schedule_backup_log($starttime,$preferences->backup_course
," copying user files");
733 $status = backup_copy_user_files ($preferences);
737 //Now, if selected, copy course files
739 if ($preferences->backup_course_files
) {
740 schedule_backup_log($starttime,$preferences->backup_course
," copying course files");
741 $status = backup_copy_course_files ($preferences);
745 //Now, if selected, copy site files
747 if ($preferences->backup_site_files
) {
748 schedule_backup_log($starttime,$preferences->backup_course
," copying site files");
749 $status = backup_copy_site_files ($preferences);
753 //Now, zip all the backup directory contents
755 schedule_backup_log($starttime,$preferences->backup_course
," zipping files");
756 $status = backup_zip ($preferences);
759 //Now, copy the zip file to course directory
761 schedule_backup_log($starttime,$preferences->backup_course
," copying backup");
762 $status = copy_zip_to_course_dir ($preferences);
765 //Now, clean temporary data (db and filesystem)
767 schedule_backup_log($starttime,$preferences->backup_course
," cleaning temp data");
768 $status = clean_temp_data ($preferences);
771 //Unset CFG->backup_preferences only needed in scheduled backups
772 unset ($CFG->backup_preferences
);
777 //This function deletes old backup files when the "keep" limit has been reached
778 //in the destination directory.
779 function schedule_backup_course_delete_old_files($preferences,$starttime=0) {
785 //Calculate the directory to check
787 //if $preferences->backup_destination isn't empty, then check that directory
788 if (!empty($preferences->backup_destination
)) {
789 $dirtocheck = $preferences->backup_destination
;
790 //else calculate standard backup directory location
792 $dirtocheck = $CFG->dataroot
."/".$preferences->backup_course
."/backupdata";
794 schedule_backup_log($starttime,$preferences->backup_course
," checking $dirtocheck");
795 if ($CFG->debug
> 7) {
796 mtrace(" Keeping backup files in $dirtocheck");
799 //Get all the files in $dirtocheck
800 $files = get_directory_list($dirtocheck,"",false);
801 //Get all matching files ($preferences->keep_name) from $files
802 $matchingfiles = array();
803 foreach ($files as $file) {
804 if (substr($file, 0, strlen($preferences->keep_name
)) == $preferences->keep_name
) {
805 $modifieddate = filemtime($dirtocheck."/".$file);
806 $matchingfiles[$modifieddate] = $file;
809 //Sort by key (modified date) to get the oldest first (instead of doing that by name
810 //because it could give us problems in some languages with different format names).
811 ksort($matchingfiles);
813 //Count matching files
814 $countmatching = count($matchingfiles);
815 schedule_backup_log($starttime,$preferences->backup_course
," found $countmatching backup files");
816 mtrace(" found $countmatching backup files");
817 if ($preferences->backup_keep
< $countmatching) {
818 schedule_backup_log($starttime,$preferences->backup_course
," keep limit ($preferences->backup_keep) reached. Deleting old files");
819 mtrace(" keep limit ($preferences->backup_keep) reached. Deleting old files");
820 $filestodelete = $countmatching - $preferences->backup_keep
;
822 foreach ($matchingfiles as $matchfile) {
823 if ($filesdeleted < $filestodelete) {
824 schedule_backup_log($starttime,$preferences->backup_course
," $matchfile deleted");
825 mtrace(" $matchfile deleted");
826 $filetodelete = $dirtocheck."/".$matchfile;
827 unlink($filetodelete);