diff --git a/admin/settings/courses.php b/admin/settings/courses.php index 88f99c3c9c1..bd88630580e 100644 --- a/admin/settings/courses.php +++ b/admin/settings/courses.php @@ -226,7 +226,8 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) { ); $temp->add(new admin_setting_configselect('backup/backup_auto_storage', new lang_string('automatedstorage', 'backup'), new lang_string('automatedstoragehelp', 'backup'), 0, $storageoptions)); $temp->add(new admin_setting_special_backup_auto_destination()); - $keepoptoins = array( + + $maxkeptoptions = array( 0 => new lang_string('all'), 1 => '1', 2 => '2', 5 => '5', @@ -240,7 +241,44 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) { 300 => '300', 400 => '400', 500 => '500'); - $temp->add(new admin_setting_configselect('backup/backup_auto_keep', new lang_string('keep'), new lang_string('backupkeephelp'), 1, $keepoptoins)); + $temp->add(new admin_setting_configselect('backup/backup_auto_max_kept', new lang_string('automatedmaxkept', 'backup'), + new lang_string('automatedmaxkepthelp', 'backup'), 1, $maxkeptoptions)); + + $automateddeletedaysoptions = array( + 0 => new lang_string('never'), + 1000 => new lang_string('numdays', '', 1000), + 365 => new lang_string('numdays', '', 365), + 180 => new lang_string('numdays', '', 180), + 150 => new lang_string('numdays', '', 150), + 120 => new lang_string('numdays', '', 120), + 90 => new lang_string('numdays', '', 90), + 60 => new lang_string('numdays', '', 60), + 35 => new lang_string('numdays', '', 35), + 10 => new lang_string('numdays', '', 10), + 5 => new lang_string('numdays', '', 5), + 2 => new lang_string('numdays', '', 2) + ); + $temp->add(new admin_setting_configselect('backup/backup_auto_delete_days', new lang_string('automateddeletedays', 'backup'), + '', 0, $automateddeletedaysoptions)); + + $minkeptoptions = array( + 0 => new lang_string('none'), + 1 => '1', + 2 => '2', + 5 => '5', + 10 => '10', + 20 => '20', + 30 => '30', + 40 => '40', + 50 => '50', + 100 => '100', + 200 => '200', + 300 => '300', + 400 => '400' + ); + $temp->add(new admin_setting_configselect('backup/backup_auto_min_kept', new lang_string('automatedminkept', 'backup'), + new lang_string('automatedminkepthelp', 'backup'), 0, $minkeptoptions)); + $temp->add(new admin_setting_configcheckbox('backup/backup_shortname', new lang_string('backup_shortname', 'admin'), new lang_string('backup_shortnamehelp', 'admin'), 0)); $temp->add(new admin_setting_configcheckbox('backup/backup_auto_skip_hidden', new lang_string('skiphidden', 'backup'), new lang_string('skiphiddenhelp', 'backup'), 1)); $temp->add(new admin_setting_configselect('backup/backup_auto_skip_modif_days', new lang_string('skipmodifdays', 'backup'), new lang_string('skipmodifdayshelp', 'backup'), 30, array( @@ -262,45 +300,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) { ))); $temp->add(new admin_setting_configcheckbox('backup/backup_auto_skip_modif_prev', new lang_string('skipmodifprev', 'backup'), new lang_string('skipmodifprevhelp', 'backup'), 0)); - // Automated backup removal section. - $temp->add(new admin_setting_heading('automatedbackupremovalsettings', - new lang_string('automatedbackupremovalsettings', 'backup'), '')); - - $temp->add(new admin_setting_configselect('backup/backup_auto_keep_days', new lang_string('automatedbackupkeepdays', 'backup'), - new lang_string('automatedbackupkeepdayshelp', 'backup'), 0, array( - 0 => new lang_string('never'), - 1000 => new lang_string('numdays', '', 1000), - 365 => new lang_string('numdays', '', 365), - 180 => new lang_string('numdays', '', 180), - 150 => new lang_string('numdays', '', 150), - 120 => new lang_string('numdays', '', 120), - 90 => new lang_string('numdays', '', 90), - 60 => new lang_string('numdays', '', 60), - 35 => new lang_string('numdays', '', 35), - 10 => new lang_string('numdays', '', 10), - 5 => new lang_string('numdays', '', 5), - 2 => new lang_string('numdays', '', 2) - ))); - - $temp->add(new admin_setting_configselect('backup/backup_auto_keep_copies', - new lang_string('automatedbackupkeepcopies', 'backup'), new lang_string('automatedbackupkeepcopieshelp', 'backup'), - 0, array( - 0 => new lang_string('none'), - 1 => '1', - 2 => '2', - 5 => '5', - 10 => '10', - 20 => '20', - 30 => '30', - 40 => '40', - 50 => '50', - 100 => '100', - 200 => '200', - 300 => '300', - 400 => '400', - 500 => '500' - ))); - // Automated defaults section. $temp->add(new admin_setting_heading('automatedsettings', new lang_string('automatedsettings','backup'), '')); $temp->add(new admin_setting_configcheckbox('backup/backup_auto_users', new lang_string('generalusers', 'backup'), new lang_string('configgeneralusers', 'backup'), 1)); diff --git a/backup/upgrade.txt b/backup/upgrade.txt index 26e2e00d810..d9c06670713 100644 --- a/backup/upgrade.txt +++ b/backup/upgrade.txt @@ -1,6 +1,11 @@ This files describes API changes in /backup/*, information provided here is intended especially for developers. +=== 3.0 === + +* The backup_auto_keep setting, in automated backups configuration, is now + renamed to backup_auto_max_kept. + === 2.6 === * The backup_controller_dbops::create_temptable_from_real_table() diff --git a/backup/util/helper/backup_cron_helper.class.php b/backup/util/helper/backup_cron_helper.class.php index 5dff97daa96..d864076d3d5 100644 --- a/backup/util/helper/backup_cron_helper.class.php +++ b/backup/util/helper/backup_cron_helper.class.php @@ -198,17 +198,18 @@ abstract class backup_cron_automated_helper { $DB->update_record('backup_courses', $backupcourse); $backupcourse->laststatus = self::launch_automated_backup($course, $backupcourse->laststarttime, - $admin->id); + $admin->id); $backupcourse->lastendtime = time(); $backupcourse->nextstarttime = $nextstarttime; $DB->update_record('backup_courses', $backupcourse); + + mtrace("complete - next execution: $showtime"); } } // Remove excess backups. $removedcount = self::remove_excess_backups($course, $now); - mtrace("complete - next execution: $showtime"); } } $rs->close(); @@ -536,88 +537,177 @@ abstract class backup_cron_automated_helper { } /** - * Removes excess backups from the external system and the local file system. + * Removes excess backups from a specified course. * - * The number of backups keep comes from $config->backup_auto_keep. - * - * @param stdClass $course object - * @param int $now execution time - * @return bool + * @param stdClass $course Course object + * @param int $now Starting time of the process + * @return bool Whether or not backups is being removed */ - public static function remove_excess_backups($course, $now) { + public static function remove_excess_backups($course, $now = null) { $config = get_config('backup'); - $keep = (int)$config->backup_auto_keep; - $storage = $config->backup_auto_storage; - $dir = $config->backup_auto_destination; - $histdays = (int)$config->backup_auto_keep_days; + $maxkept = (int)$config->backup_auto_max_kept; + $storage = $config->backup_auto_storage; + $deletedays = (int)$config->backup_auto_delete_days; - if ($keep == 0 && $histdays == 0) { - // Means keep all backup files and never remove backup after x days. + if ($maxkept == 0 && $deletedays == 0) { + // Means keep all backup files and never delete backup after x days. return true; } - if (!file_exists($dir) || !is_dir($dir) || !is_writable($dir)) { - $dir = null; + if (!isset($now)) { + $now = time(); } // Clean up excess backups in the course backup filearea. + $deletedcoursebackups = false; if ($storage == 0 || $storage == 2) { - $fs = get_file_storage(); - $context = context_course::instance($course->id); - $component = 'backup'; - $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) { - $files[$file->get_timemodified()] = $file; - } - - $backupremoved = self::remove_old_backups($files, true, $now, $course->idnumber); - if (!$backupremoved) { - return 0; - } + $deletedcoursebackups = self::remove_excess_backups_from_course($course, $now); } // 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 = backup::FORMAT_MOODLE . '-' . backup::TYPE_1COURSE . '-' . $course->id . '-'; - $regex = '#' . preg_quote($filename, '#') . '.*\.mbz$#'; + $deleteddirectorybackups = false; + if ($storage == 1 || $storage == 2) { + $deleteddirectorybackups = self::remove_excess_backups_from_directory($course, $now); + } - // Store all the matching files into filename => timemodified array. - $files = array(); - foreach (scandir($dir) as $file) { - // Skip files not matching the naming convention. - if (!preg_match($regex, $file, $matches)) { - continue; - } + if ($deletedcoursebackups || $deleteddirectorybackups) { + return true; + } else { + return false; + } + } - // 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; - } + /** + * Removes excess backups in the course backup filearea from a specified course. + * + * @param stdClass $course Course object + * @param int $now Starting time of the process + * @return bool Whether or not backups are being removed + */ + protected static function remove_excess_backups_from_course($course, $now) { + $fs = get_file_storage(); + $context = context_course::instance($course->id); + $component = 'backup'; + $filearea = 'automated'; + $itemid = 0; + $backupfiles = array(); + $backupfilesarea = $fs->get_area_files($context->id, $component, $filearea, $itemid, 'timemodified DESC', false); + // Store all the matching files into timemodified => stored_file array. + foreach ($backupfilesarea as $backupfile) { + $backupfiles[$backupfile->get_timemodified()] = $backupfile; + } - // 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; - } + $backupstodelete = self::get_backups_to_delete($backupfiles, $now); + if ($backupstodelete) { + foreach ($backupstodelete as $backuptodelete) { + $backuptodelete->delete(); + } + mtrace('Deleted ' . count($backupstodelete) . ' old backup file(s) from the automated filearea'); + return true; + } else { + return false; + } + } + + /** + * Removes excess backups in the specified external directory from a specified course. + * + * @param stdClass $course Course object + * @param int $now Starting time of the process + * @return bool Whether or not backups are being removed + */ + protected static function remove_excess_backups_from_directory($course, $now) { + $config = get_config('backup'); + $dir = $config->backup_auto_destination; + + $isnotvaliddir = !file_exists($dir) || !is_dir($dir) || !is_writable($dir); + if ($isnotvaliddir) { + mtrace('Error: ' . $dir . ' does not appear to be a valid directory'); + return false; + } + + // Calculate backup filename regex, ignoring the date/time/info parts that can be + // variable, depending of languages, formats and automated backup settings. + $filename = backup::FORMAT_MOODLE . '-' . backup::TYPE_1COURSE . '-' . $course->id . '-'; + $regex = '#' . preg_quote($filename, '#') . '.*\.mbz$#'; + + // Store all the matching files into filename => timemodified array. + $backupfiles = array(); + foreach (scandir($dir) as $backupfile) { + // Skip files not matching the naming convention. + if (!preg_match($regex, $backupfile)) { + continue; } - $backupremoved = self::remove_old_backups($files, false, $now, $course->idnumber); - if (!$backupremoved) { - return 0; + // Read the information contained in the backup itself. + try { + $bcinfo = backup_general_helper::get_backup_information_from_mbz($dir . '/' . $backupfile); + } catch (backup_helper_exception $e) { + mtrace('Error: ' . $backupfile . ' 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)) { + $backupfiles[$bcinfo->backup_date] = $backupfile; } } - return true; + $backupstodelete = self::get_backups_to_delete($backupfiles, $now); + if ($backupstodelete) { + foreach ($backupstodelete as $backuptodelete) { + unlink($dir . '/' . $backuptodelete); + } + mtrace('Deleted ' . count($backupstodelete) . ' old backup file(s) from external directory'); + return true; + } else { + return false; + } + } + + /** + * Get the list of backup files to delete depending on the automated backup settings. + * + * @param array $backupfiles Existing backup files + * @param int $now Starting time of the process + * @return array Backup files to delete + */ + protected static function get_backups_to_delete($backupfiles, $now) { + $config = get_config('backup'); + $maxkept = (int)$config->backup_auto_max_kept; + $deletedays = (int)$config->backup_auto_delete_days; + $minkept = (int)$config->backup_auto_min_kept; + + // Sort by keys descending (newer to older filemodified). + krsort($backupfiles); + $tokeep = $maxkept; + if ($deletedays > 0) { + $deletedayssecs = $deletedays * DAYSECS; + $tokeep = 0; + $backupfileskeys = array_keys($backupfiles); + foreach ($backupfileskeys as $timemodified) { + $mustdeletebackup = $timemodified < ($now - $deletedayssecs); + if ($mustdeletebackup || $tokeep >= $maxkept) { + break; + } + $tokeep++; + } + + if ($tokeep < $minkept) { + $tokeep = $minkept; + } + } + + if (count($backupfiles) <= $tokeep) { + // There are less or equal matching files than the desired number to keep, there is nothing to clean up. + return false; + } else { + $backupstodelete = array_splice($backupfiles, $tokeep); + return $backupstodelete; + } } /** @@ -641,78 +731,4 @@ abstract class backup_cron_automated_helper { } return false; } - - /** - * Removes excess and old backups from the external system or the local file system. - * - * The number of backups to keep comes from $config->backup_auto_keep and - * $config->backup_auto_keep_copies. - * - * @param array $files existing backups - * @param bool $timeinkey endicate if the backup's time is in the key of the array - * @param int $now starting time of the process - * @param string $courseidnumber courseidnumer currently processed - * @return bool - */ - protected static function remove_old_backups($files, $timeinkey, $now, $courseidnumber) { - $config = get_config('backup'); - $dir = $config->backup_auto_destination; - $keep = (int)$config->backup_auto_keep; - $histkeep = (int)$config->backup_auto_keep_copies; - $histdays = (int)$config->backup_auto_keep_days; - - if ($timeinkey) { - // Sort by keys descending (newer to older filemodified). - krsort($files); - } else { - // Sort by values descending (newer to older filemodified). - arsort($files); - } - - $tokeep = $keep; - $oldbackup = false; - if ($histdays != 0) { - $keepcounter = 0; - foreach ($files as $key => $value) { - if ($timeinkey) { - $timemodified = $key; - } else { - $timemodified = $value; - } - if ($timemodified < ($now - ($histdays * DAYSECS)) || $keepcounter >= $keep) { - $oldbackup = true; - break; - } - $keepcounter++; - } - - if ($keepcounter < $histkeep) { - $tokeep = $histkeep; - } else { - $tokeep = $keepcounter; - } - } - - if (count($files) <= $tokeep) { - // There are less matching files than the desired number to keep there is nothing to clean up. - return false; - } - - $remove = array_splice($files, $tokeep); - if ($timeinkey) { - foreach ($remove as $file) { - $file->delete(); - } - } else { - foreach (array_keys($remove) as $file) { - unlink($dir . '/' . $file); - } - } - - if ($oldbackup) { - mtrace('Course '. $courseidnumber. ' removed '.count($remove).' old backup file(s) from the automated filearea'); - } - - return true; - } } diff --git a/backup/util/helper/tests/cronhelper_test.php b/backup/util/helper/tests/cronhelper_test.php index cb88d5376e0..320daacfbfa 100644 --- a/backup/util/helper/tests/cronhelper_test.php +++ b/backup/util/helper/tests/cronhelper_test.php @@ -244,4 +244,100 @@ class backup_cron_helper_testcase extends advanced_testcase { $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); $this->assertEquals(date('w-20:00'), date('w-H:i', $next)); } + + /** + * Test {@link backup_cron_automated_helper::get_backups_to_delete}. + */ + public function test_get_backups_to_delete() { + $this->resetAfterTest(); + // Active only backup_auto_max_kept config to 2 days. + set_config('backup_auto_max_kept', '2', 'backup'); + set_config('backup_auto_delete_days', '0', 'backup'); + set_config('backup_auto_min_kept', '0', 'backup'); + + // No backups to delete. + $backupfiles = array( + '1000000000' => 'file1.mbz', + '1000432000' => 'file3.mbz' + ); + $deletedbackups = testable_backup_cron_automated_helper::testable_get_backups_to_delete($backupfiles, 1000432000); + $this->assertFalse($deletedbackups); + + // Older backup to delete. + $backupfiles['1000172800'] = 'file2.mbz'; + $deletedbackups = testable_backup_cron_automated_helper::testable_get_backups_to_delete($backupfiles, 1000432000); + $this->assertEquals(1, count($deletedbackups)); + $this->assertArrayHasKey('1000000000', $backupfiles); + $this->assertEquals('file1.mbz', $backupfiles['1000000000']); + + // Activate backup_auto_max_kept to 5 days and backup_auto_delete_days to 10 days. + set_config('backup_auto_max_kept', '5', 'backup'); + set_config('backup_auto_delete_days', '10', 'backup'); + set_config('backup_auto_min_kept', '0', 'backup'); + + // No backups to delete. Timestamp is 1000000000 + 10 days. + $backupfiles['1000432001'] = 'file4.mbz'; + $backupfiles['1000864000'] = 'file5.mbz'; + $deletedbackups = testable_backup_cron_automated_helper::testable_get_backups_to_delete($backupfiles, 1000864000); + $this->assertFalse($deletedbackups); + + // One old backup to delete. Timestamp is 1000000000 + 10 days + 1 second. + $deletedbackups = testable_backup_cron_automated_helper::testable_get_backups_to_delete($backupfiles, 1000864001); + $this->assertEquals(1, count($deletedbackups)); + $this->assertArrayHasKey('1000000000', $backupfiles); + $this->assertEquals('file1.mbz', $backupfiles['1000000000']); + + // Two old backups to delete. Timestamp is 1000000000 + 12 days + 1 second. + $deletedbackups = testable_backup_cron_automated_helper::testable_get_backups_to_delete($backupfiles, 1001036801); + $this->assertEquals(2, count($deletedbackups)); + $this->assertArrayHasKey('1000000000', $backupfiles); + $this->assertEquals('file1.mbz', $backupfiles['1000000000']); + $this->assertArrayHasKey('1000172800', $backupfiles); + $this->assertEquals('file2.mbz', $backupfiles['1000172800']); + + // Activate backup_auto_max_kept to 5 days, backup_auto_delete_days to 10 days and backup_auto_min_kept to 2. + set_config('backup_auto_max_kept', '5', 'backup'); + set_config('backup_auto_delete_days', '10', 'backup'); + set_config('backup_auto_min_kept', '2', 'backup'); + + // Three instead of four old backups are deleted. Timestamp is 1000000000 + 16 days. + $deletedbackups = testable_backup_cron_automated_helper::testable_get_backups_to_delete($backupfiles, 1001382400); + $this->assertEquals(3, count($deletedbackups)); + $this->assertArrayHasKey('1000000000', $backupfiles); + $this->assertEquals('file1.mbz', $backupfiles['1000000000']); + $this->assertArrayHasKey('1000172800', $backupfiles); + $this->assertEquals('file2.mbz', $backupfiles['1000172800']); + $this->assertArrayHasKey('1000432000', $backupfiles); + $this->assertEquals('file3.mbz', $backupfiles['1000432000']); + + // Three instead of all five backups are deleted. Timestamp is 1000000000 + 60 days. + $deletedbackups = testable_backup_cron_automated_helper::testable_get_backups_to_delete($backupfiles, 1005184000); + $this->assertEquals(3, count($deletedbackups)); + $this->assertArrayHasKey('1000000000', $backupfiles); + $this->assertEquals('file1.mbz', $backupfiles['1000000000']); + $this->assertArrayHasKey('1000172800', $backupfiles); + $this->assertEquals('file2.mbz', $backupfiles['1000172800']); + $this->assertArrayHasKey('1000432000', $backupfiles); + $this->assertEquals('file3.mbz', $backupfiles['1000432000']); + } +} + +/** + * Provides access to protected methods we want to explicitly test + * + * @copyright 2015 Jean-Philippe Gaudreau + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class testable_backup_cron_automated_helper extends backup_cron_automated_helper { + + /** + * Provides access to protected method get_backups_to_remove. + * + * @param array $backupfiles Existing backup files + * @param int $now Starting time of the process + * @return array Backup files to remove + */ + public static function testable_get_backups_to_delete($backupfiles, $now) { + return parent::get_backups_to_delete($backupfiles, $now); + } } diff --git a/lang/en/backup.php b/lang/en/backup.php index eedd2735ea0..c0c00783cca 100644 --- a/lang/en/backup.php +++ b/lang/en/backup.php @@ -26,15 +26,15 @@ $string['autoactivedisabled'] = 'Disabled'; $string['autoactiveenabled'] = 'Enabled'; $string['autoactivemanual'] = 'Manual'; $string['autoactivedescription'] = 'Choose whether or not to do automated backups. If manual is selected automated backups will be possible only by through the automated backups CLI script. This can be done either manually on the command line or through cron.'; -$string['automatedbackupkeepcopies'] = 'Number of backups to keep'; -$string['automatedbackupkeepcopieshelp'] = 'Choose the minimum number of automated backups to keep.'; -$string['automatedbackupkeepdays'] = 'Remove backups after'; -$string['automatedbackupkeepdayshelp'] = 'Indicate after how many days you want to remove automated backups.'; -$string['automatedbackupremovalsettings'] = 'Automated backup removal settings'; $string['automatedbackupschedule'] = 'Schedule'; $string['automatedbackupschedulehelp'] = 'Choose which days of the week to perform automated backups.'; $string['automatedbackupsinactive'] = 'Automated backups haven\'t been enabled by the site admin'; $string['automatedbackupstatus'] = 'Automated backup status'; +$string['automateddeletedays'] = 'Delete backups older than'; +$string['automatedmaxkept'] = 'Maximum number of backups kept'; +$string['automatedmaxkepthelp'] = 'This specifies the maximum number of recent automated backups to be kept for each course. Older backups will be deleted automatically.'; +$string['automatedminkept'] = 'Minimum number of backups kept'; +$string['automatedminkepthelp'] = 'If backups older than a specified number of days are deleted, it can happen that an inactive course ends up with no backup. To prevent this, a minimum number of backups kept should be specified.'; $string['automatedsetup'] = 'Automated backup setup'; $string['automatedsettings'] = 'Automated backup settings'; $string['automatedstorage'] = 'Automated backup storage'; diff --git a/lang/en/moodle.php b/lang/en/moodle.php index 4a6e3fcb091..2085e55af91 100644 --- a/lang/en/moodle.php +++ b/lang/en/moodle.php @@ -186,7 +186,6 @@ $string['backupfromthissite'] = 'Backup was made on this site?'; $string['backupgradebookhistoryhelp'] = 'If enabled then gradebook history will be included in automated backups. Note that grade history must not be disabled in server settings (disablegradehistory) in order for this to work'; $string['backupincludemoduleshelp'] = 'Choose whether you want to include course modules, with or without user data, in automated backups'; $string['backupincludemoduleuserdatahelp'] = 'Choose whether you want to include module user data in automated backups.'; -$string['backupkeephelp'] = 'How many recent backups for each course do you want to keep? (older ones will be deleted automatically)'; $string['backuplogdetailed'] = 'Detailed execution log'; $string['backuploglaststatus'] = 'Last execution log'; $string['backupmissinguserinfoperms'] = 'Note: This backup contains no user data. Exercise and Workshop activities will not be included in the backup, since these modules are not compatible with this type of backup.'; diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index fd98221e183..20b5aaae50b 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -4572,5 +4572,17 @@ function xmldb_main_upgrade($oldversion) { upgrade_main_savepoint(true, 2015092200.00); } + if ($oldversion < 2015092400.01) { + // Rename backup_auto_keep setting to backup_auto_max_kept. + $keep = get_config('backup', 'backup_auto_keep'); + if ($keep !== false) { + set_config('backup_auto_max_kept', $keep, 'backup'); + unset_config('backup_auto_keep', 'backup'); + } + + // Main savepoint reached. + upgrade_main_savepoint(true, 2015092400.01); + } + return true; } diff --git a/version.php b/version.php index 19abbe40295..4622b2aa700 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2015092400.00; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2015092400.01; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes.