From af9cd9552e0c2b6f2d768225a9cef7243ba6e874 Mon Sep 17 00:00:00 2001 From: stronk7 Date: Fri, 20 Jun 2003 19:42:20 +0000 Subject: [PATCH] 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. --- backup/backuplib.php | 31 +++++++-- backup/lib.php | 149 +++++++++++++++++++++++++++++++++++------- backup/restorelib.php | 79 +++++++++++----------- 3 files changed, 191 insertions(+), 68 deletions(-) diff --git a/backup/backuplib.php b/backup/backuplib.php index 284c5a4684..60c2bea626 100644 --- a/backup/backuplib.php +++ b/backup/backuplib.php @@ -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 "

From: ".$from_zip_file."
"; //Debug + + echo "

Checking: ".$to_zip_file."
"; //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 "

Checking: ".$to_zip_file."
"; //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 "

To: ".$to_zip_file."
"; //Debug + //Copy zip file if ($status) { $status = backup_copy_file ($from_zip_file,$to_zip_file); diff --git a/backup/lib.php b/backup/lib.php index b5f840274f..46656297a7 100644 --- a/backup/lib.php +++ b/backup/lib.php @@ -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; $iprefix}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); + } ?> diff --git a/backup/restorelib.php b/backup/restorelib.php index eda79326d7..beffb6dfc5 100644 --- a/backup/restorelib.php +++ b/backup/restorelib.php @@ -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(" ",$this->level*2)."<".$tagName.">
\n"; //Debug @@ -840,6 +835,10 @@ $this->level++; $this->tree[$this->level] = $tagName; +if ($tagName == "MOD" && $this->tree[3] == "MODULES") { +echo "

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 "
"; + } + 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 = "\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())."

"; //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 "

id: ".$mod_id."-".$mod_type." len.: ".strlen($sla_mod_temp)." to_db: ".$status."

"; //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; -- 2.39.5