MDL-35117 backup: Read information from backup XML file when removing excess backups

This commit is contained in:
Frederic Massart
2012-10-18 15:13:50 +08:00
parent e462f46b77
commit db6c8b82d2
3 changed files with 70 additions and 18 deletions
+34 -18
View File
@@ -15,7 +15,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Utility helper for automated backups run through cron.
*
@@ -25,6 +24,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* This class is an abstract class with methods that can be called to aid the
* running of automated backups over cron.
@@ -505,9 +506,9 @@ abstract class backup_cron_automated_helper {
/**
* Removes excess backups from the external system and the local file system.
*
* The number of backups keep comes from $config->backup_auto_keep
* The number of backups keep comes from $config->backup_auto_keep.
*
* @param stdClass $course
* @param stdClass $course object
* @return bool
*/
public static function remove_excess_backups($course) {
@@ -517,7 +518,7 @@ abstract class backup_cron_automated_helper {
$dir = $config->backup_auto_destination;
if ($keep == 0) {
// means keep all backup files
// Means keep all backup files.
return true;
}
@@ -528,7 +529,7 @@ abstract class backup_cron_automated_helper {
$dir = null;
}
// Clean up excess backups in the course backup filearea
// Clean up excess backups in the course backup filearea.
if ($storage == 0 || $storage == 2) {
$fs = get_file_storage();
$context = context_course::instance($course->id);
@@ -536,7 +537,7 @@ abstract class backup_cron_automated_helper {
$filearea = 'automated';
$itemid = 0;
$files = array();
// Store all the matching files into timemodified => stored_file 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;
@@ -544,11 +545,10 @@ abstract class backup_cron_automated_helper {
$files[$file->get_timemodified()] = $file;
}
if (count($files) <= $keep) {
// There are less matching files than the desired number to keep
// do there is nothing to clean up.
// There are less matching files than the desired number to keep there is nothing to clean up.
return 0;
}
// Sort by keys descending (newer to older filemodified)
// Sort by keys descending (newer to older filemodified).
krsort($files);
$remove = array_splice($files, $keep);
foreach ($remove as $file) {
@@ -557,26 +557,42 @@ abstract class backup_cron_automated_helper {
//mtrace('Removed '.count($remove).' old backup file(s) from the automated filearea');
}
// Clean up excess backups in the specified external directory
// Clean up excess backups in the specified external directory.
if (!empty($dir) && ($storage == 1 || $storage == 2)) {
// 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 . '-';
// variable, depending of languages, formats and automated backup settings.
$filename = $backupword . '-' . backup::FORMAT_MOODLE . '-' . backup::TYPE_1COURSE . '-' . $course->id . '-';
$regex = '#^'.preg_quote($filename, '#').'.*\.mbz$#';
// Store all the matching files into fullpath => timemodified array
// Store all the matching files into filename => timemodified array.
$files = array();
foreach (scandir($dir) as $file) {
if (preg_match($regex, $file, $matches)) {
$files[$file] = filemtime($dir . '/' . $file);
// Skip files not matching the naming convention.
if (!preg_match($regex, $file, $matches)) {
continue;
}
// Read the information contained in the backup itself.
try {
$bcinfo = backup_general_helper::get_backup_information_from_mbz($dir . '/' . $file);
} catch (backup_helper_exception $e) {
mtrace('Error: ' . $file . ' does not appear to be a valid backup (' . $e->errorcode . ')');
continue;
}
// Make sure this backup concerns the course and site we are looking for.
if ($bcinfo->format === backup::FORMAT_MOODLE &&
$bcinfo->type === backup::TYPE_1COURSE &&
$bcinfo->original_course_id == $course->id &&
backup_general_helper::backup_is_samesite($bcinfo)) {
$files[$file] = $bcinfo->backup_date;
}
}
if (count($files) <= $keep) {
// There are less matching files than the desired number to keep
// do there is nothing to clean up.
// There are less matching files than the desired number to keep there is nothing to clean up.
return 0;
}
// Sort by values descending (newer to older filemodified)
// Sort by values descending (newer to older filemodified).
arsort($files);
$remove = array_splice($files, $keep);
foreach (array_keys($remove) as $file) {
@@ -22,6 +22,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Non instantiable helper class providing general helper methods for backup/restore
*
@@ -216,6 +218,38 @@ abstract class backup_general_helper extends backup_helper {
return $info;
}
/**
* Load and format all the needed information from a backup file.
*
* This will only extract the moodle_backup.xml file from an MBZ
* file and then call {@link self::get_backup_information()}.
*
* @param string $filepath absolute path to the MBZ file.
* @return stdClass containing information.
* @since 2.4
*/
public static function get_backup_information_from_mbz($filepath) {
global $CFG;
if (!is_readable($filepath)) {
throw new backup_helper_exception('missing_moodle_backup_file', $filepath);
}
// Extract moodle_backup.xml.
$tmpname = 'info_from_mbz_' . time() . '_' . random_string(4);
$tmpdir = $CFG->tempdir . '/backup/' . $tmpname;
$fp = get_file_packer('application/vnd.moodle.backup');
$extracted = $fp->extract_to_pathname($filepath, $tmpdir, array('moodle_backup.xml'));
$moodlefile = $tmpdir . '/' . 'moodle_backup.xml';
if (!$extracted || !is_readable($moodlefile)) {
throw new backup_helper_exception('missing_moodle_backup_xml_file', $moodlefile);
}
// Read the information and delete the temporary directory.
$info = self::get_backup_information($tmpname);
remove_dir($tmpdir);
return $info;
}
/**
* Given the information fetched from moodle_backup.xml file
* decide if we are restoring in the same site the backup was
+2
View File
@@ -60,10 +60,12 @@ require_once($CFG->dirroot . '/backup/util/helper/backup_null_iterator.class.php
require_once($CFG->dirroot . '/backup/util/helper/backup_array_iterator.class.php');
require_once($CFG->dirroot . '/backup/util/helper/backup_anonymizer_helper.class.php');
require_once($CFG->dirroot . '/backup/util/helper/backup_file_manager.class.php');
require_once($CFG->dirroot . '/backup/util/helper/restore_moodlexml_parser_processor.class.php'); // Required by backup_general_helper::get_backup_information().
require_once($CFG->dirroot . '/backup/util/xml/xml_writer.class.php');
require_once($CFG->dirroot . '/backup/util/xml/output/xml_output.class.php');
require_once($CFG->dirroot . '/backup/util/xml/output/file_xml_output.class.php');
require_once($CFG->dirroot . '/backup/util/xml/contenttransformer/xml_contenttransformer.class.php');
require_once($CFG->dirroot . '/backup/util/xml/parser/progressive_parser.class.php');
require_once($CFG->dirroot . '/backup/util/loggers/base_logger.class.php');
require_once($CFG->dirroot . '/backup/util/loggers/error_log_logger.class.php');
require_once($CFG->dirroot . '/backup/util/loggers/file_logger.class.php');