### Eclipse Workspace Patch 1.0
#P moodle19
Index: backup/restorelib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/backup/restorelib.php,v
retrieving revision 1.283.2.30
diff -u -r1.283.2.30 restorelib.php
--- backup/restorelib.php	17 Mar 2008 21:54:47 -0000	1.283.2.30
+++ backup/restorelib.php	20 Mar 2008 18:09:12 -0000
@@ -104,7 +104,7 @@
                     if (!defined('RESTORE_SILENTLY')) {
                         echo "<li>".get_string ("from")." ".get_string("modulenameplural",$name);
                     }
-                    $status = $function_name($restore);
+                    $status = $function_name($restore) && $status;
                     if (!defined('RESTORE_SILENTLY')) {
                         echo '</li>';
                     }
@@ -116,17 +116,18 @@
         if (!defined('RESTORE_SILENTLY')) {
             echo '<li>' . get_string ('from') . ' ' . get_string('blocks');
         }
-        if (!empty($restore->blockinstanceids)) {
+        if ($restored_blocks = get_records_select("backup_ids","table_name = 'block_instance' AND backup_code = $restore->backup_unique_code AND new_id > 0", "", "new_id")) {
             $blocks = blocks_get_record();
-            $instances = get_records_list('block_instance', 'id', implode(',', $restore->blockinstanceids), '', 'id,blockid,configdata');
-            foreach ($instances as $instance) {
-                if (!isset($blocks[$instance->blockid]->blockobject)) {
-                    $blocks[$instance->blockid]->blockobject = block_instance($blocks[$instance->blockid]->name);
-                }
-                $config = unserialize(base64_decode($instance->configdata));
-                if ($blocks[$instance->blockid]->blockobject->restore_decode_absolute_links_in_config($config)) {
-                    $instance->configdata = base64_encode(serialize($config));
-                    $status = $status && update_record('block_instance', $instance);
+            if ($instances = get_records_list('block_instance', 'id', implode(',', array_keys($restored_blocks)), '', 'id,blockid,configdata')) {
+                foreach ($instances as $instance) {
+                    if (!isset($blocks[$instance->blockid]->blockobject)) {
+                        $blocks[$instance->blockid]->blockobject = block_instance($blocks[$instance->blockid]->name);
+                    }
+                    $config = unserialize(base64_decode($instance->configdata));
+                    if ($blocks[$instance->blockid]->blockobject->restore_decode_absolute_links_in_config($config, $restore)) {
+                        $instance->configdata = base64_encode(serialize($config));
+                        $status = update_record('block_instance', $instance) && $status;
+                    }
                 }
             }
         }
@@ -139,7 +140,7 @@
         if (!defined('RESTORE_SILENTLY')) {
             echo '<li>' . get_string('from') . ' ' . get_string('questions', 'quiz');
         }
-        $status = question_decode_content_links_caller($restore);
+        $status = question_decode_content_links_caller($restore) && $status;
         if (!defined('RESTORE_SILENTLY')) {
             echo '</li>';
         }
@@ -248,10 +249,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;
     }
@@ -810,17 +811,13 @@
 
         $status = true;
 
-        // Tracks which blocks we create during the restore.
-        // This is used in restore_decode_content_links.
-        $restore->blockinstanceids = array();
-
         //Check it exists
         if (!file_exists($xml_file)) {
             $status = false;
         }
         //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)) {
@@ -869,7 +866,8 @@
             $pageinstances[$instance->pagetype][$instance->pageid][] = $instance;
         }
 
-        $blocks = get_records_select('block', '', '', 'name, id, multiple');
+        // get list of all enabled blocks - disabled blocks are not restored anymore
+        $blocks = get_records_select('block', 'visible = 1', '', 'name, id, multiple');
 
         // For each type of page we have restored
         foreach($pageinstances as $thistypeinstances) {
@@ -907,11 +905,35 @@
                     //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)) {
+                        // Create block instance
+                        if (!$blockobj = block_instance($instance->name, $instance)) {
+                            $status = false;
+                            break;
                         }
-                        $restore->blockinstanceids[] = $newid;
+                        // 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;
                         break;
@@ -919,8 +941,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];
@@ -4278,6 +4301,17 @@
             //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")
@@ -5069,6 +5103,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) {
@@ -5076,6 +5117,37 @@
                             //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
+                                
+                                if ($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);
@@ -8097,7 +8169,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) {
Index: backup/backuplib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/backup/backuplib.php,v
retrieving revision 1.179.2.21
diff -u -r1.179.2.21 backuplib.php
--- backup/backuplib.php	17 Mar 2008 19:36:36 -0000	1.179.2.21
+++ backup/backuplib.php	20 Mar 2008 18:09:01 -0000
@@ -968,6 +968,11 @@
                             continue;
                         }
 
