]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-8605 More changes to upgrade and restore, and some unit tests with db and rs...
authornicolasconnault <nicolasconnault>
Fri, 12 Oct 2007 19:13:18 +0000 (19:13 +0000)
committernicolasconnault <nicolasconnault>
Fri, 12 Oct 2007 19:13:18 +0000 (19:13 +0000)
backup/backuplib.php
backup/lib.php
backup/restorelib.php
lib/dmllib.php
lib/gdlib.php
lib/moodlelib.php
lib/simpletest/testbackuplib.php [new file with mode: 0644]

index 84beeac159c1b1f5377da94f8ba593bb18e0eff2..b80908f13e31fddfb6ff8a9a9879e2031799a547 100644 (file)
 
         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']}");
             }
         }
 
index 2a309c54f3afba84af0c382a55fcc64f8fcf79d1..05b267687c8af28df30ce557502362b86181c843 100644 (file)
         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)) {
index 12d91450678e2edd88bf6cc7bcc7ec400e68290d..10666adb0d6ef3abc149e4b8870e6067e245c5f4 100644 (file)
 
         $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);
                         }
                     }
                 }
index ae0026bdb28e6a4bfa1bd561f8314ebd576b6bf2..514b45e888112f1e840d3853908301ba78420911 100644 (file)
@@ -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
index 9e39ad5835dbc065861f073130c23b4868fc5827..932806d180253b89e7f7c1866f2c356fc68ff0cf 100644 (file)
@@ -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;
         }
     }
index 59fecc8c9b15e4c2403b66bb22c98d8b746ab725..edd3286f6f69a3e6860ba7eaec0fbdc61819a16c 100644 (file)
@@ -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 (file)
index 0000000..b237dc2
--- /dev/null
@@ -0,0 +1,135 @@
+<?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']);
+        }
+    } 
+}
+
+?>