Changes in:

- 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.
This commit is contained in:
stronk7
2003-06-20 19:42:20 +00:00
parent 28a1cb407a
commit af9cd9552e
3 changed files with 191 additions and 68 deletions
+25 -6
View File
@@ -866,13 +866,32 @@
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);
+124 -25
View 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);
@@ -92,36 +92,62 @@
}
//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;
@@ -305,23 +331,50 @@
}
//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;
@@ -336,16 +389,37 @@
}
//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;
}
@@ -378,5 +452,30 @@
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);
}
?>
+42 -37
View File
@@ -443,10 +443,7 @@
//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
@@ -688,15 +685,17 @@
//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 {
@@ -714,23 +713,23 @@
$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;
@@ -746,8 +745,6 @@
$status = false;
}
}
} else {
$status = false;
}
@@ -764,6 +761,7 @@
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
@@ -826,9 +824,6 @@
$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
@@ -840,6 +835,10 @@
$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();
@@ -1135,14 +1134,21 @@
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;
@@ -1298,6 +1304,7 @@
//Speed up a lot (avoid parse all)
if ($tagName == "USERS" and $this->level == 3) {
$this->finished = true;
$this->counter = 0;
}
//Clear things
@@ -1321,7 +1328,9 @@
//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
@@ -1331,21 +1340,17 @@
$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);
}
}
@@ -1426,7 +1431,7 @@
//Clear parser mem
xml_parser_free($xml_parser);
if ($status) {
if ($status && $info) {
return $info;
} else {
return $status;