Index: backup/backuplib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/backup/backuplib.php,v
retrieving revision 1.135.2.3
diff -u -r1.135.2.3 backuplib.php
--- backup/backuplib.php	16 Jul 2007 20:16:24 -0000	1.135.2.3
+++ backup/backuplib.php	20 Aug 2007 17:11:00 -0000
@@ -903,6 +903,10 @@
                         if(empty($blocks[$instance->blockid]->name)) {
                             continue;
                         }
+                        if (!$blockobj = block_instance($blocks[$instance->blockid]->name, $instance)) {
+                            // Invalid block
+                            continue;
+                        }
                         //Begin Block
                         
                         fwrite ($bf,start_tag('BLOCK',3,true));
@@ -914,7 +918,13 @@
                         fwrite ($bf,full_tag('WEIGHT',4,false,$instance->weight));
                         fwrite ($bf,full_tag('VISIBLE',4,false,$instance->visible));
                         fwrite ($bf,full_tag('CONFIGDATA',4,false,$instance->configdata));
-                                             
+
+                        // Write instance data if needed
+                        if ($blockobj->backuprestore_enabled()) {
+                            fwrite ($bf,start_tag('INSTANCEDATA',4,true));
+                            $status = $blockobj->instance_backup($bf, $preferences);
+                            fwrite ($bf,end_tag('INSTANCEDATA',4,true));
+                        }
                         $context = get_context_instance(CONTEXT_BLOCK, $instance->id);
                         write_role_overrides_xml($bf, $context, 4);
                         /// write role_assign code here
@@ -1892,6 +1902,33 @@
             }
         }
 
+        // For each block, call its encode_content_links method
+        static $blockobjects; 
+        if (!isset($blockobjects)) { 
+            $blockobjects = array(); 
+            if ($blocks = blocks_get_record()) { 
+                foreach ($blocks as $block) { 
+                    if ($obj = block_instance($block->name)) {
+                        $blockobjects[] = $obj; 
+                    }
+                }
+            }
+        }
+        
+        foreach ($blockobjects as $blockobject) { 
+            $result = $blockobject->encode_content_links($result,$mypreferences); 
+        }
+        
+        // for the current course format call its encode_content_links method (if it exists)
+        $format = get_field('course', 'format', 'id', $mypreferences->backup_course);
+        if (file_exists("$CFG->dirroot/course/format/$format/backuplib.php")) {
+            include_once("$CFG->dirroot/course/format/$format/backuplib.php");
+            $function_name = $format.'_encode_format_content_links';
+            if (function_exists($function_name)) {
+                $result = $function_name($result, $mypreferences);
+            }
+        }
+
         if ($result != $content) {
             debugging('<br /><hr />'.s($content).'<br />changed to<br />'.s($result).'<hr /><br />');
         }
Index: backup/restorelib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/backup/restorelib.php,v
retrieving revision 1.218.2.22
diff -u -r1.218.2.22 restorelib.php
--- backup/restorelib.php	25 Jul 2007 21:34:11 -0000	1.218.2.22
+++ backup/restorelib.php	20 Aug 2007 17:11:01 -0000
@@ -89,7 +89,47 @@
                 }
             }
         }
+        // Now run through the blocks
+        if (!empty($CFG->restore_blockinstanceids)) {
+            if ($instances = get_records_list('block_instance', 'id', implode(',', $CFG->restore_blockinstanceids))) {
+                foreach ($instances as $instance) {
+                    $block = blocks_get_record($instance->blockid);
 
+                    if (!$blockobj = block_instance($block->name, $instance)) {
+                        // Invalid block
+                        continue;
+                    }
+                    if (!defined('RESTORE_SILENTLY')) {
+                        echo '<li>'.get_string ('from')." $blockobj->title</li>";
+                    }
+                    $status = $blockobj->decode_content_links_caller($restore);
+                }
+            }
+        }
+        
+        // for the course format call its decode_content_links method (if it exists)
+        $format = get_field('course', 'format', 'id', $restore->course_id);
+        if (file_exists("$CFG->dirroot/course/format/$format/restorelib.php")) {
+            include_once("$CFG->dirroot/course/format/$format/restorelib.php");
+            $function_name = $format.'_decode_format_content_links_caller';
+
+            if (function_exists($function_name)) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo "<li>".get_string ("from")." ".get_string("format").' '.$format;
+                }
+                $status = $function_name($restore);
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo '</li>';
+                }
+            }
+            else {
+                print "function doesn't exist: $function_name<br />";
+            }
+        }
+        else {
+            print "file doesn't exist: $CFG->dirroot/course/format/$format/backuplib.php<br />";
+        }
+      
         // TODO: process all html text also in blocks too
 
         // Restore links in questions.
