Commit 7a8fe6fa authored by Petr Skoda's avatar Petr Skoda
Browse files

Merge branch 'MDL-25863_automated_backups_wip' of git://github.com/stronk7/moodle

parents 9ceaf7b5 8afbe44f
......@@ -147,34 +147,49 @@ abstract class backup_plan_dbops extends backup_dbops {
* Returns the default backup filename, based in passed params.
*
* Default format is (see MDL-22145)
* backup word - format - type - name - date - info . mbz
* backup word - format - type - name - date - info . mbz
* where name is variable (course shortname, section name/id, activity modulename + cmid)
* and info can be (nu = no user info, an = anonymized)
* and info can be (nu = no user info, an = anonymized). The last param $useidasname,
* defaulting to false, allows to replace the course shortname by the course id (used
* by automated backups, to avoid non-ascii chars in OS filesystem)
*
* @param string $format One of backup::FORMAT_
* @param string $type One of backup::TYPE_
* @param int $courseid/$sectionid/$cmid
* @param bool $users Should be true is users were included in the backup
* @param bool $anonymised Should be true is user information was anonymized.
* @param bool $useidasname true to use id, false to use strings (default)
* @return string The filename to use
*/
public static function get_default_backup_filename($format, $type, $id, $users, $anonymised) {
public static function get_default_backup_filename($format, $type, $id, $users, $anonymised, $useidasname = false) {
global $DB;
// Calculate backup word
$backupword = str_replace(' ', '_', moodle_strtolower(get_string('backupfilename')));
$backupword = trim(clean_filename($backupword), '_');
// Calculate proper name element (based on type)
switch ($type) {
case backup::TYPE_1COURSE:
$shortname = $DB->get_field('course', 'shortname', array('id' => $id));
break;
case backup::TYPE_1SECTION:
if (!$shortname = $DB->get_field('course_sections', 'name', array('id' => $id))) {
$shortname = $DB->get_field('course_sections', 'section', array('id' => $id));
}
break;
case backup::TYPE_1ACTIVITY:
$cm = get_coursemodule_from_id(null, $id);
$shortname = $cm->modname . $id;
break;
$shortname = '';
// Not $useidasname, lets calculate it, else $id will be used
if (!$useidasname) {
// Calculate proper name element (based on type)
switch ($type) {
case backup::TYPE_1COURSE:
$shortname = $DB->get_field('course', 'shortname', array('id' => $id));
break;
case backup::TYPE_1SECTION:
if (!$shortname = $DB->get_field('course_sections', 'name', array('id' => $id))) {
$shortname = $DB->get_field('course_sections', 'section', array('id' => $id));
}
break;
case backup::TYPE_1ACTIVITY:
$cm = get_coursemodule_from_id(null, $id);
$shortname = $cm->modname . $id;
break;
}
$shortname = str_replace(' ', '_', $shortname);
$shortname = moodle_strtolower(trim(clean_filename($shortname), '_'));
}
$shortname = str_replace(' ', '_', $shortname);
$shortname = moodle_strtolower(trim(clean_filename($shortname), '_'));
$name = empty($shortname) ? $id : $shortname;
// Calculate date
......
......@@ -347,7 +347,7 @@ abstract class backup_cron_automated_helper {
$dir = null;
}
if (!empty($dir) && $storage !== 0) {
$filename = self::get_external_filename($course->id, $format, $type, $users, $anonymised);
$filename = backup_plan_dbops::get_default_backup_filename($format, $type, $course->id, $users, $anonymised, true);
$outcome = $file->copy_content_to($dir.'/'.$filename);
if ($outcome && $storage === 1) {
$file->delete();
......@@ -366,38 +366,6 @@ abstract class backup_cron_automated_helper {
return true;
}
/**
* Gets the filename to use for the backup when it is being moved to an
* external location.
*
* Note: we use the course id in the filename rather than the course shortname
* because it may contain UTF-8 characters that could cause problems for the
* recieving filesystem.
*
* @param int $courseid
* @param string $format One of backup::FORMAT_
* @param string $type One of backup::TYPE_
* @param bool $users Should be true is users were included in the backup
* @param bool $anonymised Should be true is user information was anonymized.
* @return string The filename to use
*/
public static function get_external_filename($courseid, $format, $type, $users, $anonymised) {
$backupword = str_replace(' ', '_', moodle_strtolower(get_string('backupfilename')));
$backupword = trim(clean_filename($backupword), '_');
// Calculate date
$backupdateformat = str_replace(' ', '_', get_string('backupnameformat', 'langconfig'));
$date = userdate(time(), $backupdateformat, 99, false);
$date = moodle_strtolower(trim(clean_filename($date), '_'));
// Calculate info
$info = '';
if (!$users) {
$info = 'nu';
} else if ($anonymised) {
$info = 'an';
}
return $backupword.'-'.$format.'-'.$type.'-'.$courseid.'-'.$date.'-'.$info.'.mbz';
}
/**
* Removes deleted courses fromn the backup_courses table so that we don't
* waste time backing them up.
......@@ -488,32 +456,39 @@ abstract class backup_cron_automated_helper {
$filearea = 'automated';
$itemid = 0;
$files = array();
// Store all the matching files into timemodified => stored_file array
foreach ($fs->get_area_files($context->id, $component, $filearea, $itemid) as $file) {
if (strpos($file->get_filename(), $backupword) !== 0) {
continue;
}
$files[$file->get_timemodified()] = $file;
}
arsort($files);
if (count($files) <= $keep) {
// There are less matching files than the desired number to keep
// do there is nothing to clean up.
return 0;
}
// Sort by keys descending (newer to older filemodified)
krsort($files);
$remove = array_splice($files, $keep);
foreach ($remove as $file) {
$file->delete();
}
//mtrace('Removed '.count($remove).' old backup file(s) from the data directory');
//mtrace('Removed '.count($remove).' old backup file(s) from the automated filearea');
}
// Clean up excess backups in the specified external directory
if (!empty($dir) && ($storage == 1 || $storage == 2)) {
// Calculate backup filename regex
// Calculate backup filename regex, ignoring the date/time/info parts that can be
// variable, depending of languages, formats and automated backup settings
$filename = $backupword . '-' . backup::FORMAT_MOODLE . '-' . backup::TYPE_1COURSE . '-' .$course->id . '-';
$regex = '#^'.preg_quote($filename, '#').'.*\.mbz$#';
$regex = '#^'.preg_quote($filename, '#').'(\d{8})\-(\d{4})\-[a-z]{2}\.mbz$#S';
// Store all the matching files into fullpath => timemodified array
$files = array();
foreach (scandir($dir) as $file) {
if (preg_match($regex, $file, $matches)) {
$files[$file] = $matches[1].$matches[2];
$files[$file] = filemtime($dir . '/' . $file);
}
}
if (count($files) <= $keep) {
......@@ -521,14 +496,15 @@ abstract class backup_cron_automated_helper {
// do there is nothing to clean up.
return 0;
}
// Sort by values descending (newer to older filemodified)
arsort($files);
$remove = array_splice($files, $keep);
foreach (array_keys($remove) as $file) {
unlink($dir.'/'.$file);
unlink($dir . '/' . $file);
}
//mtrace('Removed '.count($remove).' old backup file(s) from external directory');
}
return true;
}
}
\ No newline at end of file
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment