# This patch file was generated by NetBeans IDE
# This patch can be applied using context Tools: Apply Diff Patch action on respective folder.
# It uses platform neutral UTF-8 encoding.
# Above lines and this line are ignored by the patching process.
Index: moodle/backup/moodle2/backup_course_task.class.php
--- moodle/backup/moodle2/backup_course_task.class.php Base (1.2)
+++ moodle/backup/moodle2/backup_course_task.class.php Locally Modified (Based On 1.2)
@@ -60,6 +60,7 @@
      * Create all the steps that will be part of this task
      */
     public function build() {
+        global $DB;
 
         // Add some extra settings that related processors are going to need
         $this->add_setting(new backup_activity_generic_setting(backup::VAR_COURSEID, base_setting::IS_INTEGER, $this->get_courseid()));
@@ -88,6 +89,26 @@
             $this->add_step(new backup_comments_structure_step('course_comments', 'comments.xml'));
         }
 
+        //determine if all activity related grade items are being backed up.
+        //If so we can also backup calculated grade items and categories
+        $backupgradebook = true;
+        $courseid = backup::VAR_COURSEID;
+        if ($grade_items = $DB->get_records_sql("SELECT *
+                                              FROM {grade_items}
+                                             WHERE courseid = $courseid
+                                                   AND itemtype = 'mod'")) {
+            foreach ($grade_items as $grade_item) {
+                if (!backup_mod_selected($preferences,$grade_item->itemmodule,$grade_item->iteminstance)) {
+                    $backupgradebook = false;
+                    break;
+                }
+            }
+            unset($grade_items);
+        }
+        if ($backupgradebook) {
+            $this->add_step(new backup_gradebook_structure_step('course_gradebook','gradebook.xml'));
+        }
+
         // Generate the logs file (conditionally)
         if ($this->get_setting_value('logs')) {
             //$this->add_step(new backup_course_logs_structure_step('course_logs', 'logs.xml'));
Index: moodle/backup/moodle2/backup_stepslib.php
--- moodle/backup/moodle2/backup_stepslib.php Base (1.7)
+++ moodle/backup/moodle2/backup_stepslib.php Locally Modified (Based On 1.7)
@@ -74,7 +74,7 @@
 }
 
 /**
- * Abtract tructure step, parent of all the activity structure steps. Used to wrap the
+ * Abtract structure step, parent of all the activity structure steps. Used to wrap the
  * activity structure definition within the main <activity ...> tag
  */
 abstract class backup_activity_structure_step extends backup_structure_step {
@@ -514,6 +514,88 @@
 }
 
 /**
+ * structure step in charge of constructing the gradebook.xml file for all the gradebook config in the course
+ * NOTE: the backup of the grade items themselves is handled by backup_activity_grades_structure_step
+ */
+class backup_gradebook_structure_step extends backup_structure_step {
+
+    protected function define_structure() {
+
+        // are we including user info?
+        $userinfo = $this->get_setting_value('users');
+
+        $gradebook = new backup_nested_element('gradebook');
+        
+        //do we need to backup outcomes or are they handled elsewhere?
+
+        //grade_letters are done in backup_activity_grades_structure_step()
+
+        //calculated grade items
+        $grade_items = new backup_nested_element('grade_items');
+        $grade_item = new backup_nested_element('grade_item', array('id'), array(
+            'categoryid', 'itemname', 'itemtype', 'itemmodule',
+            'iteminstance', 'itemnumber', 'iteminfo', 'idnumber',
+            'calculation', 'gradetype', 'grademax', 'grademin',
+            'scaleid', 'outcomeid', 'gradepass', 'multfactor',
+            'plusfactor', 'aggregationcoef', 'sortorder', 'display',
+            'decimals', 'hidden', 'locked', 'locktime',
+            'needsupdate', 'timecreated', 'timemodified'));
+
+        $grade_grades = new backup_nested_element('grade_grades');
+        $grade_grade = new backup_nested_element('grade_grade', array('id'), array(
+            'userid', 'rawgrade', 'rawgrademax', 'rawgrademin',
+            'rawscaleid', 'usermodified', 'finalgrade', 'hidden',
+            'locked', 'locktime', 'exported', 'overridden',
+            'excluded', 'feedback', 'feedbackformat', 'information',
+            'informationformat', 'timecreated', 'timemodified'));
+
+        //grade_categories
+        $grade_categories = new backup_nested_element('grade_categories');
+        $grade_category   = new backup_nested_element('grade_category', null, array('courseid', 
+                'parent', 'depth', 'path', 'fullname', 'aggregation', 'keephigh', 
+                'dropload', 'aggregateonlygraded', 'aggregateoutcomes', 'aggregatesubcats',
+                'timecreated', 'timemodified'));
+
+
+        // Build the tree
+
+        $gradebook->add_child($grade_items);
+        $grade_items->add_child($grade_item);
+        $grade_item->add_child($grade_grades);
+        $grade_grades->add_child($grade_grade);
+
+        $gradebook->add_child($grade_categories);
+        $grade_categories->add_child($grade_category);
+
+        // Define sources
+
+        //if itemtype == manual then item is a calculated item so isn't attached to an activity and we need to back it up here
+        $grade_items_array = grade_item::fetch_all(array('itemtype' => 'manual', 'courseid' => backup::VAR_COURSEID));
+        //$grade_items_array==false rather than empty array if no items. set_source_array() has an error if you pass in a bool
+        if ($grade_items_array) {
+            $grade_item->set_source_array($grade_items_array);
+        }
+
+        if ($userinfo) {
+            $grade_grade->set_source_table('grade_grades', array('itemid' => backup::VAR_PARENTID));
+        }
+
+        $grade_category_sql = "SELECT gc.*, gi.sortorder
+                                   FROM {grade_categories} gc
+                                        JOIN {grade_items} gi
+                                          ON (gi.iteminstance = gc.id)
+                                  WHERE gc.courseid = :courseid
+                                        AND (gi.itemtype='course' OR gi.itemtype='category')
+                               ORDER BY gi.sortorder ASC";
+        $grade_category_params = array('courseid'=>backup::VAR_COURSEID);
+        $grade_category->set_source_sql($grade_category_sql, $grade_category_params);
+
+        // Return the root element
+        return $gradebook;
+    }
+}
+
+/**
  * structure step in charge if constructing the completion.xml file for all the users completion
  * information in a given activity
  */
