Merge branch 'MDL-41210-master' of git://github.com/FMCorz/moodle

This commit is contained in:
Sam Hemelryk
2013-08-21 10:21:04 +12:00
4 changed files with 90 additions and 69 deletions
+33 -47
View File
@@ -37,31 +37,6 @@ require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
*/
class tool_uploadcourse_helper {
/**
* Remove the restore content from disk and cache.
*
* @return void
*/
public static function clean_restore_content() {
global $CFG;
// There are some sloppy unclosed file handles in backup/restore code,
// let's hope somebody unset all controllers before calling this
// and destroy magic will close all remaining open file handles,
// otherwise Windows will fail deleting the directory.
gc_collect_cycles();
if (!empty($CFG->keeptempdirectoriesonbackup)) {
$cache = cache::make('tool_uploadcourse', 'helper');
$backupids = (array) $cache->get('backupids');
foreach ($backupids as $cachekey => $backupid) {
$cache->delete($cachekey);
fulldelete("$CFG->tempdir/backup/$backupid/");
}
$cache->delete('backupids');
}
}
/**
* Generate a shortname based on a template.
*
@@ -216,7 +191,9 @@ class tool_uploadcourse_helper {
* Get the restore content tempdir.
*
* The tempdir is the sub directory in which the backup has been extracted.
* This caches the result for better performance.
*
* This caches the result for better performance, but $CFG->keeptempdirectoriesonbackup
* needs to be enabled, otherwise the cache is ignored.
*
* @param string $backupfile path to a backup file.
* @param string $shortname shortname of a course.
@@ -229,6 +206,10 @@ class tool_uploadcourse_helper {
$cachekey = null;
if (!empty($backupfile)) {
$backupfile = realpath($backupfile);
if (empty($backupfile) || !is_readable($backupfile)) {
$errors['cannotreadbackupfile'] = new lang_string('cannotreadbackupfile', 'tool_uploadcourse');
return false;
}
$cachekey = 'backup_path:' . $backupfile;
} else if (!empty($shortname) || is_numeric($shortname)) {
$cachekey = 'backup_sn:' . $shortname;
@@ -238,23 +219,27 @@ class tool_uploadcourse_helper {
return false;
}
$cache = cache::make('tool_uploadcourse', 'helper');
if (($backupid = $cache->get($cachekey)) === false) {
// Use false instead of null because it would consider that the cache
// key has not been set.
$backupid = false;
// If $CFG->keeptempdirectoriesonbackup is not set to true, any restore happening would
// automatically delete the backup directory... causing the cache to return an unexisting directory.
$usecache = !empty($CFG->keeptempdirectoriesonbackup);
if ($usecache) {
$cache = cache::make('tool_uploadcourse', 'helper');
}
// If we don't use the cache, or if we do and not set, or the directory doesn't exist any more.
if (!$usecache || (($backupid = $cache->get($cachekey)) === false || !is_dir("$CFG->tempdir/backup/$backupid"))) {
// Use null instead of false because it would consider that the cache key has not been set.
$backupid = null;
if (!empty($backupfile)) {
if (!is_readable($backupfile)) {
$errors['cannotreadbackupfile'] = new lang_string('cannotreadbackupfile', 'tool_uploadcourse');
} else {
// Extracting the backup file.
$packer = get_file_packer('application/vnd.moodle.backup');
$backupid = restore_controller::get_tempdir_name(SITEID, $USER->id);
$path = "$CFG->tempdir/backup/$backupid/";
$result = $packer->extract_to_pathname($backupfile, $path);
if (!$result) {
$errors['invalidbackupfile'] = new lang_string('invalidbackupfile', 'tool_uploadcourse');
}
// Extracting the backup file.
$packer = get_file_packer('application/vnd.moodle.backup');
$backupid = restore_controller::get_tempdir_name(SITEID, $USER->id);
$path = "$CFG->tempdir/backup/$backupid/";
$result = $packer->extract_to_pathname($backupfile, $path);
if (!$result) {
$errors['invalidbackupfile'] = new lang_string('invalidbackupfile', 'tool_uploadcourse');
}
} else if (!empty($shortname) || is_numeric($shortname)) {
// Creating restore from an existing course.
@@ -270,14 +255,15 @@ class tool_uploadcourse_helper {
new lang_string('coursetorestorefromdoesnotexist', 'tool_uploadcourse');
}
}
$cache->set($cachekey, $backupid);
// Store all the directories to be able to remove them in self::clean_restore_content().
$backupids = (array) $cache->get('backupids');
$backupids[$cachekey] = $backupid;
$cache->set('backupids', $backupids);
if ($usecache) {
$cache->set($cachekey, $backupid);
}
}
if ($backupid === null) {
$backupid = false;
}
return $backupid;
}
@@ -223,8 +223,6 @@ class tool_uploadcourse_processor {
$tracker->finish();
$tracker->results($total, $created, $updated, $deleted, $errors);
$this->remove_restore_content();
}
/**
@@ -349,20 +347,10 @@ class tool_uploadcourse_processor {
}
$tracker->finish();
$this->remove_restore_content();
return $preview;
}
/**
* Delete the restore object.
*
* @return void
*/
protected function remove_restore_content() {
tool_uploadcourse_helper::clean_restore_content();
}
/**
* Reset the current process.
*
@@ -635,6 +635,23 @@ class tool_uploadcourse_course_testcase extends advanced_testcase {
}
$this->assertTrue($found);
// Restoring twice from the same course should work.
$data = array('shortname' => 'B1', 'templatecourse' => $c1->shortname, 'summary' => 'B', 'category' => 1,
'fullname' => 'B1');
$co = new tool_uploadcourse_course($mode, $updatemode, $data);
$this->assertTrue($co->prepare());
$co->proceed();
$course = $DB->get_record('course', array('shortname' => 'B1'));
$modinfo = get_fast_modinfo($course);
$found = false;
foreach ($modinfo->get_cms() as $cmid => $cm) {
if ($cm->modname == 'forum' && $cm->name == $c1f1->name) {
$found = true;
break;
}
}
$this->assertTrue($found);
// Restore the time limit to prevent warning.
set_time_limit(0);
}
@@ -668,6 +685,25 @@ class tool_uploadcourse_course_testcase extends advanced_testcase {
}
$this->assertTrue($found);
// Restoring twice from the same file should work.
$data = array('shortname' => 'B1', 'backupfile' => __DIR__ . '/fixtures/backup.mbz',
'summary' => 'B', 'category' => 1, 'fullname' => 'B1');
$co = new tool_uploadcourse_course($mode, $updatemode, $data);
$this->assertTrue($co->prepare());
$co->proceed();
$course = $DB->get_record('course', array('shortname' => 'B1'));
$modinfo = get_fast_modinfo($course);
$found = false;
foreach ($modinfo->get_cms() as $cmid => $cm) {
if ($cm->modname == 'glossary' && $cm->name == 'Imported Glossary') {
$found = true;
} else if ($cm->modname == 'forum' && $cm->name == $c1f1->name) {
// We should not find this!
$this->assertTrue(false);
}
}
$this->assertTrue($found);
// Restore the time limit to prevent warning.
set_time_limit(0);
}
+21 -10
View File
@@ -141,6 +141,9 @@ class tool_uploadcourse_helper_testcase extends advanced_testcase {
$bc->destroy();
unset($bc); // File logging is a mess, we can only try to rely on gc to close handles.
$oldcfg = isset($CFG->keeptempdirectoriesonbackup) ? $CFG->keeptempdirectoriesonbackup : false;
$CFG->keeptempdirectoriesonbackup = true;
// Checking restore dir.
$dir = tool_uploadcourse_helper::get_restore_content_dir($c1backupfile, null);
$bcinfo = backup_general_helper::get_backup_information($dir);
@@ -179,18 +182,26 @@ class tool_uploadcourse_helper_testcase extends advanced_testcase {
$this->assertFalse($dir);
$this->assertArrayHasKey('coursetorestorefromdoesnotexist', $errors);
// Cleaning content directories.
$oldcfg = isset($CFG->keeptempdirectoriesonbackup) ? $CFG->keeptempdirectoriesonbackup : false;
$dir = "$CFG->tempdir/backup/$dir";
$this->assertTrue(file_exists($dir));
// Trying again without caching. $CFG->keeptempdirectoriesonbackup is required for caching.
$CFG->keeptempdirectoriesonbackup = false;
tool_uploadcourse_helper::clean_restore_content();
$this->assertTrue(file_exists($dir));
$CFG->keeptempdirectoriesonbackup = true;
tool_uploadcourse_helper::clean_restore_content();
$this->assertFalse(file_exists($dir));
// Checking restore dir.
$dir = tool_uploadcourse_helper::get_restore_content_dir($c1backupfile, null);
$dir2 = tool_uploadcourse_helper::get_restore_content_dir($c1backupfile, null);
$this->assertNotEquals($dir, $dir2);
// Checking with a shortname.
$dir = tool_uploadcourse_helper::get_restore_content_dir(null, $c1->shortname);
$dir2 = tool_uploadcourse_helper::get_restore_content_dir(null, $c1->shortname);
$this->assertNotEquals($dir, $dir2);
// Get a course that does not exist.
$errors = array();
$dir = tool_uploadcourse_helper::get_restore_content_dir(null, 'DoesNotExist', $errors);
$this->assertFalse($dir);
$this->assertArrayHasKey('coursetorestorefromdoesnotexist', $errors);
$dir2 = tool_uploadcourse_helper::get_restore_content_dir(null, 'DoesNotExist', $errors);
$this->assertEquals($dir, $dir2);
$CFG->keeptempdirectoriesonbackup = $oldcfg;