+                        if (!$blockobj = block_instance($blocks[$instance->blockid]->name, $instance)) {
+                            // Invalid block
+                            continue;
+                        }
+
                         //Give the block a chance to process any links in configdata.
                         if (!isset($blocks[$instance->blockid]->blockobject)) {
                             $blocks[$instance->blockid]->blockobject = block_instance($blocks[$instance->blockid]->name);
@@ -986,7 +991,12 @@
                         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
Index: blocks/moodleblock.class.php
===================================================================
RCS file: /cvsroot/moodle/moodle/blocks/moodleblock.class.php,v
retrieving revision 1.92.2.4
diff -u -r1.92.2.4 moodleblock.class.php
--- blocks/moodleblock.class.php	20 Dec 2007 16:25:18 -0000	1.92.2.4
+++ blocks/moodleblock.class.php	20 Mar 2008 18:09:12 -0000
@@ -130,6 +130,49 @@
     }
 
     /**
+     * Enable the block for backup and restore.
+     * 
+     * If return true, then {@link instance_backup()} and
+     * {@link instance_restore()} will be called during
+     * backup/restore routines.
+     *
+     * @return boolean
+     **/
+    function backuprestore_enabled() {
+        return false;
+    }
+
+    /**
+     * Allows the block class to have a backup routine.  Handy 
+     * when the block has its own tables that have foreign keys to 
+     * other tables (example: user table).
+     * 
+     * Note: at the time of writing this comment, the indent level 
+     * for the {@link full_tag()} should start at 5.
+     *
+     * @param resource $bf Backup File
+     * @param object $preferences Backup preferences
+     * @return boolean
+     **/
+    function instance_backup($bf, $preferences) {
+        return true;
+    }
+
+    /**
+     * Allows the block class to restore its backup routine.
+     * 
+     * Should not return false if data is empty 
+     * because old backups would not contain block instance backup data.
+     * 
+     * @param object $restore Standard restore object
+     * @param object $data Object from backup_getid for this block instance
+     * @return boolean
+     **/
+    function instance_restore($restore, $data) {
+        return true;
+    }
+
+    /**
      * Will be called before an instance of this block is backed up, so that any links in
      * any links in any HTML fields on config can be encoded. For example, for the HTML block
      * we need to do $config->text = backup_encode_absolute_links($config->text);. 
@@ -144,10 +187,11 @@
      * HTML block we need to do $config->text = restore_decode_absolute_links($config->text);
      *
      * @param object $config the config field for an insance of this class.
+     * @param object $restore added in 1.9.1 - allows encoding of links to modules
      * @return boolean return true if something has changed, so the database can be updated,
      *       false if not, for efficiency reasons.
      */
-    function restore_decode_absolute_links_in_config(&$config) {
+    function restore_decode_absolute_links_in_config(&$config, $restore) {
         return false;
     }
 
Index: blocks/html/block_html.php
===================================================================
RCS file: /cvsroot/moodle/moodle/blocks/html/block_html.php,v
retrieving revision 1.8.22.3
diff -u -r1.8.22.3 block_html.php
--- blocks/html/block_html.php	3 Mar 2008 11:41:02 -0000	1.8.22.3
+++ blocks/html/block_html.php	20 Mar 2008 18:09:12 -0000
@@ -40,9 +40,10 @@
         $config->text = backup_encode_absolute_links($config->text);
     }
 
-    function restore_decode_absolute_links_in_config(&$config) {
+    function restore_decode_absolute_links_in_config(&$config, $restore) {
         $oldtext = $config->text;
-        $config->text = restore_decode_absolute_links($oldtext);
+        $config->text = restore_decode_absolute_links($oldtext);                      // links to course files
+        $config->text = restore_decode_content_links_worker($config->text, $restore); // links to activities
         return $config->text != $oldtext;
     }
 }
