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;
}
//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']}");
}
}
if (!is_dir($to_file)) {
//echo "<br />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)) {
$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 "<br />";
- }
+ $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 "<br />";
}
- backup_flush(300);
}
+ backup_flush(300);
}
}
}
// 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 //
} 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
}
if (!file_exists($destination)) {
- if (!mkdir($destination, $CFG->directorypermissions)) {
+ if (!make_upload_directory(str_replace($CFG->dataroot . '/', '', $destination))) {
return 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.
*
--- /dev/null
+<?php // $Id$
+
+///////////////////////////////////////////////////////////////////////////
+// //
+// NOTICE OF COPYRIGHT //
+// //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment //
+// http://moodle.org //
+// //
+// 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 //
+// the Free Software Foundation; either version 2 of the License, or //
+// (at your option) any later version. //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License for more details: //
+// //
+// http://www.gnu.org/copyleft/gpl.html //
+// //
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ * Unit tests for (some of) ../../backup/backuplib.php.
+ *
+ * @author nicolasconnault@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package moodlecore
+ */
+
+if (!defined('MOODLE_INTERNAL')) {
+ die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
+}
+
+require_once($CFG->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']);
+ }
+ }
+}
+
+?>