@@ -99,13 +139,12 @@
         }
         $status = question_decode_content_links_caller($restore);
         if (!defined('RESTORE_SILENTLY')) {
-            echo '</li>';
+            echo '</li></ul>';
         }
 
         if (!defined('RESTORE_SILENTLY')) {
             echo "</ul>";
         }
-
         return $status;
     }
     
@@ -113,12 +152,29 @@
     //its task is to ask all modules (maybe other linkable objects) to restore
     //links to them.
     function restore_decode_content_links_worker($content,$restore) {
+        global $CFG;
         foreach($restore->mods as $name => $info) {
             $function_name = $name."_decode_content_links";
             if (function_exists($function_name)) {
                 $content = $function_name($content,$restore);
             }
         }
+        if ($blocks = blocks_get_record()) {
+            foreach ($blocks as $block) {
+                if ($obj = block_instance($block->name)) {
+                    $content = $obj->decode_content_links($content,$restore);
+                }
+            }
+        }
+        
+        $format = get_field('course', 'format', 'id', $restore->course_id);
+        if (file_exists("$CFG->dirroot/course/format/$format/restorelib.php")) {
+            include_once("$CFG->dirroot/course/format/$format/restorelib.php");
+            $function_name = $format.'_decode_format_content_links';
+            if (function_exists($function_name)) {
+                $content = $function_name($content, $restore);
+            }
+        }
         return $content;
     }
 
@@ -206,10 +262,10 @@
     }
 
     //This function read the xml file and store its data from the blocks in a object
