From: nicolasconnault Date: Fri, 12 Oct 2007 19:13:18 +0000 (+0000) Subject: MDL-8605 More changes to upgrade and restore, and some unit tests with db and rs... X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=ddaadc7c786c44dcfe04b0e90de4ae7861f49eb9;p=moodle.git MDL-8605 More changes to upgrade and restore, and some unit tests with db and rs mock objects --- diff --git a/backup/backuplib.php b/backup/backuplib.php index 84beeac159..b80908f13e 100644 --- a/backup/backuplib.php +++ b/backup/backuplib.php @@ -346,7 +346,7 @@ global $CFG; - $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/user_files",true); + $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code."/user_files",true, true); return $status; } @@ -2174,26 +2174,18 @@ //in temp/backup/$backup_code dir $status = check_and_create_user_files_dir($preferences->backup_unique_code); - //Now iterate over directories under "users" to check if that user must be - //copied to backup + //Now iterate over directories under "user" to check if that user must be copied to backup - $rootdir = $CFG->dataroot."/users"; - //Check if directory exists - if (is_dir($rootdir)) { - $list = list_directories ($rootdir); - if ($list) { - //Iterate - foreach ($list as $dir) { - //Look for dir like username in backup_ids - $data = get_record ("backup_ids","backup_code",$preferences->backup_unique_code, - "table_name","user", - "old_id",$dir); - //If exists, copy it - if ($data) { - $status = backup_copy_file($rootdir."/".$dir, - $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/user_files/".$dir); - } - } + // Method to get a list of userid=>array(basedir => $basedir, userfolder => $userfolder) + $userlist = get_user_directories(); + + foreach ($userlist as $userid => $userinfo) { + //Look for dir like username in backup_ids + $data = count_records("backup_ids","backup_code",$preferences->backup_unique_code, "table_name","user", "old_id",$userid); + //If exists, copy it + if ($data) { + $status = backup_copy_file($userinfo['basedir'] . '/' . $userinfo['userfolder'], + "$CFG->dataroot/temp/backup/$preferences->backup_unique_code/user_files/{$userinfo['userfolder']}"); } } diff --git a/backup/lib.php b/backup/lib.php index 2a309c54f3..05b267687c 100644 --- a/backup/lib.php +++ b/backup/lib.php @@ -305,7 +305,7 @@ if (!is_dir($to_file)) { //echo "
Creating ".$to_file; //Debug umask(0000); - $status = mkdir($to_file,$CFG->directorypermissions); + $status = check_dir_exists($to_file, true, true); } $dir = opendir($from_file); while ($file=readdir($dir)) { diff --git a/backup/restorelib.php b/backup/restorelib.php index 12d9145067..10666adb0d 100644 --- a/backup/restorelib.php +++ b/backup/restorelib.php @@ -3200,48 +3200,56 @@ $counter = 0; - //First, we check to "users" exists and create is as necessary + // 'users' is the old users folder, 'user' is the new one, with a new hierarchy. Detect which one is here and treat accordingly //in CFG->dataroot - $dest_dir = $CFG->dataroot."/users"; + $dest_dir = $CFG->dataroot."/user"; $status = check_dir_exists($dest_dir,true); //Now, we iterate over "user_files" records to check if that user dir must be //copied (and renamed) to the "users" dir. $rootdir = $CFG->dataroot."/temp/backup/".$restore->backup_unique_code."/user_files"; + //Check if directory exists - if (is_dir($rootdir)) { - $list = list_directories ($rootdir); - if ($list) { - //Iterate - $counter = 0; - foreach ($list as $dir) { - //Look for dir like username in backup_ids - $data = get_record ("backup_ids","backup_code",$restore->backup_unique_code, - "table_name","user", - "old_id",$dir); - //If thar user exists in backup_ids - if ($data) { - //Only it user has been created now - //or if it existed previously, but he hasn't image (see bug 1123) - if ((strpos($data->info,"new") !== false) or - (!check_dir_exists($dest_dir."/".$data->new_id,false))) { - //Copy the old_dir to its new location (and name) !! - //Only if destination doesn't exists - if (!file_exists($dest_dir."/".$data->new_id)) { - $status = backup_copy_file($rootdir."/".$dir, - $dest_dir."/".$data->new_id,true); - $counter ++; - } - //Do some output - if ($counter % 2 == 0) { - if (!defined('RESTORE_SILENTLY')) { - echo "."; - if ($counter % 40 == 0) { - echo "
"; - } + $userlist = array(); + + if (is_dir($rootdir) && ($list = list_directories ($rootdir))) { + $counter = 0; + foreach ($list as $dir) { + // If there are directories in this folder, we are in the new user hierarchy + if ($newlist = list_directories("$rootdir/$dir")) { + foreach ($newlist as $userid) { + $userlist[$userid] = "$rootdir/$dir/$userid"; + } + } else { + $userlist[$userid] = "$rootdir/$dir"; + } + } + + foreach ($userlist as $userid => $backup_location) { + //Look for dir like username in backup_ids + $data = get_record ("backup_ids","backup_code",$restore->backup_unique_code, "table_name","user", "old_id",$userid); + + //If that user exists in backup_ids + if ($data) { + //Only if user has been created now or if it existed previously, but he hasn't got an image (see bug 1123) + $newuserdir = make_user_directory($userid, true); // Doesn't create the folder, just returns the location + + if ((strpos($data->info,"new") !== false) or (!check_dir_exists($newuserdir))) { + //Copy the old_dir to its new location (and name) !! Only if destination doesn't exists + if (!file_exists($newuserdir)) { + make_user_directory($userid); // Creates the folder + $status = backup_copy_file($backup_location, $newuserdir, true); + $counter ++; + } + //Do some output + if ($counter % 2 == 0) { + if (!defined('RESTORE_SILENTLY')) { + echo "."; + if ($counter % 40 == 0) { + echo "
"; } - backup_flush(300); } + backup_flush(300); } } } diff --git a/lib/dmllib.php b/lib/dmllib.php index ae0026bdb2..514b45e888 100644 --- a/lib/dmllib.php +++ b/lib/dmllib.php @@ -7,7 +7,7 @@ // Moodle - Modular Object-Oriented Dynamic Learning Environment // // http://moodle.com // // // -// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com // +// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -490,11 +490,11 @@ function get_record_sql($sql, $expectmultiple=false, $nolimit=false) { } else if ($recordcount == 1) { // Found one record /// DIRTY HACK to retrieve all the ' ' (1 space) fields converted back /// to '' (empty string) for Oracle. It's the only way to work with - /// all those NOT NULL DEFAULT '' fields until we definetively delete them + /// all those NOT NULL DEFAULT '' fields until we definitively delete them if ($CFG->dbfamily == 'oracle') { array_walk($rs->fields, 'onespace2empty'); } - /// End od DIRTY HACK + /// End of DIRTY HACK return (object)$rs->fields; } else { // Error: found more than one record diff --git a/lib/gdlib.php b/lib/gdlib.php index 9e39ad5835..932806d180 100644 --- a/lib/gdlib.php +++ b/lib/gdlib.php @@ -125,7 +125,7 @@ function save_profile_image($id, $uploadmanager, $dir='user') { } if (!file_exists($destination)) { - if (!mkdir($destination, $CFG->directorypermissions)) { + if (!make_upload_directory(str_replace($CFG->dataroot . '/', '', $destination))) { return false; } } diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 59fecc8c9b..edd3286f6f 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -4153,6 +4153,51 @@ function make_user_directory($userid, $test=false) { } } +/** + * Returns an array of full paths to user directories, indexed by their userids. + * + * @param bool $only_non_empty Only return directories that contain files + * @param bool $legacy Search for user directories in legacy location (dataroot/users/userid) instead of (dataroot/user/section/userid) + * @return array An associative array: userid=>array(basedir => $basedir, userfolder => $userfolder) + */ +function get_user_directories($only_non_empty=true, $legacy=false) { + global $CFG; + + $rootdir = $CFG->dataroot."/user"; + + if ($legacy) { + $rootdir = $CFG->dataroot."/users"; + } + $dirlist = array(); + + //Check if directory exists + if (is_dir($rootdir)) { + if ($legacy) { + if ($userlist = get_directory_list($rootdir, '', true, true, false)) { + foreach ($userlist as $userid) { + $dirlist[$userid] = array('basedir' => $rootdir, 'userfolder' => $userid); + } + } else { + notify("no directories found under $rootdir"); + } + } else { + if ($grouplist =get_directory_list($rootdir, '', true, true, false)) { // directories will be in the form 0, 1000, 2000 etc... + foreach ($grouplist as $group) { + if ($userlist = get_directory_list("$rootdir/$group", '', true, true, false)) { + foreach ($userlist as $userid) { + $dirlist[$userid] = array('basedir' => $rootdir, 'userfolder' => $group . '/' . $userid); + } + } + } + } + } + } else { + notify("$rootdir does not exist!"); + return false; + } + return $dirlist; +} + /** * Returns current name of file on disk if it exists. * diff --git a/lib/simpletest/testbackuplib.php b/lib/simpletest/testbackuplib.php new file mode 100644 index 0000000000..b237dc2097 --- /dev/null +++ b/lib/simpletest/testbackuplib.php @@ -0,0 +1,135 @@ +dirroot . '/backup/backuplib.php'); +Mock::generate('ADODB_mysql'); +Mock::generate('ADORecordSet_mysql'); + +class backuplib_test extends UnitTestCase { + var $real_db; + var $real_dataroot; + var $rs; + var $firstcolumn; + var $db; + var $testfiles = array(); + var $userbasedir; + + function setUp() { + global $db, $CFG; + $this->real_db = fullclone($db); + $db = new MockADODB_mysql(); + $this->rs = new MockADORecordSet_mysql(); + $this->rs->EOF = false; + $this->firstcolumn = new stdClass(); + $this->firstcolumn->name = 'id'; + + // Override dataroot: we don't want to test with live data + $this->real_dataroot = fullclone($CFG->dataroot); + $CFG->dataroot .= '/unittests'; + $this->userbasedir = $CFG->dataroot.'/user'; + + // Create some sample files in this temporary directory + mkdir($CFG->dataroot); + mkdir($this->userbasedir); + + $this->testfiles = array('0/1','0/3','1000/1043','457498000/457498167'); + foreach ($this->testfiles as $file) { + $parts = explode('/', $file); + + if (!file_exists("$this->userbasedir/{$parts[0]}")) { + mkdir("$this->userbasedir/{$parts[0]}"); + } + mkdir("$this->userbasedir/$file"); + $handle = fopen("$this->userbasedir/$file/f1.gif", 'w+b'); + fclose($handle); + } + } + + function tearDown() { + global $CFG, $db; + + if (!is_null($this->real_dataroot) && $this->real_dataroot != $CFG->dataroot) { + remove_dir($CFG->dataroot); + } + $db = $this->real_db; + $CFG->dataroot = $this->real_dataroot; + } + + function test_backup_copy_user_files() { + global $CFG, $db; + $preferences = new stdClass(); + $preferences->backup_unique_code = time(); + + $db->setReturnValue('Execute', $this->rs); + $this->rs->setReturnValue('RecordCount', 1); + $this->rs->fields = array(1); + + // Perform the backup + backup_copy_user_files($preferences); + + // Check for the existence of the backup file + $this->assertTrue(file_exists("$CFG->dataroot/temp/backup/$preferences->backup_unique_code/user_files")); + + // Check for the existence of the user files in the backup file + foreach ($this->testfiles as $file) { + $parts = explode('/', $file); + $section = $parts[0]; + $userid = $parts[1]; + $this->assertTrue(file_exists("$CFG->dataroot/temp/backup/$preferences->backup_unique_code/user_files/$section/$userid/f1.gif")); + } + } + + /** + * This is a moodlelib method but it is used in backuplib, so it is tested here in that context, with typical backup data. + */ + function test_get_user_directories() { + global $CFG; + $dirlist = get_user_directories(); + $this->assertEqual(4, count($dirlist)); + + foreach ($this->testfiles as $file) { + $parts = explode('/', $file); + $section = $parts[0]; + $userid = $parts[1]; + + $this->assertEqual($file, $dirlist[$userid]['userfolder']); + $this->assertEqual($this->userbasedir, $dirlist[$userid]['basedir']); + } + } +} + +?>