MDL-35117 backup: Read information from backup XML file when removing excess backups
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user