Index: backup/backuplib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/backup/backuplib.php,v
retrieving revision 1.217
diff -u -a -w -b -B -r1.217 backuplib.php
--- backup/backuplib.php	4 Aug 2008 16:45:08 -0000	1.217
+++ backup/backuplib.php	18 Aug 2008 20:49:29 -0000
@@ -903,69 +903,142 @@
 
     }
 
-    //Print blogs info (post table, module=blog, course=0)
-    function backup_blogs($bf, $preferences) {
-        global $CFG, $DB;
 
-        $status = true;
+    function backup_course_associations($bf, $preferences) {
+        global $DB;
+        fwrite($bf, start_tag("ASSOCIATIONS",2,true));
 
-    /// Check we have something to backup
-        $siteblogs = $DB->count_records('post', array('module'=>'blog', 'courseid'=>0));
+        $contextids = array();
+        $coursecontext = get_context_instance(CONTEXT_COURSE, $preferences->backup_course);
+        $contextids[] = $coursecontext->id;
+        $modcontexts = $DB->get_records_sql('SELECT id FROM {context} WHERE path LIKE \''.$courseid->path.'%\'');
+        foreach($modcontexts as $modcontext) {
+            $contextids[] = $modcontext->id;
+        }
+        $asocciations = $DB->get_records_sql('SELECT id FROM {blog_association} WHERE contextid IN ('.implode(', ',$contextids).')');
+        foreach($associations as $association) {
+            backup_association($bf, $association->id, 3,  true);
+        }       
+        fwrite($bf, end_tag("ASSOCIATIONS",2,true));
+    }
+
+    function backup_association($bf, $associd, $level, $blogid=false) {
+        global $DB;
+        
+        $assoc = $DB->get_record('blog_association', array('id' => $associd));
+        $context = $DB->get_record('context', array('id' => $assoc->contextid));
+        fwrite ($bf,start_tag("ASSOCIATION",$level,true));
+        if($blogid) {
+            fwrite($bf, full_tag("BLOGID",$level+1,false,$assoc->blogid);
+        }
+        switch($context->contextlevel) {
+            case CONTEXT_COURSE:
+                fwrite ($bf,full_tag("COURSE",$level+1,false,$context->instanceid));
+                break;
+            case CONTEXT_MODULE:
+                $mod = $DB->get_record('course_modules', array('id' => $context->instanceid));
+                fwrite ($bf,full_tag("MODULE",$level+1,false,$DB->get_field('modules', $mod->module)));
+                fwrite ($bf,full_tag("INSTANCE",$level+1,false,$mod->instance));
+                break;
+        }
+        fwrite ($bf,end_tag("ASSOCIATION",$level,true));
+    }
 
-        if ($siteblogs) {
-            $counter = 0;
-        /// blogs open tag
+    function backup_course_blogs($bf, $preferences) {
+        global $DB;
             fwrite ($bf, start_tag("BLOGS",2,true));
 
-            if ($siteblogs) {
-                $rs_blogs = $DB->get_recordset('post', array('module'=>'blog', 'courseid'=>0));
-            /// Iterate over every blog
-                foreach ($rs_blogs as $blog) {
+        $sql = 'SELECT as.data1 FROM {assignment} a, {assignment_submissions} as WHERE 
+                as.assignment = a.id AND a.assignmenttype = \'blog\' AND a.course = '.$preferences->backup_course;
+        $records = $DB->get_records_sql($sql);
+        foreach($records as $rec) {
+            backup_blog($bf, $rec->data1, 3); 
+        }
+        fwrite($bf, end_tag("BLOGS",2,true));
+    }
+    
+    function backup_blog($bf, $blogid, $level) {
+        global $DB;
+        $blog = $DB->get_record('post', array('module'=>'blog', 'id'=>$blogid));
+    
                 /// start blog
-                    fwrite($bf, start_tag("BLOG",3,true));
+        fwrite($bf, start_tag("BLOG",$level,true));
                 /// blog body
-                    fwrite ($bf,full_tag("ID",4,false,$blog->id));
-                    fwrite ($bf,full_tag("MODULE",4,false,$blog->module));
-                    fwrite ($bf,full_tag("USERID",4,false,$blog->userid));
-                    fwrite ($bf,full_tag("COURSEID",4,false,$blog->courseid));
-                    fwrite ($bf,full_tag("GROUPID",4,false,$blog->groupid));
-                    fwrite ($bf,full_tag("MODULEID",4,false,$blog->moduleid));
-                    fwrite ($bf,full_tag("COURSEMODULEID",4,false,$blog->coursemoduleid));
-                    fwrite ($bf,full_tag("SUBJECT",4,false,$blog->subject));
-                    fwrite ($bf,full_tag("SUMMARY",4,false,$blog->summary));
-                    fwrite ($bf,full_tag("CONTENT",4,false,$blog->content));
-                    fwrite ($bf,full_tag("UNIQUEHASH",4,false,$blog->uniquehash));
-                    fwrite ($bf,full_tag("RATING",4,false,$blog->rating));
-                    fwrite ($bf,full_tag("FORMAT",4,false,$blog->format));
-                    fwrite ($bf,full_tag("ATTACHMENT",4,false,$blog->attachment));
-                    fwrite ($bf,full_tag("PUBLISHSTATE",4,false,$blog->publishstate));
-                    fwrite ($bf,full_tag("LASTMODIFIED",4,false,$blog->lastmodified));
-                    fwrite ($bf,full_tag("CREATED",4,false,$blog->created));
-                    fwrite ($bf,full_tag("USERMODIFIED",4,false,$blog->usermodified));
+        fwrite ($bf,full_tag("ID",$level+1,false,$blog->id));
+        fwrite ($bf,full_tag("MODULE",$level+1,false,$blog->module));
+        fwrite ($bf,full_tag("USERID",$level+1,false,$blog->userid));
+        fwrite ($bf,full_tag("COURSEID",$level+1,false,$blog->courseid));
+        fwrite ($bf,full_tag("GROUPID",$level+1,false,$blog->groupid));
+        fwrite ($bf,full_tag("MODULEID",$level+1,false,$blog->moduleid));
+        fwrite ($bf,full_tag("COURSEMODULEID",$level+1,false,$blog->coursemoduleid));
+        fwrite ($bf,full_tag("SUBJECT",$level+1,false,$blog->subject));
+        fwrite ($bf,full_tag("SUMMARY",$level+1,false,$blog->summary));
+        fwrite ($bf,full_tag("CONTENT",$level+1,false,$blog->content));
+        fwrite ($bf,full_tag("UNIQUEHASH",$level+1,false,$blog->uniquehash));
+        fwrite ($bf,full_tag("RATING",$level+1,false,$blog->rating));
+        fwrite ($bf,full_tag("FORMAT",$level+1,false,$blog->format));
+        fwrite ($bf,full_tag("ATTACHMENT",$level+1,false,$blog->attachment));
+        fwrite ($bf,full_tag("PUBLISHSTATE",$level+1,false,$blog->publishstate));
+        fwrite ($bf,full_tag("LASTMODIFIED",$level+1,false,$blog->lastmodified));
+        fwrite ($bf,full_tag("CREATED",$level+1,false,$blog->created));
+        fwrite ($bf,full_tag("USERMODIFIED",$level+1,false,$blog->usermodified));
 
                 /// Blog tags
                 /// Check if we have blog tags to backup
                     if (!empty($CFG->usetags)) {
                         if ($tags = tag_get_tags('post', $blog->id)) { //This return them ordered by default
                         /// Start BLOG_TAGS tag
-                            fwrite ($bf,start_tag("BLOG_TAGS",4,true));
+                fwrite ($bf,start_tag("BLOG_TAGS",$level+1,true));
                         /// Write blog tags fields
                             foreach ($tags as $tag) {
-                                fwrite ($bf,start_tag("BLOG_TAG",5,true));
-                                fwrite ($bf,full_tag("NAME",6,false,$tag->name));
-                                fwrite ($bf,full_tag("RAWNAME",6,false,$tag->rawname));
-                                fwrite ($bf,end_tag("BLOG_TAG",5,true));
+                    fwrite ($bf,start_tag("BLOG_TAG",$level+2,true));
+                    fwrite ($bf,full_tag("NAME",$level+3,false,$tag->name));
+                    fwrite ($bf,full_tag("RAWNAME",$level+3,false,$tag->rawname));
+                    fwrite ($bf,end_tag("BLOG_TAG",$level+2,true));
                             }
                         /// End BLOG_TAGS tag
-                            fwrite ($bf,end_tag("BLOG_TAGS",4,true));
+                fwrite ($bf,end_tag("BLOG_TAGS",$level+1,true));
                         }
                     }
 
-                /// Blog comments
-                    /// TODO: Blog comments go here (2.0)
+        /// Blog associations
+        if(!empty($CFG->useassoc)) {
+            if($records = $DB->get_records('blog_association', array('blogid' => $blogid))) {
+                /// Start ASSOCIATIONS tag
+                fwrite ($bf,start_tag("ASSOCIATIONS",$level+1,true));
+                /// Write blog association fields
+                foreach ($records as $rec) {
+                    backup_association($bf, $rec->contextid, $level+2);
+                }
+                /// End ASSOCIATIONS tag
+                fwrite ($bf,end_tag("ASSOCIATIONS",$level+1,true));
+            }
+        }
 
                 /// end blog
-                    fwrite($bf, end_tag("BLOG",3,true));
+        fwrite($bf, end_tag("BLOG",$level,true));
+    }
+    
+    
+    //Print blogs info (post table, module=blog, course=0)
+    function backup_blogs($bf, $preferences) {
+        global $CFG, $DB;
+
+        $status = true;
+
+    /// Check we have something to backup
+        $siteblogs = $DB->count_records('post', array('module'=>'blog', 'courseid'=>0));
+
+        if ($siteblogs) {
+            $counter = 0;
+        /// blogs open tag
+            fwrite ($bf, start_tag("BLOGS",2,true));
+
+            if ($siteblogs) {
+                $rs_blogs = $DB->get_records('post', array('module'=>'blog', 'courseid'=>0));
+            /// Iterate over every blog
+                foreach ($rs_blogs as $blog) {
+                    backup_blog($bf, $blog->id, 3);
 
                 /// Do some output
                     $counter++;
@@ -3240,6 +3314,38 @@
                 }
             }
 
+            //Backup course blog assignment data, if any.
+            if (!defined('BACKUP_SILENTLY')) {
+                echo '<li>'.get_string("courseblogdata").'</li>';
+            }
+            if($status) {
+                if (!$status = backup_course_blogs($backup_file,$preferences)) {
+                    if (!defined('BACKUP_SILENTLY')) {
+                        notify("An error occurred while backing up the course blog assignment data");
+                    }
+                    else {
+                        $errorstr = "An error occurred while backing up the course blog assignment data";
+                        return false;
+                    }
+                }
+            }
+
+            //Backup course blog association data, if any.
+            if (!defined('BACKUP_SILENTLY')) {
+                echo '<li>'.get_string("courseassociationdata").'</li>';
+            }
+            if($status) {
+                if (!$status = backup_course_associations($backup_file,$preferences)) {
+                    if (!defined('BACKUP_SILENTLY')) {
+                        notify("An error occurred while backing up the course association data");
+                    }
+                    else {
+                        $errorstr = "An error occurred while backing up the course association data";
+                        return false;
+                    }
+                }
+            }
+
             //Prints course end
             if ($status) {
                 if (!$status = backup_course_end($backup_file,$preferences)) {
Index: backup/restorelib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/backup/restorelib.php,v
retrieving revision 1.348
diff -u -a -w -b -B -r1.348 restorelib.php
--- backup/restorelib.php	6 Aug 2008 16:43:40 -0000	1.348
+++ backup/restorelib.php	18 Aug 2008 20:49:40 -0000
@@ -315,6 +315,15 @@
         return $info;
     }
 
+
+    function restore_read_xml_associations ($xml_file) {
+
+        //We call the main read_xml function, with todo = ASSOCIATIONS
+        $info = restore_read_xml ($xml_file,"ASSOCIATIONS",false);
+
+        return $info;
+    }
+
     //This function read the xml file and store its data from the course format in an object
     function restore_read_xml_formatdata ($xml_file) {
 
@@ -2999,6 +3008,61 @@
        return $status;
     }
 
+    function restore_create_associations($restore, $xml_file) {
+        global $CFG, $DB;
+
+        $status = true;
+        //Check it exists
+        if (!file_exists($xml_file)) {
+            $status = false;
+        }
+        //Get info from xml
+        if ($status) {
+            //info will contain the number of blogs in the backup file
+            //in backup_ids->info will be the real info (serialized)
+            $info = restore_read_xml_associations($restore,$xml_file);
+
+            //If we have info, then process blogs & blog_tags
+            if ($info > 0) {
+                //Count how many we have
+                $assoccount = $DB->count_records('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'blog_association'));
+                if ($blogcount) {
+                    //Number of records to get in every chunk
+                    $recordset_size = 4;
+
+                    //Process blog
+                    if ($assoccount) {
+                        $counter = 0;
+                        while ($counter < $assoccount) {
+                            //Fetch recordset_size records in each iteration
+                            $recs = $DB->get_records("backup_ids", array("table_name"=>'blog_association', 'backup_code'=>$restore->backup_unique_code),"old_id","old_id",$counter,$recordset_size);
+                            if ($recs) {
+                                foreach ($recs as $rec) {
+                                    //Get the full record from backup_ids
+                                    $data = backup_getid($restore->backup_unique_code,"blog_association",$rec->old_id);
+                                    if ($data) {
+                                        $contextid = backup_todb($info['ASSOCIATION']['#']['CONTEXTID']['0']['#']);
+                                        $blogid = backup_todb($info['ASSOCIATION']['#']['CONTEXTID']['0']['#']);
+                                        //association may be to a new mod/course context
+                                        //!!!!!!I'm not sure this is the proper way to retrieve a new context id, but I can't 
+                                        //!!!!!!test this yet.
+                                        $backupcontextid = backup_getid($restore->backup_unique_code, 'context', $contextid);
+                                        $backupblogid = backup_getid($restore->backup_unique_code, 'blog', $blogid);
+                                        if($backupcontextid) $contextid = $backupcontextid;
+                                        if($backupblogid) $blogid = $backupblogid;
+                                        $blogid = $exist ? $exist->id : $newblogid;
+                                        blog_add_association($blogid, $contextid);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return $status;
+    }
+
     //This function creates all the structures for blogs and blog tags
     function restore_create_blogs($restore,$xml_file) {
         global $CFG, $DB;
@@ -3096,6 +3160,23 @@
                                                 tag_set('post', $newblogid, $tags); //Add all the tags in one API call
                                             }
                                         }
+                                        if ($CFG->useassoc) {
+                                            //Look for associations in this blog
+                                            if(isset($info['BLOG']['#']['ASSOCIATIONS']['0']['#']['ASSOCIATION'])) {
+                                                $associations = $info['BLOG']['#']['ASSOCIATIONS']['0']['#']['ASSOCIATION'];
+                                                foreach($associations as $i => $association) {
+                                                    $contextid = backup_todb($association['#']['CONTEXTID']['0']['#']);
+        
+                                                    //association may be to a new mod/course context
+                                                    //!!!!!!I'm not sure this is the proper way to retrieve a new context id, but I can't 
+                                                    //!!!!!!test this yet.
+                                                    $backupid = backup_getid($restore->backup_unique_code, 'context', $contextid);
+                                                    if($backupid) $contextid = $backupid;
+                                                    $blogid = $exist ? $exist->id : $newblogid;
+                                                    blog_add_association($blogid, $contextid);
+                                                }
+                                            }
+                                        }
                                     }
                                     //Do some output
                                     $counter++;
@@ -4650,6 +4731,22 @@
             }
         }
 
+        function startElementAssociations($parser, $tagName, $attrs) {
+            //Refresh properties
+            $this->level++;
+            $this->tree[$this->level] = $tagName;
+
+            //If we are under an ASSOCIATION tag under an ASSOCIATIONS zone, accumulate it
+            if (isset($this->tree[4]) and isset($this->tree[3])) {
+                if ($this->tree[4] == "ASSOCIATION" and $this->tree[3] == "ASSOCIATIONS") {
+                    if (!isset($this->temp)) {
+                        $this->temp = "";
+                    }
+                    $this->temp .= "<".$tagName.">";
+                }
+            }
+        }
+
         //This is the startTag handler we use where we are reading the blogs zone (todo="BLOGS")
         function startElementBlogs($parser, $tagName, $attrs) {
             //Refresh properties
@@ -6694,14 +6791,33 @@
                 }
             }
 
-            //Stop parsing if todo = BLOGS and tagName = BLOGS (end of the tag, of course)
-            //Speed up a lot (avoid parse all)
-            if ($tagName == "BLOGS" and $this->level == 3) {
+
+        function endElementAssociations($parser, $tagName) {
+            //Check if we are into ASSOCIATIONS zone
+            if ($this->tree[3] == "ASSOCIATIONS") {
+                if (!isset($this->temp)) {
+                    $this->temp = "";
+                }
+                $this->temp .= htmlspecialchars(trim($this->content))."</".$tagName.">";
+                //If we've finished an association, xmlize it an save to db
+                if (($this->level == 4) and ($tagName == "ASSOCIATION")) {
+                    $xml_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".$this->temp;
+                    $data = xmlize($xml_data,0);
+                    $associationid = $data["ASSOCIATION"]["#"]["ID"]["0"]["#"];
+                    $this->counter++;
+                    //Save to db
+                    $status = backup_putid($this->preferences->backup_unique_code, 'blog_association', $associationid,null,$data);
+                    $this->info = $this->counter;
+                    unset($this->temp);
+                }
+            }
+
+            //Stop parsing if todo = ASSOCIATIONS and tagName = ASSOCIATIONS
+            if ($tagName == "ASSOCIATIONS" and $this->level == 3) {
                 $this->finished = true;
                 $this->counter = 0;
             }
 
-            //Clear things
             $this->tree[$this->level] = "";
             $this->level--;
             $this->content = "";
@@ -7198,6 +7314,8 @@
             xml_set_element_handler($xml_parser, "startElementModules", "endElementModules");
         } else if ($todo == "LOGS") {
             xml_set_element_handler($xml_parser, "startElementLogs", "endElementLogs");
+        } else if ($todo == "ASSOCIATIONS") {
+            xml_set_element_handler($xml_parser, "startElementAssociations", "endElementAssociations"); {
         } else {
             //Define default handlers (must no be invoked when everything become finished)
             xml_set_element_handler($xml_parser, "startElementInfo", "endElementInfo");
@@ -7953,6 +8071,24 @@
             }
         }
 
+        //Now create associations as needed
+        if ($status and ($restore->associations)) {
+            if (!defined('RESTORE_SILENTLY')) {
+                echo "<li>".get_string("creatingassociationsinfo");
+            }
+            if (!$status = restore_create_associations($restore,$xml_file)) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    notify("Could not restore associations!");
+                } else {
+                    $errorstr = "Could not restore associations!";
+                    return false;
+                }
+            }
+            if (!defined('RESTORE_SILENTLY')) {
+                echo "</li>";
+            }
+        }
+
         //Now create scales as needed
         if ($status) {
             if (!defined('RESTORE_SILENTLY')) {
