]> git.mjollnir.org Git - moodle.git/commitdiff
Changes in:
authorstronk7 <stronk7>
Fri, 20 Jun 2003 19:42:20 +0000 (19:42 +0000)
committerstronk7 <stronk7>
Fri, 20 Jun 2003 19:42:20 +0000 (19:42 +0000)
   - Saving temp data to fs, instead of db
     (mysql limit bug OUT)
   - Modified clean directories (moodle standard delete dir
     function seems to work wrong with large dirs
   - Send info to browser continuosly to avoid timeouts.
   - Increase php execution time limit
   - More checks.
   - Restore into existing course now works fine
   - Create course_dir if it doesn't exist in the final step
     of backup.

backup/backuplib.php
backup/lib.php
backup/restorelib.php

index 284c5a4684fc638ca64426efdbee82d3030b5b49..60c2bea626d91e6dd37f9d09a706c0dc87a1c2df 100644 (file)
     
         global $CFG;
 
-        //Backup zip file name
+        //Define zip location (from)
         $from_zip_file = $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/".$preferences->backup_name;
-        $to_zip_file = $CFG->dataroot."/".$preferences->backup_course."/".get_string("backupdir")."/".$preferences->backup_name;
-   
-        //Check to directory
-        $status = check_dir_exists(dirname($to_zip_file),true);
-       
+
+        //Define zip destination (course dir)
+        $to_zip_file = $CFG->dataroot."/".$preferences->backup_course;
+
+        echo "<p>From: ".$from_zip_file."<br>";                                              //Debug
+
+        echo "<p>Checking: ".$to_zip_file."<br>";                                          //Debug
+
+        //Checks course dir exists
+        $status = check_dir_exists($to_zip_file,true);
+
+        //Define zip destination (backup dir)
+        $to_zip_file = $to_zip_file."/".get_string("backupdir");
+
+        echo "<p>Checking: ".$to_zip_file."<br>";                                          //Debug
+
+        //Checks backup dir exists
+        $status = check_dir_exists($to_zip_file,true);
+
+        //Define zip destination (zip file)
+        $to_zip_file = $to_zip_file."/".$preferences->backup_name;
+        
+        echo "<p>To: ".$to_zip_file."<br>";                                              //Debug
+
         //Copy zip file
         if ($status) {
             $status = backup_copy_file ($from_zip_file,$to_zip_file);
index b5f840274f01f566a068185345b8bde3ca093a35..46656297a7d6ac1bc8f5b26b233eece0154c66c3 100644 (file)
@@ -38,7 +38,7 @@
         foreach ($list as $file) {
             $file_path = $CFG->dataroot."/temp/backup/".$file;
             $moddate = filemtime($file_path);
-            if ($status and $moddate < $delete_from) {
+            if ($status && $moddate < $delete_from) {
                 //If directory, recurse
                 if (is_dir($file_path)) {
                     $status = delete_dir_contents($file_path);
     }
 
     //Function to delete all the directory contents recursively
-    //Copied from admin/delete.php
-    function delete_dir_contents ($rootdir) {
+    //Copied from the web !!
+    function delete_dir_contents ($dir) {
 
-        $dir = opendir($rootdir);
+        $slash = "/";
 
-        $status = true;
+        // Create arrays to store files and directories
+        $dir_files      = array();
+        $dir_subdirs    = array();
 
-        while ($file = readdir($dir)) {
-            if ($file != "." and $file != "..") {
-                $fullfile = "$rootdir/$file";
-                if (filetype($fullfile) == "dir") {
-                    delete_dir_contents($fullfile);
-                    if (!rmdir($fullfile)) {
-                        $status = false;
-                    }
-                } else {
-                    if (!unlink("$fullfile")) {
-                        $status = false;
-                    }
+        // Make sure we can delete it
+        chmod($dir, 0777);
+
+        if ((($handle = opendir($dir))) == FALSE) {
+            // The directory could not be opened
+            return false;
+        }
+
+        // Loop through all directory entries, and construct two temporary arrays containing files and sub directories
+        while($entry = readdir($handle)) {
+            if (is_dir($dir. $slash .$entry) && $entry !=  ".." && $entry !=  ".") {
+                $dir_subdirs[] = $dir. $slash .$entry;
+            }
+            else if ($entry !=  ".." && $entry !=  ".") {
+                $dir_files[] = $dir. $slash .$entry;
+            }
+        }
+
+        // Delete all files in the curent directory return false and halt if a file cannot be removed
+        for($i=0; $i<count($dir_files); $i++) {
+            chmod($dir_files[$i], 0777);
+            if (((unlink($dir_files[$i]))) == FALSE) {
+                return false;
+            }
+        }
+
+        // Empty sub directories and then remove the directory
+        for($i=0; $i<count($dir_subdirs); $i++) {
+            chmod($dir_subdirs[$i], 0777);
+            if (delete_dir_contents($dir_subdirs[$i]) == FALSE) {
+                return false;
+            }
+            else {
+                if (rmdir($dir_subdirs[$i]) == FALSE) {
+                return false;
                 }
             }
         }
-        closedir($dir);
-        return $status;
 
+        // Close directory
+        closedir($handle);
+
+        // Success, every thing is gone return true
+        return true;
     }
 
     //Function to clear (empty) the contents of the backup_dir
-    //Copied from admin/delete.php
     function clear_backup_dir($backup_unique_code) {
   
         global $CFG; 
     }
  
     //This function is used to insert records in the backup_ids table
+    //If the info field is greater than max_db_storage, then its info
+    //is saved to filesystem
     function backup_putid ($backup_unique_code, $table, $old_id, $new_id, $info="") {
 
         global $CFG;
+
+        $max_db_storage = 128;  //Max bytes to save to db, else save to file
+                                //MUST BE LOWER THAN 256 (VARCHAR LIMIT)
  
         $status = true;
         
         //First delete to avoid PK duplicates
         $status = backup_delid($backup_unique_code, $table, $old_id);
 
-        $status = execute_sql("INSERT INTO {$CFG->prefix}backup_ids
-                                   (backup_code, table_name, old_id, new_id, info)
-                               VALUES 
-                                   ($backup_unique_code, '$table', '$old_id', '$new_id', '$info')",false);
+        //Now, serialize info
+        $info_ser = serialize($info);
+
+        //Now, if the size of $info_ser > $max_db_storage, save it to filesystem and 
+        //insert a "infile" in the info field
+
+        if (strlen($info_ser) > $max_db_storage) {
+            //Calculate filename (in current_backup_dir, $backup_unique_code_$table_$old_id.info)
+            $filename = $CFG->dataroot."/temp/backup/".$backup_unique_code."/".$backup_unique_code."_".$table."_".$old_id.".info";
+            //Save data to file
+            $status = backup_data2file($filename,$info_ser); 
+            //Set info_to save
+            $info_to_save = "infile";
+        } else {
+            //Saving to db, addslashes
+            $info_to_save = addslashes($info_ser);
+        }
+
+        //Now, insert the record
+        if ($status) {
+            $status = execute_sql("INSERT INTO {$CFG->prefix}backup_ids
+                                       (backup_code, table_name, old_id, new_id, info)
+                                   VALUES 
+                                       ($backup_unique_code, '$table', '$old_id', '$new_id', '$info_to_save')",false);
+        }
         return $status;
     }
 
     //This function is used to delete recods from the backup_ids table
+    //If the info field is "infile" then the file is deleted too
     function backup_delid ($backup_unique_code, $table, $old_id) {
 
         global $CFG;
     }
 
     //This function is used to get a record from the backup_ids table
+    //If the info field is "infile" then its info
+    //is read from filesystem
     function backup_getid ($backup_unique_code, $table, $old_id) {
 
         global $CFG;
 
         $status = true;
+        $status2 = true;
 
         $status = get_record ("backup_ids","backup_code",$backup_unique_code,
                                            "table_name",$table, 
                                            "old_id", $old_id);
 
+        //If info field = "infile", get file contents
+        if ($status->info == "infile") {
+            $filename = $CFG->dataroot."/temp/backup/".$backup_unique_code."/".$backup_unique_code."_".$table."_".$old_id.".info";
+            //Read data from file
+            $status2 = backup_file2data($filename,$info);
+            if ($status2) {
+                //unserialize data
+                $status->info = unserialize($info);
+            } else {
+                $status = false;
+            }
+        } else {
+            ////First strip slashes
+            $temp = stripslashes($status->info);
+            //Now unserialize
+            $status->info = unserialize($temp);
+        }
+
         return $status;
     }
 
         flush();
     }
     
+    //This function creates the filename and write data to it
+    //returning status as result
+    function backup_data2file ($file,&$data) {
+
+        $status = true;
+        $status2 = true;
+    
+        $f = fopen($file,"w");
+        $status = fwrite($f,$data);
+        $status2 = fclose($f);
+
+        return ($status && $status2);
+    }
 
+    //This function read the filename and read data from it
+    function backup_file2data ($file,&$data) {
+
+        $status = true;
+        $status2 = true;
+
+        $f = fopen($file,"r");
+        $data = fread ($f,filesize($file));
+        $status2 = fclose($f);
+
+        return ($status && $status2);
+    }
 ?>
index eda79326d783286bcd24554994134d554e5b763e..beffb6dfc51c42cf5793b157d029e0e33f541528 100644 (file)
             //For each, user, take its info from backup_ids
             foreach ($info->users as $userid) {
                 $rec = backup_getid($restore->backup_unique_code,"user",$userid); 
-                //First strip slashes 
-                $temp = stripslashes($rec->info);
-                //Now unserialize
-                $user = unserialize($temp);
+                $user = $rec->info;
                 //Calculate if it is a course user
                 //Has role teacher or student or admin or coursecreator
                 $is_course_user = ($user->roles[teacher] or $user->roles[student] or
         //Now, if we have anything in info, we have to restore that mods
         //from backup_ids (calling every mod restore function)
         if ($info) {
-            //Iterate over each module
-            foreach ($info as $mod) {
-                $modrestore = $mod->modtype."_restore_mods";
-                if (function_exists($modrestore)) {
-                    //print_object ($mod);                                                //Debug
-                    $status = $modrestore($mod,$restore);
-                } else {
-                    //Something was wrong. Function should exist.
-                    $status = false;
+            if ($info !== true) {
+                //Iterate over each module
+                foreach ($info as $mod) {
+                    $modrestore = $mod->modtype."_restore_mods";
+                    if (function_exists($modrestore)) {
+                        //print_object ($mod);                                                //Debug
+                        $status = $modrestore($mod,$restore);
+                    } else {
+                        //Something was wrong. Function should exist.
+                        $status = false;
+                    }
                 }
             }
         } else {
         $status = true;
 
         //We are going to iterate over each course_module saved in backup_ids
-        $course_modules = get_records_sql("SELECT new_id,info as instance
+        $course_modules = get_records_sql("SELECT old_id,new_id
                                            FROM {$CFG->prefix}backup_ids
                                            WHERE backup_code = '$restore->backup_unique_code' AND
                                                  table_name = 'course_modules'");
         if ($course_modules) {
             foreach($course_modules as $cm) {
+                //Get full record, using backup_getids
+                $cm_module = backup_getid($restore->backup_unique_code,"course_modules",$cm->old_id);
                 //Now we are going to the REAL course_modules to get its type (field module)
-                $module = get_record("course_modules","id",$cm->new_id);
+                $module = get_record("course_modules","id",$cm_module->new_id);
                 if ($module) {
                     //We know the module type id. Get the name from modules
                     $type = get_record("modules","id",$module->module);
                     if ($type) {
                         //We know the type name and the old_id. Get its new_id
                         //from backup_ids. It's the instance !!!
-                        $instance = get_record("backup_ids","backup_code",$restore->backup_unique_code,
-                                                            "table_name",$type->name,
-                                                            "old_id",$cm->instance);
+                        $instance =  backup_getid($restore->backup_unique_code,$type->name,$cm_module->info);
                         if ($instance) {
                             //We have the new instance, so update the record in course_modules
                             $module->instance = $instance->new_id;
                     $status = false;
                }
             }
-        } else {
-            $status = false;
         }
 
 
     class MoodleParser {
 
         var $level = 0;        //Level we are
+        var $counter = 0;      //Counter
         var $tree = array();   //Array of levels we are
         var $content = "";     //Content under current level
         var $todo = "";        //What we hav to do when parsing
             $this->level++;
             $this->tree[$this->level] = $tagName;   
 
-            //Output something to avoid browser timeouts...
-            backup_flush();
-
             //Check if we are into USERS zone  
             //if ($this->tree[3] == "USERS")                                                            //Debug
             //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br>\n";   //Debug
             $this->level++;
             $this->tree[$this->level] = $tagName;
 
+if ($tagName == "MOD" && $this->tree[3] == "MODULES") {
+echo "<P>MOD: ".strftime ("%X",time()),"-";
+}
+
             //Output something to avoid browser timeouts...
             backup_flush();
 
                 if ($this->level == 4) {
                     switch ($tagName) {
                         case "USER":
-                            //We've finalized a user, get it and save to db
-                            //First serialize
-                            $ser_temp = serialize($this->info->tempuser);
-                            //Now add slashes
-                            $sla_temp = addslashes($ser_temp);
+                            //Increment counter
+                            $this->counter++;
                             //Save to db
                             backup_putid($this->preferences->backup_unique_code,"user",$this->info->tempuser->id,
-                                          null,$sla_temp);
+                                          null,$this->info->tempuser);
+
+                            //Do some output   
+                            if ($this->counter % 10 == 0) {
+                                echo ".";
+                                if ($this->counter % 200 == 0) {
+                                echo "<br>";
+                                }
+                                backup_flush(300);
+                            }
+
                             //Delete temp obejct
                             unset($this->info->tempuser);
                             break;
             //Speed up a lot (avoid parse all)
             if ($tagName == "USERS" and $this->level == 3) {
                 $this->finished = true;
+                $this->counter = 0;
             }
 
             //Clear things
                     //Prepend XML standard header to info gathered
                     $xml_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".$this->temp;
                     //Call to xmlize for this portion of xml data (one MOD)
+                    echo "-XMLIZE: ".strftime ("%X",time()),"-";
                     $data = xmlize($xml_data);
+                    echo strftime ("%X",time())."<p>";
                     //traverse_xmlize($data);                                                                     //Debug
                     //print_object ($GLOBALS['traverse_array']);                                                  //Debug
                     //$GLOBALS['traverse_array']="";                                                              //Debug
                     $mod_type = $data["MOD"]["#"]["MODTYPE"]["0"]["#"];
                     //Only if we've selected to restore it
                     if  ($this->preferences->mods[$mod_type]->restore) {
-                        //Serialize it
-                        $mod_temp = serialize($data);
-                        //Now add slashes
-                        $sla_mod_temp = addslashes($mod_temp);
                         //Save to db
                         $status = backup_putid($this->preferences->backup_unique_code,$mod_type,$mod_id,
-                                     null,$sla_mod_temp);
+                                     null,$data);
                         //echo "<p>id: ".$mod_id."-".$mod_type." len.: ".strlen($sla_mod_temp)." to_db: ".$status."<p>";   //Debug
                         //Create returning info
                         $ret_info->id = $mod_id;
                         $ret_info->modtype = $mod_type;
                         $this->info[] = $ret_info;
                     }
-                    //Reset info to empty
-                    $this->temp = "";
+                    //Reset temp
+                    unset($this->temp);
                 }
             }
 
         //Clear parser mem
         xml_parser_free($xml_parser);
 
-        if ($status) {
+        if ($status && $info) {
             return $info;
         } else {
             return $status;