-    function restore_read_xml_blocks ($xml_file) {
+    function restore_read_xml_blocks ($restore,$xml_file) {
 
         //We call the main read_xml function, with todo = BLOCKS
-        $info = restore_read_xml ($xml_file,'BLOCKS',false);
+        $info = restore_read_xml ($xml_file,'BLOCKS',$restore);
 
         return $info;
     }
@@ -766,7 +822,9 @@
     //This function creates all the block_instances from xml when restoring in a
     //new course
     function restore_create_block_instances($restore,$xml_file) {
+        global $CFG;
 
+        $CFG->restore_blockinstanceids = array();
         $status = true;
         //Check it exists
         if (!file_exists($xml_file)) {
@@ -774,7 +832,7 @@
         }
         //Get info from xml
         if ($status) {
-            $info = restore_read_xml_blocks($xml_file);
+            $info = restore_read_xml_blocks($restore,$xml_file);
         }
 
         if(empty($info->instances)) {
@@ -855,10 +913,36 @@
 
                     //Add this instance
                     $instance->blockid = $blocks[$instance->name]->id;
-                    
-                    if ($newid = insert_record('block_instance', $instance)) {
-                        if (!empty($instance->id)) { // this will only be set if we come from 1.7 and above backups
-                            backup_putid ($restore->backup_unique_code,"block_instance",$instance->id,$newid);
+
+                    // This will only be set if we come from 1.7 and above backups
+                    //  Also, must do this before insert (insert_record unsets id)
+                    if (!empty($instance->id)) { 
+                        $oldid = $instance->id;
+                    } else {
+                        $oldid = 0;
+                    }
+
+                    if ($instance->id = insert_record('block_instance', $instance)) {
+                        // Save the new ID for later
+                        $CFG->restore_blockinstanceids[] = $instance->id;
+                        // Create block instance
+                        if (!$blockobj = block_instance($instance->name, $instance)) {
+                            $status = false;
+                            break;
+                        }
+                        // Run the block restore if needed
+                        if ($blockobj->backuprestore_enabled()) {
+                            // Get restore information
+                            $data = backup_getid($restore->backup_unique_code,'block_instance',$oldid);
+                            $data->new_id = $instance->id;  // For completeness
+                            if (!$blockobj->instance_restore($restore, $data)) {
+                                $status = false;
+                                break;
+                            }
+                        }
+                        // Save oldid after block restore process because info will be over-written with blank string
+                        if ($oldid) {
+                            backup_putid ($restore->backup_unique_code,"block_instance",$oldid,$instance->id);
                         }
                     } else {
                         $status = false;
@@ -867,8 +951,9 @@
                     
                     //Get an object for the block and tell it it's been restored so it can update dates
                     //etc. if necessary
-                    $blockobj=block_instance($instance->name,$instance);
-                    $blockobj->after_restore($restore);
+                    if ($blockobj = block_instance($instance->name,$instance)) {
+                        $blockobj->after_restore($restore);
+                    }
     
                     //Now we can increment the weight counter
                     ++$maxweights[$instance->position];
@@ -3318,6 +3403,16 @@
             //Check if we are into BLOCKS zone
             //if ($this->tree[3] == "BLOCKS")                                                         //Debug
             //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
+
+            //If we are under a BLOCK tag under a BLOCKS zone, accumule it
+            if (isset($this->tree[4]) and isset($this->tree[3])) {  // 
+                if ($this->tree[4] == "BLOCK" and $this->tree[3] == "BLOCKS") {
+                    if (!isset($this->temp)) {
+                        $this->temp = "";
+                    }
+                    $this->temp .= "<".$tagName.">";
+                }
+            }
         }
 
         //This is the startTag handler we use where we are reading the sections zone (todo="SECTIONS")
@@ -4047,6 +4142,13 @@
                 //if (trim($this->content))                                                                     //Debug
                 //    echo "C".str_repeat("&nbsp;",($this->level+2)*2).$this->getContents()."<br />\n";           //Debug
                 //echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;/".$tagName."&gt;<br />\n";          //Debug
+
+                // Collect everything into $this->temp
+                if (!isset($this->temp)) {
+                    $this->temp = "";
+                }
+                $this->temp .= htmlspecialchars(trim($this->content))."</".$tagName.">";
+
                 //Dependig of different combinations, do different things
                 if ($this->level == 4) {
                     switch ($tagName) {
@@ -4054,6 +4156,34 @@
                             //We've finalized a block, get it
                             $this->info->instances[] = $this->info->tempinstance;
                             unset($this->info->tempinstance);
+                            
+                            //Also, xmlize INSTANCEDATA and save to db
+                            //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 BLOCK)
+                            //echo "-XMLIZE: ".strftime ("%X",time()),"-";                                                //Debug
+                            $data = xmlize($xml_data,0);         
+                            //echo strftime ("%X",time())."<p>";                                                          //Debug
+                            //traverse_xmlize($data);                                                                     //Debug
+                            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
+                            //$GLOBALS['traverse_array']="";                                                              //Debug
+                            //Check for instancedata, is exists, then save to DB
+                            if (isset($data['BLOCK']['#']['INSTANCEDATA']['0']['#'])) {
+                                //Get old id
+                                $oldid = $data['BLOCK']['#']['ID']['0']['#'];
+                                //Get instancedata
+                                $data = $data['BLOCK']['#']['INSTANCEDATA']['0']['#'];
+                                //Restore code calls this multiple times - so might already have the newid
+                                if ($newid = backup_getid($this->preferences->backup_unique_code,'block_instance',$oldid)) {
+                                    $newid = $newid->new_id;
+                                } else {
+                                    $newid = null;
+                                }
+                                //Save to DB, we will use it later
+                                $status = backup_putid($this->preferences->backup_unique_code,'block_instance',$oldid,$newid,$data);
+                            }
+                            //Reset temp
+                            unset($this->temp);
                             break;
                         default:
                             die($tagName);
@@ -6658,7 +6788,7 @@
             if (!defined('RESTORE_SILENTLY')) {
                 echo "<li>".get_string("creatingblocksroles").'</li>';
             }
-            $blocks = restore_read_xml_blocks($xmlfile);
+            $blocks = restore_read_xml_blocks($restore, $xmlfile);
             if (isset($blocks->instances)) {
                 foreach ($blocks->instances as $instance) {
                     if (isset($instance->roleassignments) && !$isimport) {
