/**
  * Test the event.
  */
 public function test_event()
 {
     global $CFG;
     require_once "{$CFG->libdir}/gradelib.php";
     $this->resetAfterTest();
     $course = $this->getDataGenerator()->create_course();
     $user = $this->getDataGenerator()->create_user();
     $this->getDataGenerator()->enrol_user($user->id, $course->id);
     $grade_category = grade_category::fetch_course_category($course->id);
     $grade_category->load_grade_item();
     $grade_item = $grade_category->grade_item;
     $grade_item->update_final_grade($user->id, 10, 'gradebook');
     $grade_grade = new grade_grade(array('userid' => $user->id, 'itemid' => $grade_item->id), true);
     $grade_grade->grade_item = $grade_item;
     $event = \core\event\user_graded::create_from_grade($grade_grade);
     $this->assertEventLegacyLogData(array($course->id, 'grade', 'update', '/report/grader/index.php?id=' . $course->id, $grade_item->itemname . ': ' . fullname($user)), $event);
     $this->assertEquals(context_course::instance($course->id), $event->get_context());
     $this->assertSame($event->objecttable, 'grade_grades');
     $this->assertEquals($event->objectid, $grade_grade->id);
     $this->assertEquals($event->other['itemid'], $grade_item->id);
     $this->assertTrue($event->other['overridden']);
     $this->assertEquals(10, $event->other['finalgrade']);
     // Trigger the events.
     $sink = $this->redirectEvents();
     $event->trigger();
     $result = $sink->get_events();
     $sink->close();
     $this->assertCount(1, $result);
     $event = reset($result);
     $this->assertEventContextNotUsed($event);
     $grade = $event->get_grade();
     $this->assertInstanceOf('grade_grade', $grade);
     $this->assertEquals($grade_grade->id, $grade->id);
 }
 protected function sub_test_grade_category_fetch_course_category()
 {
     $category = new grade_category();
     $this->assertTrue(method_exists($category, 'fetch_course_category'));
     $category = grade_category::fetch_course_category($this->courseid);
     $this->assertTrue(empty($category->parent));
 }
Exemple #3
0
        $url = $CFG->wwwroot . '/grade/edit/tree/outcomeitem.php?id=' . $id . '&courseid=' . $courseid;
        redirect($gpr->add_url_params($url));
    }
    if ($grade_item->is_course_item() or $grade_item->is_category_item()) {
        $grade_category = $grade_item->get_item_category();
        $url = $CFG->wwwroot . '/grade/edit/tree/category.php?id=' . $grade_category->id . '&courseid=' . $courseid;
        redirect($gpr->add_url_params($url));
    }
    $item = $grade_item->get_record_data();
    $parent_category = $grade_item->get_parent_category();
    $item->parentcategory = $parent_category->id;
} else {
    $heading = get_string('newitem', 'grades');
    $grade_item = new grade_item(array('courseid' => $courseid, 'itemtype' => 'manual'), false);
    $item = $grade_item->get_record_data();
    $parent_category = grade_category::fetch_course_category($courseid);
    $item->parentcategory = $parent_category->id;
}
$decimalpoints = $grade_item->get_decimals();
if ($item->hidden > 1) {
    $item->hiddenuntil = $item->hidden;
    $item->hidden = 0;
} else {
    $item->hiddenuntil = 0;
}
$item->locked = !empty($item->locked);
$item->grademax = format_float($item->grademax, $decimalpoints);
$item->grademin = format_float($item->grademin, $decimalpoints);
$item->gradepass = format_float($item->gradepass, $decimalpoints);
$item->multfactor = format_float($item->multfactor, 4);
$item->plusfactor = format_float($item->plusfactor, 4);
 /**
  * Load grade_item data into the database, and adds the corresponding objects to this class' variable.
  */
 function load_grade_items()
 {
     global $DB;
     $course_category = grade_category::fetch_course_category($this->courseid);
     // id = 0
     $grade_item = new stdClass();
     $grade_item->courseid = $this->courseid;
     $grade_item->categoryid = $this->grade_categories[1]->id;
     $grade_item->itemname = 'unittestgradeitem1';
     $grade_item->itemtype = 'mod';
     $grade_item->itemmodule = 'quiz';
     $grade_item->iteminstance = 1;
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->grademin = 30;
     $grade_item->grademax = 110;
     $grade_item->itemnumber = 1;
     $grade_item->idnumber = 'item id 0';
     $grade_item->iteminfo = 'Grade item 0 used for unit testing';
     $grade_item->timecreated = mktime();
     $grade_item->timemodified = mktime();
     $grade_item->sortorder = 3;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[0] = $grade_item;
     // id = 1
     $grade_item = new stdClass();
     $grade_item->courseid = $this->courseid;
     $grade_item->categoryid = $this->grade_categories[1]->id;
     $grade_item->itemname = 'unittestgradeitem2';
     $grade_item->itemtype = 'import';
     $grade_item->itemmodule = 'assignment';
     $grade_item->calculation = '= ##gi' . $this->grade_items[0]->id . '## + 30 + [[item id 0]] - [[item id 0]]';
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->iteminstance = 2;
     $grade_item->itemnumber = null;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Grade item 1 used for unit testing';
     $grade_item->timecreated = mktime();
     $grade_item->timemodified = mktime();
     $grade_item->sortorder = 4;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[1] = $grade_item;
     // id = 2
     $grade_item = new stdClass();
     $grade_item->courseid = $this->courseid;
     $grade_item->categoryid = $this->grade_categories[2]->id;
     $grade_item->itemname = 'unittestgradeitem3';
     $grade_item->itemtype = 'mod';
     $grade_item->itemmodule = 'forum';
     $grade_item->iteminstance = 3;
     $grade_item->gradetype = GRADE_TYPE_SCALE;
     $grade_item->scaleid = $this->scale[0]->id;
     $grade_item->grademin = 0;
     $grade_item->grademax = $this->scalemax[0];
     $grade_item->iteminfo = 'Grade item 2 used for unit testing';
     $grade_item->timecreated = mktime();
     $grade_item->timemodified = mktime();
     $grade_item->sortorder = 6;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[2] = $grade_item;
     // Load grade_items associated with the 3 categories
     // id = 3
     $grade_item = new stdClass();
     $grade_item->courseid = $this->courseid;
     $grade_item->iteminstance = $this->grade_categories[0]->id;
     $grade_item->itemname = 'unittestgradeitemcategory1';
     $grade_item->needsupdate = 0;
     $grade_item->itemtype = 'category';
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Grade item 3 used for unit testing';
     $grade_item->timecreated = mktime();
     $grade_item->timemodified = mktime();
     $grade_item->sortorder = 1;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[3] = $grade_item;
     // id = 4
     $grade_item = new stdClass();
     $grade_item->courseid = $this->courseid;
     $grade_item->iteminstance = $this->grade_categories[1]->id;
     $grade_item->itemname = 'unittestgradeitemcategory2';
     $grade_item->itemtype = 'category';
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->needsupdate = 0;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Grade item 4 used for unit testing';
     $grade_item->timecreated = mktime();
     $grade_item->timemodified = mktime();
     $grade_item->sortorder = 2;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[4] = $grade_item;
     // id = 5
     $grade_item = new stdClass();
     $grade_item->courseid = $this->courseid;
     $grade_item->iteminstance = $this->grade_categories[2]->id;
     $grade_item->itemname = 'unittestgradeitemcategory3';
     $grade_item->itemtype = 'category';
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->needsupdate = true;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Grade item 5 used for unit testing';
     $grade_item->timecreated = mktime();
     $grade_item->timemodified = mktime();
     $grade_item->sortorder = 5;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[5] = $grade_item;
     // Orphan grade_item
     // id = 6
     $grade_item = new stdClass();
     $grade_item->courseid = $this->courseid;
     $grade_item->categoryid = $course_category->id;
     $grade_item->itemname = 'unittestorphangradeitem1';
     $grade_item->itemtype = 'mod';
     $grade_item->itemmodule = 'quiz';
     $grade_item->iteminstance = 5;
     $grade_item->itemnumber = 0;
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->grademin = 10;
     $grade_item->grademax = 120;
     $grade_item->locked = time();
     $grade_item->iteminfo = 'Orphan Grade 6 item used for unit testing';
     $grade_item->timecreated = mktime();
     $grade_item->timemodified = mktime();
     $grade_item->sortorder = 7;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[6] = $grade_item;
     // 2 grade items under level1category
     // id = 7
     $grade_item = new stdClass();
     $grade_item->courseid = $this->courseid;
     $grade_item->categoryid = $this->grade_categories[3]->id;
     $grade_item->itemname = 'singleparentitem1';
     $grade_item->itemtype = 'mod';
     $grade_item->itemmodule = 'forum';
     $grade_item->iteminstance = 7;
     $grade_item->gradetype = GRADE_TYPE_SCALE;
     $grade_item->scaleid = $this->scale[0]->id;
     $grade_item->grademin = 0;
     $grade_item->grademax = $this->scalemax[0];
     $grade_item->iteminfo = 'Grade item 7 used for unit testing';
     $grade_item->timecreated = mktime();
     $grade_item->timemodified = mktime();
     $grade_item->sortorder = 9;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[7] = $grade_item;
     // id = 8
     $grade_item = new stdClass();
     $grade_item->courseid = $this->courseid;
     $grade_item->categoryid = $this->grade_categories[3]->id;
     $grade_item->itemname = 'singleparentitem2';
     $grade_item->itemtype = 'mod';
     $grade_item->itemmodule = 'forum';
     $grade_item->iteminstance = 9;
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Grade item 8 used for unit testing';
     $grade_item->timecreated = mktime();
     $grade_item->timemodified = mktime();
     $grade_item->sortorder = 10;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[8] = $grade_item;
     // Grade_item for level1category
     // id = 9
     $grade_item = new stdClass();
     $grade_item->courseid = $this->courseid;
     $grade_item->itemname = 'grade_item for level1 category';
     $grade_item->itemtype = 'category';
     $grade_item->itemmodule = 'quiz';
     $grade_item->iteminstance = $this->grade_categories[3]->id;
     $grade_item->needsupdate = true;
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Orphan Grade item 9 used for unit testing';
     $grade_item->timecreated = mktime();
     $grade_item->timemodified = mktime();
     $grade_item->sortorder = 8;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[9] = $grade_item;
     // Manual grade_item
     // id = 10
     $grade_item = new stdClass();
     $grade_item->courseid = $this->courseid;
     $grade_item->categoryid = $course_category->id;
     $grade_item->itemname = 'manual grade_item';
     $grade_item->itemtype = 'manual';
     $grade_item->itemnumber = 0;
     $grade_item->needsupdate = false;
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Manual grade item 10 used for unit testing';
     $grade_item->timecreated = mktime();
     $grade_item->timemodified = mktime();
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[10] = $grade_item;
 }
 public function test_upgrade_extra_credit_weightoverride()
 {
     global $DB, $CFG;
     $this->resetAfterTest(true);
     $c = array();
     $a = array();
     $gi = array();
     for ($i = 0; $i < 5; $i++) {
         $c[$i] = $this->getDataGenerator()->create_course();
         $a[$i] = array();
         $gi[$i] = array();
         for ($j = 0; $j < 3; $j++) {
             $a[$i][$j] = $this->getDataGenerator()->create_module('assign', array('course' => $c[$i], 'grade' => 100));
             $giparams = array('itemtype' => 'mod', 'itemmodule' => 'assign', 'iteminstance' => $a[$i][$j]->id, 'courseid' => $c[$i]->id, 'itemnumber' => 0);
             $gi[$i][$j] = grade_item::fetch($giparams);
         }
     }
     // Case 1: Course $c[0] has aggregation method different from natural.
     $coursecategory = grade_category::fetch_course_category($c[0]->id);
     $coursecategory->aggregation = GRADE_AGGREGATE_WEIGHTED_MEAN;
     $coursecategory->update();
     $gi[0][1]->aggregationcoef = 1;
     $gi[0][1]->update();
     $gi[0][2]->weightoverride = 1;
     $gi[0][2]->update();
     // Case 2: Course $c[1] has neither extra credits nor overrides
     // Case 3: Course $c[2] has extra credits but no overrides
     $gi[2][1]->aggregationcoef = 1;
     $gi[2][1]->update();
     // Case 4: Course $c[3] has no extra credits and has overrides
     $gi[3][2]->weightoverride = 1;
     $gi[3][2]->update();
     // Case 5: Course $c[4] has both extra credits and overrides
     $gi[4][1]->aggregationcoef = 1;
     $gi[4][1]->update();
     $gi[4][2]->weightoverride = 1;
     $gi[4][2]->update();
     // Run the upgrade script and make sure only course $c[4] was marked as needed to be fixed.
     upgrade_extra_credit_weightoverride();
     $this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $c[0]->id}));
     $this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $c[1]->id}));
     $this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $c[2]->id}));
     $this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $c[3]->id}));
     $this->assertEquals(20150619, $CFG->{'gradebook_calculations_freeze_' . $c[4]->id});
     set_config('gradebook_calculations_freeze_' . $c[4]->id, null);
     // Run the upgrade script for a single course only.
     upgrade_extra_credit_weightoverride($c[0]->id);
     $this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $c[0]->id}));
     upgrade_extra_credit_weightoverride($c[4]->id);
     $this->assertEquals(20150619, $CFG->{'gradebook_calculations_freeze_' . $c[4]->id});
 }
 function definition_after_data()
 {
     global $CFG, $COURSE;
     $mform =& $this->_form;
     if ($id = $mform->getElementValue('id')) {
         $grade_item = grade_item::fetch(array('id' => $id));
         //remove the aggregation coef element if not needed
         if ($grade_item->is_course_item()) {
             $mform->removeElement('aggregationcoef');
         } else {
             if ($grade_item->is_category_item()) {
                 $category = $grade_item->get_item_category();
                 $parent_category = $category->get_parent_category();
                 if (!$parent_category->is_aggregationcoef_used()) {
                     $mform->removeElement('aggregationcoef');
                 }
             } else {
                 $parent_category = $grade_item->get_parent_category();
                 if (!$parent_category->is_aggregationcoef_used()) {
                     $mform->removeElement('aggregationcoef');
                 }
             }
         }
     } else {
         $course_category = grade_category::fetch_course_category($COURSE->id);
         if (!$course_category->is_aggregationcoef_used()) {
             $mform->removeElement('aggregationcoef');
         }
     }
 }
Exemple #7
0
 /**
  * Returns tree with all grade_items and categories as elements
  *
  * @param int $courseid The course ID
  * @param bool $include_category_items as category children
  * @return array
  */
 public static function fetch_course_tree($courseid, $include_category_items = false)
 {
     $course_category = grade_category::fetch_course_category($courseid);
     $category_array = array('object' => $course_category, 'type' => 'category', 'depth' => 1, 'children' => $course_category->get_children($include_category_items));
     $course_category->sortorder = $course_category->get_sortorder();
     $sortorder = $course_category->get_sortorder();
     return grade_category::_fetch_course_tree_recursion($category_array, $sortorder);
 }
/**
 * Remove all grade related course data
 * Grade history is kept
 *
 * @param int $courseid The course ID
 * @param bool $showfeedback If true success notifications will be displayed
 */
function remove_course_grades($courseid, $showfeedback)
{
    global $DB, $OUTPUT;
    $fs = get_file_storage();
    $strdeleted = get_string('deleted');
    $course_category = grade_category::fetch_course_category($courseid);
    $course_category->delete('coursedelete');
    $fs->delete_area_files(get_context_instance(CONTEXT_COURSE, $courseid)->id, 'grade', 'feedback');
    if ($showfeedback) {
        echo $OUTPUT->notification($strdeleted . ' - ' . get_string('grades', 'grades') . ', ' . get_string('items', 'grades') . ', ' . get_string('categories', 'grades'), 'notifysuccess');
    }
    if ($outcomes = grade_outcome::fetch_all(array('courseid' => $courseid))) {
        foreach ($outcomes as $outcome) {
            $outcome->delete('coursedelete');
        }
    }
    $DB->delete_records('grade_outcomes_courses', array('courseid' => $courseid));
    if ($showfeedback) {
        echo $OUTPUT->notification($strdeleted . ' - ' . get_string('outcomes', 'grades'), 'notifysuccess');
    }
    if ($scales = grade_scale::fetch_all(array('courseid' => $courseid))) {
        foreach ($scales as $scale) {
            $scale->delete('coursedelete');
        }
    }
    if ($showfeedback) {
        echo $OUTPUT->notification($strdeleted . ' - ' . get_string('scales'), 'notifysuccess');
    }
    $DB->delete_records('grade_settings', array('courseid' => $courseid));
    if ($showfeedback) {
        echo $OUTPUT->notification($strdeleted . ' - ' . get_string('settings', 'grades'), 'notifysuccess');
    }
}
Exemple #9
0
 /**
  * Load grade_item data into the database, and adds the corresponding objects to this class' variable.
  */
 protected function load_grade_items()
 {
     global $DB;
     // Purge all items created by module generators.
     $DB->delete_records('grade_items', array('itemtype' => 'mod'));
     $course_category = grade_category::fetch_course_category($this->course->id);
     // id = 0
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->categoryid = $this->grade_categories[1]->id;
     $grade_item->itemname = 'unittestgradeitem1';
     $grade_item->itemtype = 'mod';
     $grade_item->itemmodule = $this->course_module[0]->modname;
     $grade_item->iteminstance = $this->course_module[0]->instance;
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->grademin = 30;
     $grade_item->grademax = 110;
     $grade_item->itemnumber = 1;
     $grade_item->idnumber = 'item id 0';
     $grade_item->iteminfo = 'Grade item 0 used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 3;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[0] = $grade_item;
     // id = 1
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->categoryid = $this->grade_categories[1]->id;
     $grade_item->itemname = 'unittestgradeitem2';
     $grade_item->itemtype = 'import';
     $grade_item->itemmodule = $this->course_module[1]->modname;
     $grade_item->iteminstance = $this->course_module[1]->instance;
     $grade_item->calculation = '= ##gi' . $this->grade_items[0]->id . '## + 30 + [[item id 0]] - [[item id 0]]';
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->itemnumber = null;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Grade item 1 used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 4;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[1] = $grade_item;
     // id = 2
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->categoryid = $this->grade_categories[2]->id;
     $grade_item->itemname = 'unittestgradeitem3';
     $grade_item->itemtype = 'mod';
     $grade_item->itemmodule = $this->course_module[2]->modname;
     $grade_item->iteminstance = $this->course_module[2]->instance;
     $grade_item->gradetype = GRADE_TYPE_SCALE;
     $grade_item->scaleid = $this->scale[0]->id;
     $grade_item->grademin = 0;
     $grade_item->grademax = $this->scalemax[0];
     $grade_item->iteminfo = 'Grade item 2 used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 6;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[2] = $grade_item;
     // Load grade_items associated with the 3 categories.
     // id = 3
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->iteminstance = $this->grade_categories[0]->id;
     $grade_item->itemname = 'unittestgradeitemcategory1';
     $grade_item->needsupdate = 0;
     $grade_item->itemtype = 'category';
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Grade item 3 used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 1;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[3] = $grade_item;
     // id = 4
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->iteminstance = $this->grade_categories[1]->id;
     $grade_item->itemname = 'unittestgradeitemcategory2';
     $grade_item->itemtype = 'category';
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->needsupdate = 0;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Grade item 4 used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 2;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[4] = $grade_item;
     // id = 5
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->iteminstance = $this->grade_categories[2]->id;
     $grade_item->itemname = 'unittestgradeitemcategory3';
     $grade_item->itemtype = 'category';
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->needsupdate = true;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Grade item 5 used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 5;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[5] = $grade_item;
     // Orphan grade_item.
     // id = 6
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->categoryid = $course_category->id;
     $grade_item->itemname = 'unittestorphangradeitem1';
     $grade_item->itemtype = 'mod';
     $grade_item->itemmodule = $this->course_module[4]->modname;
     $grade_item->iteminstance = $this->course_module[4]->instance;
     $grade_item->itemnumber = 0;
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->grademin = 10;
     $grade_item->grademax = 120;
     $grade_item->locked = time();
     $grade_item->iteminfo = 'Orphan Grade 6 item used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 7;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[6] = $grade_item;
     // 2 grade items under level1category.
     // id = 7
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->categoryid = $this->grade_categories[3]->id;
     $grade_item->itemname = 'singleparentitem1';
     $grade_item->itemtype = 'mod';
     $grade_item->itemmodule = $this->course_module[5]->modname;
     $grade_item->iteminstance = $this->course_module[5]->instance;
     $grade_item->gradetype = GRADE_TYPE_SCALE;
     $grade_item->scaleid = $this->scale[0]->id;
     $grade_item->grademin = 0;
     $grade_item->grademax = $this->scalemax[0];
     $grade_item->iteminfo = 'Grade item 7 used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 9;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[7] = $grade_item;
     // id = 8
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->categoryid = $this->grade_categories[3]->id;
     $grade_item->itemname = 'singleparentitem2';
     $grade_item->itemtype = 'mod';
     $grade_item->itemmodule = $this->course_module[6]->modname;
     $grade_item->iteminstance = $this->course_module[6]->instance;
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Grade item 8 used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 10;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[8] = $grade_item;
     // Grade_item for level1category.
     // id = 9
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->itemname = 'grade_item for level1 category';
     $grade_item->itemtype = 'category';
     $grade_item->iteminstance = $this->grade_categories[3]->id;
     $grade_item->needsupdate = true;
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Orphan Grade item 9 used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 8;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[9] = $grade_item;
     // Manual grade_item.
     // id = 10
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->categoryid = $course_category->id;
     $grade_item->itemname = 'manual grade_item';
     $grade_item->itemtype = 'manual';
     $grade_item->itemnumber = 0;
     $grade_item->needsupdate = false;
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Manual grade item 10 used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 10;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[10] = $grade_item;
     // Quiz grade_item (course_module = 7).
     // id = 11
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->categoryid = $course_category->id;
     $grade_item->itemname = 'Quiz grade item';
     $grade_item->itemtype = 'mod';
     $grade_item->itemmodule = $this->course_module[7]->modname;
     $grade_item->iteminstance = $this->course_module[7]->instance;
     $grade_item->itemnumber = 0;
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->locked = 0;
     $grade_item->iteminfo = 'Quiz grade item used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 11;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[11] = $grade_item;
     // id = 12
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->iteminstance = $this->grade_categories[4]->id;
     $grade_item->itemname = 'unittestgradeitemaggregatesubcats';
     $grade_item->itemtype = 'category';
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->needsupdate = true;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Grade item 12 used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 12;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[12] = $grade_item;
     // id = 13
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->iteminstance = $this->grade_categories[5]->id;
     $grade_item->itemname = 'unittestgradeitemcategory5';
     $grade_item->itemtype = 'category';
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->needsupdate = true;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Grade item 13 used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 13;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[13] = $grade_item;
     // id = 14
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->iteminstance = $this->grade_categories[6]->id;
     $grade_item->itemname = 'unittestgradeitemcategory6';
     $grade_item->itemtype = 'category';
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->needsupdate = true;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Grade item 14 used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 14;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[14] = $grade_item;
     // Manual grade_item
     // id = 15
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->categoryid = $this->grade_categories[5]->id;
     $grade_item->itemname = 'manual grade_item';
     $grade_item->itemtype = 'manual';
     $grade_item->itemnumber = 0;
     $grade_item->needsupdate = false;
     $grade_item->gradetype = GRADE_TYPE_VALUE;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Manual grade item 15 used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 15;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[15] = $grade_item;
     // Manual grade_item
     // id = 16
     $grade_item = new stdClass();
     $grade_item->courseid = $this->course->id;
     $grade_item->categoryid = $this->grade_categories[6]->id;
     $grade_item->itemname = 'manual grade_item';
     $grade_item->itemtype = 'manual';
     $grade_item->itemnumber = 0;
     $grade_item->needsupdate = false;
     $grade_item->gradetype = GRADE_TYPE_SCALE;
     $grade_item->grademin = 0;
     $grade_item->grademax = 100;
     $grade_item->iteminfo = 'Manual grade item 16 used for unit testing';
     $grade_item->timecreated = time();
     $grade_item->timemodified = time();
     $grade_item->sortorder = 16;
     $grade_item->id = $DB->insert_record('grade_items', $grade_item);
     $this->grade_items[16] = $grade_item;
     // $this->grade_items[17] loaded in load_grade_outcomes() in order to use an outcome id.
 }
function restore_create_gradebook($restore, $xml_file)
{
    global $CFG, $db, $SESSION;
    $status = true;
    //Check it exists
    if (!file_exists($xml_file)) {
        return false;
    }
    // Get info from xml
    // info will contain the number of record to process
    $info = restore_read_xml_gradebook($restore, $xml_file);
    // If we have info, then process
    if ($info <= 0) {
        return $status;
    }
    // Count how many we have
    $categoriescount = count_records('backup_ids', 'backup_code', $restore->backup_unique_code, 'table_name', 'grade_categories');
    $itemscount = count_records('backup_ids', 'backup_code', $restore->backup_unique_code, 'table_name', 'grade_items');
    $outcomecount = count_records('backup_ids', 'backup_code', $restore->backup_unique_code, 'table_name', 'grade_outcomes');
    $outcomescoursescount = count_records('backup_ids', 'backup_code', $restore->backup_unique_code, 'table_name', 'grade_outcomes_courses');
    $gchcount = count_records('backup_ids', 'backup_code', $restore->backup_unique_code, 'table_name', 'grade_categories_history');
    $gghcount = count_records('backup_ids', 'backup_code', $restore->backup_unique_code, 'table_name', 'grade_grades_history');
    $gihcount = count_records('backup_ids', 'backup_code', $restore->backup_unique_code, 'table_name', 'grade_items_history');
    $gohcount = count_records('backup_ids', 'backup_code', $restore->backup_unique_code, 'table_name', 'grade_outcomes_history');
    // we need to know if all grade items that were backed up are being restored
    // if that is not the case, we do not restore grade categories nor gradeitems of category type or course type
    // i.e. the aggregated grades of that category
    $restoreall = true;
    // set to false if any grade_item is not selected/restored
    if ($recs = get_records_select("backup_ids", "table_name = 'grade_items' AND backup_code = '{$restore->backup_unique_code}'", "old_id", "old_id")) {
        foreach ($recs as $rec) {
            if ($data = backup_getid($restore->backup_unique_code, 'grade_items', $rec->old_id)) {
                $info = $data->info;
                // do not restore if this grade_item is a mod, and
                $itemtype = backup_todb($info['GRADE_ITEM']['#']['ITEMTYPE']['0']['#']);
                if ($itemtype == 'mod') {
                    $iteminstance = backup_todb($info['GRADE_ITEM']['#']['ITEMINSTANCE']['0']['#']);
                    $itemmodule = backup_todb($info['GRADE_ITEM']['#']['ITEMMODULE']['0']['#']);
                    if (!restore_userdata_selected($restore, $itemmodule, $iteminstance)) {
                        // module instance not selected when restored using granular
                        // we are not restoring all grade items, set flag to false
                        // so that we do not process grade categories and related grade items/grades
                        $restoreall = false;
                        break;
                    }
                }
            }
        }
    }
    // return if nothing to restore
    if (!$itemscount && !$categoriescount && !$outcomecount) {
        return $status;
    }
    // Start ul
    if (!defined('RESTORE_SILENTLY')) {
        echo '<ul>';
    }
    // fetch the course grade item
    require_once $CFG->libdir . '/grade/grade_item.php';
    require_once $CFG->libdir . '/grade/grade_category.php';
    require_once $CFG->libdir . '/gradelib.php';
    $courseitem = grade_item::fetch_course_item($restore->course_id);
    $coursecategory = grade_category::fetch_course_category($restore->course_id);
    // Number of records to get in every chunk
    $recordset_size = 2;
    // Flag to mark if we must continue
    $continue = true;
    // Process categories
    if ($categoriescount && $continue && $restoreall) {
        if (!defined('RESTORE_SILENTLY')) {
            echo '<li>' . get_string('gradecategories', 'grades') . '</li>';
        }
        $counter = 0;
        while ($counter < $categoriescount) {
            // Fetch recordset_size records in each iteration
            $recs = get_records_select("backup_ids", "table_name = 'grade_categories' AND 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, 'grade_categories', $rec->old_id);
                    if ($data) {
                        // Now get completed xmlized object
                        $info = $data->info;
                        //traverse_xmlize($info);                            //Debug
                        //print_object ($GLOBALS['traverse_array']);         //Debug
                        //$GLOBALS['traverse_array']="";                     //Debug
                        //Now build the GRADE_PREFERENCES record structure
                        $dbrec->courseid = $restore->course_id;
                        // categories are not backed up during import.
                        // however, depth 1 categories needs to be skipped during restore into exisiting course
                        // get the new grade category parent
                        //if (!empty($info['GRADE_CATEGORY']['#']['PARENT']['0']['#']) && $info['GRADE_CATEGORY']['#']['PARENT']['0']['#'] != '$@NULL@$') {
                        $parent = backup_getid($restore->backup_unique_code, 'grade_categories', backup_todb($info['GRADE_CATEGORY']['#']['PARENT']['0']['#']));
                        if (isset($parent->new_id)) {
                            $dbrec->parent = $parent->new_id;
                        } else {
                            // orphans should get adopted by course category
                            $dbrec->parent = $coursecategory->id;
                        }
                        //}
                        $dbrec->fullname = backup_todb($info['GRADE_CATEGORY']['#']['FULLNAME']['0']['#']);
                        $dbrec->aggregation = backup_todb($info['GRADE_CATEGORY']['#']['AGGREGATION']['0']['#']);
                        $dbrec->keephigh = backup_todb($info['GRADE_CATEGORY']['#']['KEEPHIGH']['0']['#']);
                        $dbrec->droplow = backup_todb($info['GRADE_CATEGORY']['#']['DROPLOW']['0']['#']);
                        $dbrec->aggregateoutcomes = backup_todb($info['GRADE_CATEGORY']['#']['AGGREGATEOUTCOMES']['0']['#']);
                        //Structure is equal to db, insert record
                        //if the fullname doesn't exist
                        if (!($prerec = get_record('grade_categories', 'courseid', $dbrec->courseid, 'fullname', $dbrec->fullname))) {
                            $newid = insert_record('grade_categories', $dbrec);
                            $status = backup_putid($restore->backup_unique_code, 'grade_categories', $rec->old_id, $newid);
                            // update this record so we can put in the right paths
                            // this can only be done after we got the new id
                            $dbrec->id = $newid;
                            include_once $CFG->dirroot . '/lib/grade/grade_category.php';
                            // rebuild the path, we need only parents info
                            // the order of restoring should ensure that the parent and grandparent(s)
                            // are already restored
                            $dbrec->path = grade_category::build_path($dbrec);
                            // this is not needed in the xml because
                            // given this parent and grandparent(s) we can recalculate the depth
                            $dbrec->depth = substr_count($dbrec->path, '/');
                            update_record('grade_categories', $dbrec);
                        } else {
                            // if fullname already exists, we should keep the current grade category
                            $status = backup_putid($restore->backup_unique_code, 'grade_categories', $rec->old_id, $rec->oldid);
                        }
                    }
                    //Increment counters
                    $counter++;
                    //Do some output
                    if ($counter % 1 == 0) {
                        if (!defined('RESTORE_SILENTLY')) {
                            echo ".";
                            if ($counter % 20 == 0) {
                                echo "<br />";
                            }
                        }
                        backup_flush(300);
                    }
                }
            }
        }
    }
    // process outcomes
    if ($outcomecount && $continue) {
        if (!defined('RESTORE_SILENTLY')) {
            echo '<li>' . get_string('gradeoutcomes', 'grades') . '</li>';
        }
        $counter = 0;
        while ($counter < $outcomecount) {
            //Fetch recordset_size records in each iteration
            $recs = get_records_select("backup_ids", "table_name = 'grade_outcomes' AND 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, 'grade_outcomes', $rec->old_id);
                    if ($data) {
                        //Now get completed xmlized object
                        $info = $data->info;
                        //traverse_xmlize($info);                            //Debug
                        //print_object ($GLOBALS['traverse_array']);         //Debug
                        //$GLOBALS['traverse_array']="";                     //Debug
                        //Now build the GRADE_PREFERENCES record structure
                        if ($info['GRADE_OUTCOME']['#']['COURSEID']['0']['#']) {
                            $dbrec->courseid = $restore->course_id;
                        } else {
                            $dbrec->courseid = NULL;
                        }
                        $dbrec->shortname = backup_todb($info['GRADE_OUTCOME']['#']['SHORTNAME']['0']['#']);
                        $dbrec->fullname = backup_todb($info['GRADE_OUTCOME']['#']['FULLNAME']['0']['#']);
                        if ($info['GRADE_OUTCOME']['#']['SCALEID']['0']['#']) {
                            $scale = backup_getid($restore->backup_unique_code, "scale", backup_todb($info['GRADE_OUTCOME']['#']['SCALEID']['0']['#']));
                            $dbrec->scaleid = $scale->new_id;
                        }
                        $modifier = backup_getid($restore->backup_unique_code, "user", backup_todb($info['GRADE_OUTCOME']['#']['USERMODIFIED']['0']['#']));
                        $dbrec->usermodified = $modifier->new_id;
                        // Structure is equal to db, insert record
                        // If the shortname doesn't exist
                        if (empty($info['GRADE_OUTCOME']['#']['COURSEID']['0']['#'])) {
                            $prerec = get_record_sql("SELECT * FROM {$CFG->prefix}grade_outcomes\n                                                                   WHERE courseid IS NULL\n                                                                   AND shortname = '{$dbrec->shortname}'");
                        } else {
                            $prerec = get_record('grade_outcomes', 'courseid', $restore->course_id, 'shortname', $dbrec->shortname);
                        }
                        if (!$prerec) {
                            $newid = insert_record('grade_outcomes', $dbrec);
                        } else {
                            $newid = $prerec->id;
                        }
                        if ($newid) {
                            backup_putid($restore->backup_unique_code, "grade_outcomes", $rec->old_id, $newid);
                        }
                    }
                    //Increment counters
                    $counter++;
                    //Do some output
                    if ($counter % 1 == 0) {
                        if (!defined('RESTORE_SILENTLY')) {
                            echo ".";
                            if ($counter % 20 == 0) {
                                echo "<br />";
                            }
                        }
                        backup_flush(300);
                    }
                }
            }
        }
    }
    // process outcomescourses
    if ($outcomescoursescount && $continue) {
        if (!defined('RESTORE_SILENTLY')) {
            echo '<li>' . get_string('gradeoutcomescourses', 'grades') . '</li>';
        }
        $counter = 0;
        while ($counter < $outcomescoursescount) {
            //Fetch recordset_size records in each iteration
            $recs = get_records_select("backup_ids", "table_name = 'grade_outcomes_courses' AND 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, 'grade_outcomes_courses', $rec->old_id);
                    if ($data) {
                        //Now get completed xmlized object
                        $info = $data->info;
                        //traverse_xmlize($info);                            //Debug
                        //print_object ($GLOBALS['traverse_array']);         //Debug
                        //$GLOBALS['traverse_array']="";                     //Debug
                        $oldoutcomesid = backup_todb($info['GRADE_OUTCOMES_COURSE']['#']['OUTCOMEID']['0']['#']);
                        $newoutcome = backup_getid($restore->backup_unique_code, "grade_outcomes", $oldoutcomesid);
                        unset($dbrec);
                        $dbrec->courseid = $restore->course_id;
                        $dbrec->outcomeid = $newoutcome->new_id;
                        insert_record('grade_outcomes_courses', $dbrec);
                    }
                    //Increment counters
                    $counter++;
                    //Do some output
                    if ($counter % 1 == 0) {
                        if (!defined('RESTORE_SILENTLY')) {
                            echo ".";
                            if ($counter % 20 == 0) {
                                echo "<br />";
                            }
                        }
                        backup_flush(300);
                    }
                }
            }
        }
    }
    // Process grade items (grade_grade)
    if ($itemscount && $continue) {
        if (!defined('RESTORE_SILENTLY')) {
            echo '<li>' . get_string('gradeitems', 'grades') . '</li>';
        }
        $counter = 0;
        $counteritems = 0;
        while ($counteritems < $itemscount) {
            //Fetch recordset_size records in each iteration
            $recs = get_records_select("backup_ids", "table_name = 'grade_items' AND backup_code = '{$restore->backup_unique_code}'", "old_id", "old_id", $counteritems, $recordset_size);
            if ($recs) {
                foreach ($recs as $rec) {
                    //Get the full record from backup_ids
                    $data = backup_getid($restore->backup_unique_code, 'grade_items', $rec->old_id);
                    if ($data) {
                        //Now get completed xmlized object
                        $info = $data->info;
                        //traverse_xmlize($info);                            //Debug
                        //print_object ($GLOBALS['traverse_array']);         //Debug
                        //$GLOBALS['traverse_array']="";                     //Debug
                        $dbrec->courseid = $restore->course_id;
                        if (isset($SESSION->restore->importing)) {
                            // if we are importing, points all grade_items to the course category
                            $coursecat = get_record('grade_categories', 'courseid', $restore->course_id, 'depth', 1);
                            $dbrec->categoryid = $coursecat->id;
                        } else {
                            if (!empty($info['GRADE_ITEM']['#']['CATEGORYID']['0']['#']) && $info['GRADE_ITEM']['#']['CATEGORYID']['0']['#'] != '$@NULL@$') {
                                $category = backup_getid($restore->backup_unique_code, 'grade_categories', backup_todb($info['GRADE_ITEM']['#']['CATEGORYID']['0']['#']));
                                if ($category->new_id) {
                                    $dbrec->categoryid = $category->new_id;
                                } else {
                                    // this could be restoring into existing course, and grade item points to the old course grade item (category)
                                    // which was never imported. In this case we just point them to the new course item
                                    $dbrec->categoryid = $coursecategory->id;
                                }
                            }
                        }
                        $dbrec->itemname = backup_todb($info['GRADE_ITEM']['#']['ITEMNAME']['0']['#']);
                        $dbrec->itemtype = backup_todb($info['GRADE_ITEM']['#']['ITEMTYPE']['0']['#']);
                        $dbrec->itemmodule = backup_todb($info['GRADE_ITEM']['#']['ITEMMODULE']['0']['#']);
                        /// this needs to point to either the new mod id
                        /// or the category id
                        $iteminstance = backup_todb($info['GRADE_ITEM']['#']['ITEMINSTANCE']['0']['#']);
                        // do not restore if this grade_item is a mod, and
                        if ($dbrec->itemtype == 'mod') {
                            // iteminstance should point to new mod
                            $mod = backup_getid($restore->backup_unique_code, $dbrec->itemmodule, $iteminstance);
                            $dbrec->iteminstance = $mod->new_id;
                        } else {
                            if ($dbrec->itemtype == 'category') {
                                // the item instance should point to the new grade category
                                // only proceed if we are restoring all grade items
                                // need to skip for imports
                                if ($restoreall && !isset($SESSION->restore->importing)) {
                                    $category = backup_getid($restore->backup_unique_code, 'grade_categories', $iteminstance);
                                    $dbrec->iteminstance = $category->new_id;
                                } else {
                                    // otherwise we can safely ignore this grade item and subsequent
                                    // grade_raws, grade_finals etc
                                    $counteritems++;
                                    continue;
                                }
                            } elseif ($dbrec->itemtype == 'course') {
                                // We don't restore course type to avoid duplicate course items
                                if ($restoreall && !isset($SESSION->restore->importing) && $restore->restoreto == 2) {
                                    // TODO any special code needed here to restore course item without duplicating it?
                                    // find the course category with depth 1, and course id = current course id
                                    // this would have been already restored
                                    $counteritems++;
                                    continue;
                                } else {
                                    $counteritems++;
                                    continue;
                                }
                            }
                        }
                        $dbrec->itemnumber = backup_todb($info['GRADE_ITEM']['#']['ITEMNUMBER']['0']['#']);
                        $dbrec->iteminfo = backup_todb($info['GRADE_ITEM']['#']['ITEMINFO']['0']['#']);
                        $dbrec->idnumber = backup_todb($info['GRADE_ITEM']['#']['IDNUMBER']['0']['#']);
                        $dbrec->calculation = backup_todb($info['GRADE_ITEM']['#']['CALCULATION']['0']['#']);
                        $dbrec->grademax = backup_todb($info['GRADE_ITEM']['#']['GRADEMAX']['0']['#']);
                        $dbrec->grademin = backup_todb($info['GRADE_ITEM']['#']['GRADEMIN']['0']['#']);
                        /// needs to be restored first
                        if (backup_todb($info['GRADE_ITEM']['#']['SCALEID']['0']['#'])) {
                            $scale = backup_getid($restore->backup_unique_code, "scale", backup_todb($info['GRADE_ITEM']['#']['SCALEID']['0']['#']));
                            $dbrec->scaleid = $scale->new_id;
                        }
                        /// needs to be restored first
                        $dbrec->outcomeid = backup_getid($restore->backup_unique_code, "grade_outcomes", backup_todb($info['GRADE_ITEM']['#']['OUTCOMEID']['0']['#']));
                        $dbrec->gradepass = backup_todb($info['GRADE_ITEM']['#']['GRADEPASS']['0']['#']);
                        $dbrec->multfactor = backup_todb($info['GRADE_ITEM']['#']['MULTFACTOR']['0']['#']);
                        $dbrec->plusfactor = backup_todb($info['GRADE_ITEM']['#']['PLUSFACTOR']['0']['#']);
                        $dbrec->hidden = backup_todb($info['GRADE_ITEM']['#']['HIDDEN']['0']['#']);
                        $dbrec->locked = backup_todb($info['GRADE_ITEM']['#']['LOCKED']['0']['#']);
                        $dbrec->locktime = backup_todb($info['GRADE_ITEM']['#']['LOCKTIME']['0']['#']);
                        $dbrec->needsupdate = backup_todb($info['GRADE_ITEM']['#']['NEEDSUPDATE']['0']['#']);
                        $dbrec->timecreated = backup_todb($info['GRADE_ITEM']['#']['TIMECREATED']['0']['#']);
                        $dbrec->timemodified = backup_todb($info['GRADE_ITEM']['#']['TIMEMODIFIED']['0']['#']);
                        // get the current sortorder, add 1 to it and use that
                        if ($lastitem = get_record_sql("SELECT sortorder, id FROM {$CFG->prefix}grade_items\n                                                        WHERE courseid = {$restore->course_id}\n                                                        ORDER BY sortorder DESC ", true)) {
                            // we just need the first one
                            $dbrec->sortorder = $lastitem->sortorder + 1;
                        } else {
                            // this is the first grade_item
                            $dbrec->sortorder = 1;
                        }
                        // always insert, since modules restored to existing courses are always inserted
                        $itemid = insert_record('grade_items', $dbrec);
                        if ($itemid) {
                            backup_putid($restore->backup_unique_code, 'grade_items', backup_todb($info['GRADE_ITEM']['#']['ID']['0']['#']), $itemid);
                        }
                        // no need to restore grades if user data is not selected
                        if ($dbrec->itemtype == 'mod' && !restore_userdata_selected($restore, $dbrec->itemmodule, $iteminstance)) {
                            // module instance not selected when restored using granular
                            // skip this item
                            $counteritems++;
                            continue;
                        }
                        /// now, restore grade_grades
                        if (!empty($info['GRADE_ITEM']['#']['GRADE_GRADES']['0']['#']) && ($grades = $info['GRADE_ITEM']['#']['GRADE_GRADES']['0']['#']['GRADE'])) {
                            //Iterate over items
                            for ($i = 0; $i < sizeof($grades); $i++) {
                                $ite_info = $grades[$i];
                                //traverse_xmlize($ite_info);
                                //Debug
                                //print_object ($GLOBALS['traverse_array']);                                                  //Debug
                                //$GLOBALS['traverse_array']="";                                                              //Debug
                                //Now build the GRADE_ITEM record structure
                                $grade = new object();
                                $grade->itemid = $itemid;
                                $user = backup_getid($restore->backup_unique_code, "user", backup_todb($ite_info['#']['USERID']['0']['#']));
                                $grade->userid = $user->new_id;
                                $grade->rawgrade = backup_todb($ite_info['#']['RAWGRADE']['0']['#']);
                                $grade->rawgrademax = backup_todb($ite_info['#']['RAWGRADEMAX']['0']['#']);
                                $grade->rawgrademin = backup_todb($ite_info['#']['RAWGRADEMIN']['0']['#']);
                                // need to find scaleid
                                if (backup_todb($ite_info['#']['RAWSCALEID']['0']['#'])) {
                                    $scale = backup_getid($restore->backup_unique_code, "scale", backup_todb($ite_info['#']['RAWSCALEID']['0']['#']));
                                    $grade->rawscaleid = $scale->new_id;
                                }
                                $grade->finalgrade = backup_todb($ite_info['#']['FINALGRADE']['0']['#']);
                                $grade->hidden = backup_todb($ite_info['#']['HIDDEN']['0']['#']);
                                $grade->locked = backup_todb($ite_info['#']['LOCKED']['0']['#']);
                                $grade->locktime = backup_todb($ite_info['#']['LOCKTIME']['0']['#']);
                                $grade->exported = backup_todb($ite_info['#']['EXPORTED']['0']['#']);
                                $grade->overridden = backup_todb($ite_info['#']['OVERRIDDEN']['0']['#']);
                                $grade->excluded = backup_todb($ite_info['#']['EXCLUDED']['0']['#']);
                                $grade->feedback = backup_todb($ite_info['#']['FEEDBACK']['0']['#']);
                                $grade->feedbackformat = backup_todb($ite_info['#']['FEEDBACKFORMAT']['0']['#']);
                                $grade->information = backup_todb($ite_info['#']['INFORMATION']['0']['#']);
                                $grade->informationformat = backup_todb($ite_info['#']['INFORMATIONFORMAT']['0']['#']);
                                $newid = insert_record('grade_grades', $grade);
                                if ($newid) {
                                    backup_putid($restore->backup_unique_code, "grade_grades", backup_todb($ite_info['#']['ID']['0']['#']), $newid);
                                }
                                $counter++;
                                if ($counter % 20 == 0) {
                                    if (!defined('RESTORE_SILENTLY')) {
                                        echo ".";
                                        if ($counter % 400 == 0) {
                                            echo "<br />";
                                        }
                                    }
                                    backup_flush(300);
                                }
                            }
                        }
                    }
                    $counteritems++;
                    // increment item count
                }
            }
        }
    }
    // process histories
    if ($gchcount && $continue && !isset($SESSION->restore->importing) && $restore->restore_gradebook_history) {
        if (!defined('RESTORE_SILENTLY')) {
            echo '<li>' . get_string('gradecategoryhistory', 'grades') . '</li>';
        }
        $counter = 0;
        while ($counter < $gchcount) {
            //Fetch recordset_size records in each iteration
            $recs = get_records_select("backup_ids", "table_name = 'grade_categories_history' AND 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, 'grade_categories_history', $rec->old_id);
                    if ($data) {
                        //Now get completed xmlized object
                        $info = $data->info;
                        //traverse_xmlize($info);                            //Debug
                        //print_object ($GLOBALS['traverse_array']);         //Debug
                        //$GLOBALS['traverse_array']="";                     //Debug
                        $oldobj = backup_getid($restore->backup_unique_code, "grade_categories", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['OLDID']['0']['#']));
                        if (empty($oldobj->new_id)) {
                            // if the old object is not being restored, can't restoring its history
                            $counter++;
                            continue;
                        }
                        $dbrec->oldid = $oldobj->new_id;
                        $dbrec->action = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['ACTION']['0']['#']);
                        $dbrec->source = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['SOURCE']['0']['#']);
                        $dbrec->timemodified = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
                        // loggeduser might not be restored, e.g. admin
                        if ($oldobj = backup_getid($restore->backup_unique_code, "user", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
                            $dbrec->loggeduser = $oldobj->new_id;
                        }
                        // this item might not have a parent at all, do not skip it if no parent is specified
                        if (backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PARENT']['0']['#'])) {
                            $oldobj = backup_getid($restore->backup_unique_code, "grade_categories", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PARENT']['0']['#']));
                            if (empty($oldobj->new_id)) {
                                // if the parent category not restored
                                $counter++;
                                continue;
                            }
                        }
                        $dbrec->parent = $oldobj->new_id;
                        $dbrec->depth = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['DEPTH']['0']['#']);
                        // path needs to be rebuilt
                        if ($path = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PATH']['0']['#'])) {
                            // to preserve the path and make it work, we need to replace the categories one by one
                            // we first get the list of categories in current path
                            if ($paths = explode("/", $path)) {
                                $newpath = '';
                                foreach ($paths as $catid) {
                                    if ($catid) {
                                        // find the new corresponding path
                                        $oldpath = backup_getid($restore->backup_unique_code, "grade_categories", $catid);
                                        $newpath .= "/{$oldpath->new_id}";
                                    }
                                }
                                $dbrec->path = $newpath;
                            }
                        }
                        $dbrec->fullname = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['FULLNAME']['0']['#']);
                        $dbrec->aggregation = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['AGGRETGATION']['0']['#']);
                        $dbrec->keephigh = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['KEEPHIGH']['0']['#']);
                        $dbrec->droplow = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['DROPLOW']['0']['#']);
                        $dbrec->courseid = $restore->course_id;
                        insert_record('grade_categories_history', $dbrec);
                        unset($dbrec);
                    }
                    //Increment counters
                    $counter++;
                    //Do some output
                    if ($counter % 1 == 0) {
                        if (!defined('RESTORE_SILENTLY')) {
                            echo ".";
                            if ($counter % 20 == 0) {
                                echo "<br />";
                            }
                        }
                        backup_flush(300);
                    }
                }
            }
        }
    }
    // process histories
    if ($gghcount && $continue && !isset($SESSION->restore->importing) && $restore->restore_gradebook_history) {
        if (!defined('RESTORE_SILENTLY')) {
            echo '<li>' . get_string('gradegradeshistory', 'grades') . '</li>';
        }
        $counter = 0;
        while ($counter < $gghcount) {
            //Fetch recordset_size records in each iteration
            $recs = get_records_select("backup_ids", "table_name = 'grade_grades_history' AND 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, 'grade_grades_history', $rec->old_id);
                    if ($data) {
                        //Now get completed xmlized object
                        $info = $data->info;
                        //traverse_xmlize($info);                            //Debug
                        //print_object ($GLOBALS['traverse_array']);         //Debug
                        //$GLOBALS['traverse_array']="";                     //Debug
                        $oldobj = backup_getid($restore->backup_unique_code, "grade_grades", backup_todb($info['GRADE_GRADES_HISTORY']['#']['OLDID']['0']['#']));
                        if (empty($oldobj->new_id)) {
                            // if the old object is not being restored, can't restoring its history
                            $counter++;
                            continue;
                        }
                        $dbrec->oldid = $oldobj->new_id;
                        $dbrec->action = backup_todb($info['GRADE_GRADES_HISTORY']['#']['ACTION']['0']['#']);
                        $dbrec->source = backup_todb($info['GRADE_GRADES_HISTORY']['#']['SOURCE']['0']['#']);
                        $dbrec->timemodified = backup_todb($info['GRADE_GRADES_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
                        if ($oldobj = backup_getid($restore->backup_unique_code, "user", backup_todb($info['GRADE_GRADES_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
                            $dbrec->loggeduser = $oldobj->new_id;
                        }
                        $oldobj = backup_getid($restore->backup_unique_code, "grade_items", backup_todb($info['GRADE_GRADES_HISTORY']['#']['ITEMID']['0']['#']));
                        $dbrec->itemid = $oldobj->new_id;
                        if (empty($dbrec->itemid)) {
                            $counter++;
                            continue;
                            // grade item not being restored
                        }
                        $oldobj = backup_getid($restore->backup_unique_code, "user", backup_todb($info['GRADE_GRADES_HISTORY']['#']['USERID']['0']['#']));
                        $dbrec->userid = $oldobj->new_id;
                        $dbrec->rawgrade = backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWGRADE']['0']['#']);
                        $dbrec->rawgrademax = backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWGRADEMAX']['0']['#']);
                        $dbrec->rawgrademin = backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWGRADEMIN']['0']['#']);
                        if ($oldobj = backup_getid($restore->backup_unique_code, "user", backup_todb($info['GRADE_GRADES_HISTORY']['#']['USERMODIFIED']['0']['#']))) {
                            $dbrec->usermodified = $oldobj->new_id;
                        }
                        $dbrec->finalgrade = backup_todb($info['GRADE_GRADES_HISTORY']['#']['FINALGRADE']['0']['#']);
                        $dbrec->hidden = backup_todb($info['GRADE_GRADES_HISTORY']['#']['HIDDEN']['0']['#']);
                        $dbrec->locked = backup_todb($info['GRADE_GRADES_HISTORY']['#']['LOCKED']['0']['#']);
                        $dbrec->locktime = backup_todb($info['GRADE_GRADES_HISTORY']['#']['LOCKTIME']['0']['#']);
                        $dbrec->exported = backup_todb($info['GRADE_GRADES_HISTORY']['#']['EXPORTED']['0']['#']);
                        $dbrec->overridden = backup_todb($info['GRADE_GRADES_HISTORY']['#']['OVERRIDDEN']['0']['#']);
                        $dbrec->excluded = backup_todb($info['GRADE_GRADES_HISTORY']['#']['EXCLUDED']['0']['#']);
                        $dbrec->feedback = backup_todb($info['GRADE_TEXT_HISTORY']['#']['FEEDBACK']['0']['#']);
                        $dbrec->feedbackformat = backup_todb($info['GRADE_TEXT_HISTORY']['#']['FEEDBACKFORMAT']['0']['#']);
                        $dbrec->information = backup_todb($info['GRADE_TEXT_HISTORY']['#']['INFORMATION']['0']['#']);
                        $dbrec->informationformat = backup_todb($info['GRADE_TEXT_HISTORY']['#']['INFORMATIONFORMAT']['0']['#']);
                        insert_record('grade_grades_history', $dbrec);
                        unset($dbrec);
                    }
                    //Increment counters
                    $counter++;
                    //Do some output
                    if ($counter % 1 == 0) {
                        if (!defined('RESTORE_SILENTLY')) {
                            echo ".";
                            if ($counter % 20 == 0) {
                                echo "<br />";
                            }
                        }
                        backup_flush(300);
                    }
                }
            }
        }
    }
    // process histories
    if ($gihcount && $continue && !isset($SESSION->restore->importing) && $restore->restore_gradebook_history) {
        if (!defined('RESTORE_SILENTLY')) {
            echo '<li>' . get_string('gradeitemshistory', 'grades') . '</li>';
        }
        $counter = 0;
        while ($counter < $gihcount) {
            //Fetch recordset_size records in each iteration
            $recs = get_records_select("backup_ids", "table_name = 'grade_items_history' AND 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, 'grade_items_history', $rec->old_id);
                    if ($data) {
                        //Now get completed xmlized object
                        $info = $data->info;
                        //traverse_xmlize($info);                            //Debug
                        //print_object ($GLOBALS['traverse_array']);         //Debug
                        //$GLOBALS['traverse_array']="";                     //Debug
                        $oldobj = backup_getid($restore->backup_unique_code, "grade_items", backup_todb($info['GRADE_ITEM_HISTORY']['#']['OLDID']['0']['#']));
                        if (empty($oldobj->new_id)) {
                            // if the old object is not being restored, can't restoring its history
                            $counter++;
                            continue;
                        }
                        $dbrec->oldid = $oldobj->new_id;
                        $dbrec->action = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ACTION']['0']['#']);
                        $dbrec->source = backup_todb($info['GRADE_ITEM_HISTORY']['#']['SOURCE']['0']['#']);
                        $dbrec->timemodified = backup_todb($info['GRADE_ITEM_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
                        if ($oldobj = backup_getid($restore->backup_unique_code, "user", backup_todb($info['GRADE_ITEM_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
                            $dbrec->loggeduser = $oldobj->new_id;
                        }
                        $oldobj = backup_getid($restore->backup_unique_code, 'grade_categories', backup_todb($info['GRADE_ITEM_HISTORY']['#']['CATEGORYID']['0']['#']));
                        $oldobj->categoryid = $category->new_id;
                        if (empty($oldobj->categoryid)) {
                            $counter++;
                            continue;
                            // category not restored
                        }
                        $dbrec->itemname = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMNAME']['0']['#']);
                        $dbrec->itemtype = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMTYPE']['0']['#']);
                        $dbrec->itemmodule = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMMODULE']['0']['#']);
                        // code from grade_items restore
                        $iteminstance = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMINSTANCE']['0']['#']);
                        // do not restore if this grade_item is a mod, and
                        if ($dbrec->itemtype == 'mod') {
                            if (!restore_userdata_selected($restore, $dbrec->itemmodule, $iteminstance)) {
                                // module instance not selected when restored using granular
                                // skip this item
                                $counter++;
                                continue;
                            }
                            // iteminstance should point to new mod
                            $mod = backup_getid($restore->backup_unique_code, $dbrec->itemmodule, $iteminstance);
                            $dbrec->iteminstance = $mod->new_id;
                        } else {
                            if ($dbrec->itemtype == 'category') {
                                // the item instance should point to the new grade category
                                // only proceed if we are restoring all grade items
                                if ($restoreall) {
                                    $category = backup_getid($restore->backup_unique_code, 'grade_categories', $iteminstance);
                                    $dbrec->iteminstance = $category->new_id;
                                } else {
                                    // otherwise we can safely ignore this grade item and subsequent
                                    // grade_raws, grade_finals etc
                                    continue;
                                }
                            } elseif ($dbrec->itemtype == 'course') {
                                // We don't restore course type to avoid duplicate course items
                                if ($restoreall) {
                                    // TODO any special code needed here to restore course item without duplicating it?
                                    // find the course category with depth 1, and course id = current course id
                                    // this would have been already restored
                                    $cat = get_record('grade_categories', 'depth', 1, 'courseid', $restore->course_id);
                                    $dbrec->iteminstance = $cat->id;
                                } else {
                                    $counter++;
                                    continue;
                                }
                            }
                        }
                        $dbrec->itemnumber = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMNUMBER']['0']['#']);
                        $dbrec->iteminfo = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMINFO']['0']['#']);
                        $dbrec->idnumber = backup_todb($info['GRADE_ITEM_HISTORY']['#']['IDNUMBER']['0']['#']);
                        $dbrec->calculation = backup_todb($info['GRADE_ITEM_HISTORY']['#']['CALCULATION']['0']['#']);
                        $dbrec->gradetype = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADETYPE']['0']['#']);
                        $dbrec->grademax = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADEMAX']['0']['#']);
                        $dbrec->grademin = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADEMIN']['0']['#']);
                        if ($oldobj = backup_getid($restore->backup_unique_code, "scale", backup_todb($info['GRADE_ITEM_HISTORY']['#']['SCALEID']['0']['#']))) {
                            // scaleid is optional
                            $dbrec->scaleid = $oldobj->new_id;
                        }
                        if ($oldobj = backup_getid($restore->backup_unique_code, "grade_outcomes", backup_todb($info['GRADE_ITEM_HISTORY']['#']['OUTCOMEID']['0']['#']))) {
                            // outcome is optional
                            $dbrec->outcomeid = $oldobj->new_id;
                        }
                        $dbrec->gradepass = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADEPASS']['0']['#']);
                        $dbrec->multfactor = backup_todb($info['GRADE_ITEM_HISTORY']['#']['MULTFACTOR']['0']['#']);
                        $dbrec->plusfactor = backup_todb($info['GRADE_ITEM_HISTORY']['#']['PLUSFACTOR']['0']['#']);
                        $dbrec->aggregationcoef = backup_todb($info['GRADE_ITEM_HISTORY']['#']['AGGREGATIONCOEF']['0']['#']);
                        $dbrec->sortorder = backup_todb($info['GRADE_ITEM_HISTORY']['#']['SORTORDER']['0']['#']);
                        $dbrec->hidden = backup_todb($info['GRADE_ITEM_HISTORY']['#']['HIDDEN']['0']['#']);
                        $dbrec->locked = backup_todb($info['GRADE_ITEM_HISTORY']['#']['LOCKED']['0']['#']);
                        $dbrec->locktime = backup_todb($info['GRADE_ITEM_HISTORY']['#']['LOCKTIME']['0']['#']);
                        $dbrec->needsupdate = backup_todb($info['GRADE_ITEM_HISTORY']['#']['NEEDSUPDATE']['0']['#']);
                        insert_record('grade_items_history', $dbrec);
                        unset($dbrec);
                    }
                    //Increment counters
                    $counter++;
                    //Do some output
                    if ($counter % 1 == 0) {
                        if (!defined('RESTORE_SILENTLY')) {
                            echo ".";
                            if ($counter % 20 == 0) {
                                echo "<br />";
                            }
                        }
                        backup_flush(300);
                    }
                }
            }
        }
    }
    // process histories
    if ($gohcount && $continue && !isset($SESSION->restore->importing) && $restore->restore_gradebook_history) {
        if (!defined('RESTORE_SILENTLY')) {
            echo '<li>' . get_string('gradeoutcomeshistory', 'grades') . '</li>';
        }
        $counter = 0;
        while ($counter < $gohcount) {
            //Fetch recordset_size records in each iteration
            $recs = get_records_select("backup_ids", "table_name = 'grade_outcomes_history' AND 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, 'grade_outcomes_history', $rec->old_id);
                    if ($data) {
                        //Now get completed xmlized object
                        $info = $data->info;
                        //traverse_xmlize($info);                            //Debug
                        //print_object ($GLOBALS['traverse_array']);         //Debug
                        //$GLOBALS['traverse_array']="";                     //Debug
                        $oldobj = backup_getid($restore->backup_unique_code, "grade_outcomes", backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['OLDID']['0']['#']));
                        if (empty($oldobj->new_id)) {
                            // if the old object is not being restored, can't restoring its history
                            $counter++;
                            continue;
                        }
                        $dbrec->oldid = $oldobj->new_id;
                        $dbrec->action = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['ACTION']['0']['#']);
                        $dbrec->source = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['SOURCE']['0']['#']);
                        $dbrec->timemodified = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
                        if ($oldobj = backup_getid($restore->backup_unique_code, "user", backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
                            $dbrec->loggeduser = $oldobj->new_id;
                        }
                        $dbrec->shortname = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['SHORTNAME']['0']['#']);
                        $dbrec->fullname = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['FULLNAME']['0']['#']);
                        $oldobj = backup_getid($restore->backup_unique_code, "scale", backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['SCALEID']['0']['#']));
                        $dbrec->scaleid = $oldobj->new_id;
                        $dbrec->description = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['DESCRIPTION']['0']['#']);
                        insert_record('grade_outcomes_history', $dbrec);
                        unset($dbrec);
                    }
                    //Increment counters
                    $counter++;
                    //Do some output
                    if ($counter % 1 == 0) {
                        if (!defined('RESTORE_SILENTLY')) {
                            echo ".";
                            if ($counter % 20 == 0) {
                                echo "<br />";
                            }
                        }
                        backup_flush(300);
                    }
                }
            }
        }
    }
    if (!defined('RESTORE_SILENTLY')) {
        //End ul
        echo '</ul>';
    }
    return $status;
}
        $courses = current($distributed_selector->find_users());
    }
}
if (!empty($courses)) {
    set_time_limit(0);
    // This could take a while, so disable max execution time
    $output = '';
    $itemnames = array('target' => get_string('item_mtg', 'report_targetgrades'), 'min' => get_string('item_alis', 'report_targetgrades'), 'alisnum' => get_string('item_alisnum', 'report_targetgrades'), 'avgcse' => get_string('item_avgcse', 'report_targetgrades'), 'cpg' => get_string('item_cpg', 'report_targetgrades'));
    $empty_courses = array();
    $unconfigured_courses = array();
    $empty_students = array();
    $failed_grade_calcs = array();
    $errors = '';
    $infofield = $DB->get_record('user_info_field', array('id' => $config->gcse_field));
    foreach ($courses as $course) {
        $category = grade_category::fetch_course_category($course->id);
        $records = null;
        $regrade = false;
        foreach ($itemnames as $item => $itemname) {
            try {
                if ($grade_item = grade_item::fetch(array('idnumber' => 'targetgrades_' . $item, 'courseid' => $course->id))) {
                    $itemdata = new stdClass();
                    if (empty($grade_item->timecreated)) {
                        $itemdata->timecreated = time();
                    }
                    if (empty($grade_item->itemnumber)) {
                        $itemdata->itemnumber = 0;
                    }
                    grade_item::set_properties($grade_item, $itemdata);
                    $grade_item->update();
                    unset($itemdata);
Exemple #12
0
        $aggregation = new completion_aggregation();
        $aggregation->course = $data->id;
        $aggregation->criteriatype = COMPLETION_CRITERIA_TYPE_COURSE;
        $aggregation->setMethod($data->course_aggregation);
        $aggregation->insert();
        // Role aggregation
        if (empty($data->role_aggregation)) {
            $data->role_aggregation = 0;
        }
        $aggregation = new completion_aggregation();
        $aggregation->course = $data->id;
        $aggregation->criteriatype = COMPLETION_CRITERIA_TYPE_ROLE;
        $aggregation->setMethod($data->role_aggregation);
        $aggregation->insert();
        // Update course total passing grade
        if (!empty($data->criteria_grade)) {
            if ($grade_item = grade_category::fetch_course_category($course->id)->grade_item) {
                $grade_item->gradepass = $data->criteria_grade_value;
                if (method_exists($grade_item, 'update')) {
                    $grade_item->update('course/completion.php');
                }
            }
        }
        redirect($CFG->wwwroot . "/course/view.php?id={$course->id}", get_string('changessaved'));
    }
}
/// Print the form
echo $OUTPUT->header();
echo $OUTPUT->heading($streditcompletionsettings);
$form->display();
echo $OUTPUT->footer();
 function definition_after_data()
 {
     global $CFG, $COURSE;
     $mform =& $this->_form;
     if ($id = $mform->getElementValue('id')) {
         $grade_item = grade_item::fetch(array('id' => $id));
         if (!$grade_item->is_raw_used()) {
             $mform->removeElement('plusfactor');
             $mform->removeElement('multfactor');
         }
         if ($grade_item->is_outcome_item()) {
             // we have to prevent incompatible modifications of outcomes if outcomes disabled
             $mform->removeElement('grademax');
             $mform->removeElement('grademin');
             $mform->removeElement('gradetype');
             $mform->removeElement('display');
             $mform->removeElement('decimals');
             $mform->hardFreeze('scaleid');
         } else {
             if ($grade_item->is_normal_item()) {
                 // following items are set up from modules and should not be overrided by user
                 $mform->hardFreeze('itemname,idnumber,gradetype,grademax,grademin,scaleid');
                 //$mform->removeElement('calculation');
             }
         }
         //remove the aggregation coef element if not needed
         if ($grade_item->is_course_item()) {
             $mform->removeElement('aggregationcoef');
         } else {
             if ($grade_item->is_category_item()) {
                 $category = $grade_item->get_item_category();
                 $parent_category = $category->get_parent_category();
                 if (!$parent_category->is_aggregationcoef_used()) {
                     $mform->removeElement('aggregationcoef');
                 }
             } else {
                 $parent_category = $grade_item->get_parent_category();
                 if (!$parent_category->is_aggregationcoef_used()) {
                     $mform->removeElement('aggregationcoef');
                 }
             }
         }
     } else {
         // all new items are manual, children of course category
         $mform->removeElement('plusfactor');
         $mform->removeElement('multfactor');
         $course_category = grade_category::fetch_course_category($COURSE->id);
         if (!$course_category->is_aggregationcoef_used()) {
             $mform->removeElement('aggregationcoef');
         }
     }
     // setup defaults and extra locking based on it
     $course_item = grade_item::fetch_course_item($COURSE->id);
     $default_gradedisplaytype = $course_item->get_displaytype();
     $default_gradedecimals = $course_item->get_decimals();
     $option_value = 'error';
     foreach ($this->displayoptions as $key => $option) {
         if ($key == $default_gradedisplaytype) {
             $option_value = $option;
             break;
         }
     }
     $displaytypeEl =& $mform->getElement('display');
     $displaytypeEl->setLabel(get_string('gradedisplaytype', 'grades') . ' (' . get_string('default', 'grades') . ': ' . $option_value . ')');
     $decimalsEl =& $mform->getElement('decimals');
     $decimalsEl->setLabel(get_string('decimalpoints', 'grades') . ' (' . get_string('default', 'grades') . ': ' . $default_gradedecimals . ')');
     // Disable decimals if displaytype is DEFAULT and course or site displaytype is LETTER
     if ($default_gradedisplaytype == GRADE_DISPLAY_TYPE_LETTER) {
         $mform->disabledIf('decimals', 'display', "eq", GRADE_DISPLAY_TYPE_DEFAULT);
     }
 }
Exemple #14
0
 /**
  * Returns the grade items associated with the courses.
  *
  * @param array $courseids Array of course ids.
  * @return array Array of grade_items for each course level grade item.
  */
 public static function fetch_course_items(array $courseids)
 {
     global $DB;
     $courseitems = array();
     if (!empty($courseids)) {
         list($courseidssql, $courseidsparams) = $DB->get_in_or_equal($courseids);
         $select = 'courseid ' . $courseidssql . ' AND itemtype = ?';
         $params = array_merge($courseidsparams, array('course'));
         $rs = $DB->get_recordset_select('grade_items', $select, $params);
         $courseitems = array();
         foreach ($rs as $data) {
             $instance = new \grade_item();
             \grade_object::set_properties($instance, $data);
             $courseitems[$instance->id] = $instance;
         }
         $rs->close();
     }
     // Determine if any courses were missing.
     $receivedids = array();
     foreach ($courseitems as $item) {
         $receivedids[] = $item->courseid;
     }
     $missingids = array_diff($courseids, $receivedids);
     // Create grade items for any courses that didn't have one.
     if (!empty($missingids)) {
         foreach ($missingids as $courseid) {
             // First get category - it creates the associated grade item.
             $coursecategory = \grade_category::fetch_course_category($courseid);
             $gradeitem = $coursecategory->get_grade_item();
             $courseitems[$gradeitem->id] = $gradeitem;
         }
     }
     return $courseitems;
 }
Exemple #15
0
 /**
  * Returns grade item associated with the course
  * @param int $courseid
  * @return course item object
  */
 function fetch_course_item($courseid)
 {
     if ($course_item = grade_item::fetch(array('courseid' => $courseid, 'itemtype' => 'course'))) {
         return $course_item;
     }
     // first get category - it creates the associated grade item
     $course_category = grade_category::fetch_course_category($courseid);
     return $course_category->get_grade_item();
 }
 /**
  * Tests grade_report_user::inject_rowspans()
  *
  * inject_rowspans() returns the count of the number of elements, sets maxdepth on the
  *  report object and sets the rowspan property on any element that has children.
  */
 public function test_inject_rowspans()
 {
     global $CFG, $USER, $DB;
     parent::setUp();
     $this->resetAfterTest(true);
     $CFG->enableavailability = 1;
     $CFG->enablecompletion = 1;
     // Create a course.
     $course = $this->getDataGenerator()->create_course();
     $coursecategory = grade_category::fetch_course_category($course->id);
     $coursecontext = context_course::instance($course->id);
     // Create and enrol test users.
     $student = $this->getDataGenerator()->create_user(array('username' => 'Student Sam'));
     $role = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
     $this->getDataGenerator()->enrol_user($student->id, $course->id, $role->id);
     $teacher = $this->getDataGenerator()->create_user(array('username' => 'Teacher T'));
     $role = $DB->get_record('role', array('shortname' => 'editingteacher'), '*', MUST_EXIST);
     $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $role->id);
     // An array so we can test with both users in a loop.
     $users = array($student, $teacher);
     // Make the student the current user.
     $this->setUser($student);
     // Test an empty course.
     $report = $this->create_report($course, $student, $coursecontext);
     // a lead column that spans all children + course grade item = 2
     $this->assertEquals(2, $report->inject_rowspans($report->gtree->top_element));
     $this->assertEquals(2, $report->gtree->top_element['rowspan']);
     $this->assertEquals(2, $report->maxdepth);
     // Only elements with children should have rowspan set.
     if (array_key_exists('rowspan', $report->gtree->top_element['children'][1])) {
         $this->fail('Elements without children should not have rowspan set');
     }
     // Add 2 activities.
     $data1 = $this->getDataGenerator()->create_module('data', array('assessed' => 1, 'scale' => 100, 'course' => $course->id));
     $forum1 = $this->getDataGenerator()->create_module('forum', array('assessed' => 1, 'scale' => 100, 'course' => $course->id));
     $forum1cm = get_coursemodule_from_id('forum', $forum1->cmid);
     // Switch the stdClass instance for a grade item instance so grade_item::set_parent() is available.
     $forum1 = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'forum', 'iteminstance' => $forum1->id, 'courseid' => $course->id));
     $report = $this->create_report($course, $student, $coursecontext);
     // Lead column + course + (2 x activity) = 4
     $this->assertEquals(4, $report->inject_rowspans($report->gtree->top_element));
     $this->assertEquals(4, $report->gtree->top_element['rowspan']);
     // Lead column + 1 level (course + 2 activities) = 2
     $this->assertEquals(2, $report->maxdepth);
     // Only elements with children should have rowspan set.
     if (array_key_exists('rowspan', $report->gtree->top_element['children'][1])) {
         $this->fail('Elements without children should not have rowspan set');
     }
     // Hide the forum activity.
     set_coursemodule_visible($forum1cm->id, 0);
     foreach ($users as $user) {
         $this->setUser($user);
         $message = 'Testing with ' . $user->username;
         accesslib_clear_all_caches_for_unit_testing();
         $report = $this->create_report($course, $user, $coursecontext);
         // Lead column + course + (2 x activity) = 4 (element count isn't affected by hiding)
         $this->assertEquals(4, $report->inject_rowspans($report->gtree->top_element), $message);
         $this->assertEquals(4, $report->gtree->top_element['rowspan'], $message);
         // Lead column -> 1 level containing the course + 2 activities = 2
         $this->assertEquals(2, $report->maxdepth, $message);
     }
     // Unhide the forum activity.
     set_coursemodule_visible($forum1cm->id, 1);
     // Create a category and put the forum in it.
     $params = new stdClass();
     $params->courseid = $course->id;
     $params->fullname = 'unittestcategory';
     $params->parent = $coursecategory->id;
     $gradecategory = new grade_category($params, false);
     $gradecategory->insert();
     $forum1->set_parent($gradecategory->id);
     $report = $this->create_report($course, $student, $coursecontext);
     // Lead column + course + (category + category grade item) + (2 x activity) = 6
     $this->assertEquals(6, $report->inject_rowspans($report->gtree->top_element));
     $this->assertEquals(6, $report->gtree->top_element['rowspan']);
     // Lead column -> the category -> the forum activity = 3
     $this->assertEquals(3, $report->maxdepth);
     // Check rowspan on the category. The category itself + category grade item + forum = 3
     $this->assertEquals(3, $report->gtree->top_element['children'][4]['rowspan']);
     // check the forum doesn't have rowspan set
     if (array_key_exists('rowspan', $report->gtree->top_element['children'][4]['children'][3])) {
         $this->fail('The forum has no children so should not have rowspan set');
     }
     // Conditional activity tests.
     $DB->insert_record('course_modules_availability', (object) array('coursemoduleid' => $forum1cm->id, 'gradeitemid' => 37, 'grademin' => 5.5));
     $cm = (object) array('id' => $forum1cm->id);
     $test = new condition_info($cm, CONDITION_MISSING_EVERYTHING);
     $fullcm = $test->get_full_course_module();
     foreach ($users as $user) {
         $this->setUser($user);
         $message = 'Testing with ' . $user->username;
         accesslib_clear_all_caches_for_unit_testing();
         $report = $this->create_report($course, $user, $coursecontext);
         // Lead column + course + (category + category grade item) + (2 x activity) = 6
         $this->assertEquals(6, $report->inject_rowspans($report->gtree->top_element), $message);
         $this->assertEquals(6, $report->gtree->top_element['rowspan'], $message);
         // Lead column -> the category -> the forum activity = 3
         $this->assertEquals(3, $report->maxdepth, $message);
     }
 }
Exemple #17
0
/**
 * This function creates all the gradebook data from xml
 */
function restore_create_gradebook($restore, $xml_file)
{
    global $CFG;
    $status = true;
    //Check it exists
    if (!file_exists($xml_file)) {
        return false;
    }
    // Get info from xml
    // info will contain the number of record to process
    $info = restore_read_xml_gradebook($restore, $xml_file);
    // If we have info, then process
    if (empty($info)) {
        return $status;
    }
    if (empty($CFG->disablegradehistory) and isset($info->gradebook_histories) and $info->gradebook_histories == "true") {
        $restore_histories = true;
    } else {
        $restore_histories = false;
    }
    // make sure top course category exists
    $course_category = grade_category::fetch_course_category($restore->course_id);
    $course_category->load_grade_item();
    // we need to know if all grade items that were backed up are being restored
    // if that is not the case, we do not restore grade categories nor gradeitems of category type or course type
    // i.e. the aggregated grades of that category
    $restoreall = true;
    // set to false if any grade_item is not selected/restored or already exist
    $importing = !empty($SESSION->restore->importing);
    if ($importing) {
        $restoreall = false;
    } else {
        $prev_grade_items = grade_item::fetch_all(array('courseid' => $restore->course_id));
        $prev_grade_cats = grade_category::fetch_all(array('courseid' => $restore->course_id));
        // if any categories already present, skip restore of categories from backup - course item or category already exist
        if (count($prev_grade_items) > 1 or count($prev_grade_cats) > 1) {
            $restoreall = false;
        }
        unset($prev_grade_items);
        unset($prev_grade_cats);
        if ($restoreall) {
            if ($recs = get_records_select("backup_ids", "table_name = 'grade_items' AND backup_code = {$restore->backup_unique_code}", "", "old_id")) {
                foreach ($recs as $rec) {
                    if ($data = backup_getid($restore->backup_unique_code, 'grade_items', $rec->old_id)) {
                        $info = $data->info;
                        // do not restore if this grade_item is a mod, and
                        $itemtype = backup_todb($info['GRADE_ITEM']['#']['ITEMTYPE']['0']['#']);
                        if ($itemtype == 'mod') {
                            $olditeminstance = backup_todb($info['GRADE_ITEM']['#']['ITEMINSTANCE']['0']['#']);
                            $itemmodule = backup_todb($info['GRADE_ITEM']['#']['ITEMMODULE']['0']['#']);
                            if (empty($restore->mods[$itemmodule]->granular)) {
                                continue;
                            } else {
                                if (!empty($restore->mods[$itemmodule]->instances[$olditeminstance]->restore)) {
                                    continue;
                                }
                            }
                            // at least one activity should not be restored - do not restore categories and manual items at all
                            $restoreall = false;
                            break;
                        }
                    }
                }
            }
        }
    }
    // Start ul
    if (!defined('RESTORE_SILENTLY')) {
        echo '<ul>';
    }
    // array of restored categories - speedup ;-)
    $cached_categories = array();
    $outcomes = array();
    /// Process letters
    $context = get_context_instance(CONTEXT_COURSE, $restore->course_id);
    // respect current grade letters if defined
    if ($status and $restoreall and !record_exists('grade_letters', 'contextid', $context->id)) {
        if (!defined('RESTORE_SILENTLY')) {
            echo '<li>' . get_string('gradeletters', 'grades') . '</li>';
        }
        // Fetch recordset_size records in each iteration
        $recs = get_records_select("backup_ids", "table_name = 'grade_letters' AND backup_code = {$restore->backup_unique_code}", "", "old_id");
        if ($recs) {
            foreach ($recs as $rec) {
                // Get the full record from backup_ids
                $data = backup_getid($restore->backup_unique_code, 'grade_letters', $rec->old_id);
                if ($data) {
                    $info = $data->info;
                    $dbrec = new object();
                    $dbrec->contextid = $context->id;
                    $dbrec->lowerboundary = backup_todb($info['GRADE_LETTER']['#']['LOWERBOUNDARY']['0']['#']);
                    $dbrec->letter = backup_todb($info['GRADE_LETTER']['#']['LETTER']['0']['#']);
                    insert_record('grade_letters', $dbrec);
                }
            }
        }
    }
    /// Preprocess outcomes - do not store them yet!
    if ($status and !$importing and $restoreall) {
        if (!defined('RESTORE_SILENTLY')) {
            echo '<li>' . get_string('gradeoutcomes', 'grades') . '</li>';
        }
        $recs = get_records_select("backup_ids", "table_name = 'grade_outcomes' AND backup_code = '{$restore->backup_unique_code}'", "", "old_id");
        if ($recs) {
            foreach ($recs as $rec) {
                //Get the full record from backup_ids
                $data = backup_getid($restore->backup_unique_code, 'grade_outcomes', $rec->old_id);
                if ($data) {
                    $info = $data->info;
                    //first find out if outcome already exists
                    $shortname = backup_todb($info['GRADE_OUTCOME']['#']['SHORTNAME']['0']['#']);
                    if ($candidates = get_records_sql("SELECT *\n                                                             FROM {$CFG->prefix}grade_outcomes\n                                                            WHERE (courseid IS NULL OR courseid = {$restore->course_id})\n                                                                  AND shortname = '{$shortname}'\n                                                         ORDER BY courseid ASC, id ASC")) {
                        $grade_outcome = reset($candidates);
                        $outcomes[$rec->old_id] = $grade_outcome;
                        continue;
                    }
                    $dbrec = new object();
                    if (has_capability('moodle/grade:manageoutcomes', get_context_instance(CONTEXT_SYSTEM))) {
                        $oldoutcome = backup_todb($info['GRADE_OUTCOME']['#']['COURSEID']['0']['#']);
                        if (empty($oldoutcome)) {
                            //site wide
                            $dbrec->courseid = null;
                        } else {
                            //course only
                            $dbrec->courseid = $restore->course_id;
                        }
                    } else {
                        // no permission to add site outcomes
                        $dbrec->courseid = $restore->course_id;
                    }
                    //Get the fields
                    $dbrec->shortname = backup_todb($info['GRADE_OUTCOME']['#']['SHORTNAME']['0']['#'], false);
                    $dbrec->fullname = backup_todb($info['GRADE_OUTCOME']['#']['FULLNAME']['0']['#'], false);
                    $dbrec->scaleid = backup_todb($info['GRADE_OUTCOME']['#']['SCALEID']['0']['#'], false);
                    $dbrec->description = backup_todb($info['GRADE_OUTCOME']['#']['DESCRIPTION']['0']['#'], false);
                    $dbrec->timecreated = backup_todb($info['GRADE_OUTCOME']['#']['TIMECREATED']['0']['#'], false);
                    $dbrec->timemodified = backup_todb($info['GRADE_OUTCOME']['#']['TIMEMODIFIED']['0']['#'], false);
                    $dbrec->usermodified = backup_todb($info['GRADE_OUTCOME']['#']['USERMODIFIED']['0']['#'], false);
                    //Need to recode the scaleid
                    if ($scale = backup_getid($restore->backup_unique_code, 'scale', $dbrec->scaleid)) {
                        $dbrec->scaleid = $scale->new_id;
                    }
                    //Need to recode the usermodified
                    if ($modifier = backup_getid($restore->backup_unique_code, 'user', $dbrec->usermodified)) {
                        $dbrec->usermodified = $modifier->new_id;
                    }
                    $grade_outcome = new grade_outcome($dbrec, false);
                    $outcomes[$rec->old_id] = $grade_outcome;
                }
            }
        }
    }
    /// Process grade items and grades
    if ($status) {
        if (!defined('RESTORE_SILENTLY')) {
            echo '<li>' . get_string('gradeitems', 'grades') . '</li>';
        }
        $counter = 0;
        //Fetch recordset_size records in each iteration
        $recs = get_records_select("backup_ids", "table_name = 'grade_items' AND backup_code = '{$restore->backup_unique_code}'", "id", "old_id");
        if ($recs) {
            foreach ($recs as $rec) {
                //Get the full record from backup_ids
                $data = backup_getid($restore->backup_unique_code, 'grade_items', $rec->old_id);
                if ($data) {
                    $info = $data->info;
                    // first find out if category or normal item
                    $itemtype = backup_todb($info['GRADE_ITEM']['#']['ITEMTYPE']['0']['#'], false);
                    if ($itemtype == 'course' or $itemtype == 'category') {
                        if (!$restoreall or $importing) {
                            continue;
                        }
                        $oldcat = backup_todb($info['GRADE_ITEM']['#']['ITEMINSTANCE']['0']['#'], false);
                        if (!($cdata = backup_getid($restore->backup_unique_code, 'grade_categories', $oldcat))) {
                            continue;
                        }
                        $cinfo = $cdata->info;
                        unset($cdata);
                        if ($itemtype == 'course') {
                            $course_category->fullname = backup_todb($cinfo['GRADE_CATEGORY']['#']['FULLNAME']['0']['#'], false);
                            $course_category->aggregation = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATION']['0']['#'], false);
                            $course_category->keephigh = backup_todb($cinfo['GRADE_CATEGORY']['#']['KEEPHIGH']['0']['#'], false);
                            $course_category->droplow = backup_todb($cinfo['GRADE_CATEGORY']['#']['DROPLOW']['0']['#'], false);
                            $course_category->aggregateonlygraded = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATEONLYGRADED']['0']['#'], false);
                            $course_category->aggregateoutcomes = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATEOUTCOMES']['0']['#'], false);
                            $course_category->aggregatesubcats = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATESUBCATS']['0']['#'], false);
                            $course_category->timecreated = backup_todb($cinfo['GRADE_CATEGORY']['#']['TIMECREATED']['0']['#'], false);
                            $course_category->update('restore');
                            $status = backup_putid($restore->backup_unique_code, 'grade_categories', $oldcat, $course_category->id) && $status;
                            $cached_categories[$oldcat] = $course_category;
                            $grade_item = $course_category->get_grade_item();
                        } else {
                            $oldparent = backup_todb($cinfo['GRADE_CATEGORY']['#']['PARENT']['0']['#'], false);
                            if (empty($cached_categories[$oldparent])) {
                                debugging('parent not found ' . $oldparent);
                                continue;
                                // parent not found, sorry
                            }
                            $grade_category = new grade_category();
                            $grade_category->courseid = $restore->course_id;
                            $grade_category->parent = $cached_categories[$oldparent]->id;
                            $grade_category->fullname = backup_todb($cinfo['GRADE_CATEGORY']['#']['FULLNAME']['0']['#'], false);
                            $grade_category->aggregation = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATION']['0']['#'], false);
                            $grade_category->keephigh = backup_todb($cinfo['GRADE_CATEGORY']['#']['KEEPHIGH']['0']['#'], false);
                            $grade_category->droplow = backup_todb($cinfo['GRADE_CATEGORY']['#']['DROPLOW']['0']['#'], false);
                            $grade_category->aggregateonlygraded = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATEONLYGRADED']['0']['#'], false);
                            $grade_category->aggregateoutcomes = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATEOUTCOMES']['0']['#'], false);
                            $grade_category->aggregatesubcats = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATESUBCATS']['0']['#'], false);
                            $grade_category->timecreated = backup_todb($cinfo['GRADE_CATEGORY']['#']['TIMECREATED']['0']['#'], false);
                            $grade_category->insert('restore');
                            $status = backup_putid($restore->backup_unique_code, 'grade_categories', $oldcat, $grade_category->id) && $status;
                            $cached_categories[$oldcat] = $grade_category;
                            $grade_item = $grade_category->get_grade_item();
                            // creates grade_item too
                        }
                        unset($cinfo);
                        $idnumber = backup_todb($info['GRADE_ITEM']['#']['IDNUMBER']['0']['#'], false);
                        if (grade_verify_idnumber($idnumber, $restore->course_id)) {
                            $grade_item->idnumber = $idnumber;
                        }
                        $grade_item->itemname = backup_todb($info['GRADE_ITEM']['#']['ITEMNAME']['0']['#'], false);
                        $grade_item->iteminfo = backup_todb($info['GRADE_ITEM']['#']['ITEMINFO']['0']['#'], false);
                        $grade_item->gradetype = backup_todb($info['GRADE_ITEM']['#']['GRADETYPE']['0']['#'], false);
                        $grade_item->calculation = backup_todb($info['GRADE_ITEM']['#']['CALCULATION']['0']['#'], false);
                        $grade_item->grademax = backup_todb($info['GRADE_ITEM']['#']['GRADEMAX']['0']['#'], false);
                        $grade_item->grademin = backup_todb($info['GRADE_ITEM']['#']['GRADEMIN']['0']['#'], false);
                        $grade_item->gradepass = backup_todb($info['GRADE_ITEM']['#']['GRADEPASS']['0']['#'], false);
                        $grade_item->multfactor = backup_todb($info['GRADE_ITEM']['#']['MULTFACTOR']['0']['#'], false);
                        $grade_item->plusfactor = backup_todb($info['GRADE_ITEM']['#']['PLUSFACTOR']['0']['#'], false);
                        $grade_item->aggregationcoef = backup_todb($info['GRADE_ITEM']['#']['AGGREGATIONCOEF']['0']['#'], false);
                        $grade_item->display = backup_todb($info['GRADE_ITEM']['#']['DISPLAY']['0']['#'], false);
                        $grade_item->decimals = backup_todb($info['GRADE_ITEM']['#']['DECIMALS']['0']['#'], false);
                        $grade_item->hidden = backup_todb($info['GRADE_ITEM']['#']['HIDDEN']['0']['#'], false);
                        $grade_item->locked = backup_todb($info['GRADE_ITEM']['#']['LOCKED']['0']['#'], false);
                        $grade_item->locktime = backup_todb($info['GRADE_ITEM']['#']['LOCKTIME']['0']['#'], false);
                        $grade_item->timecreated = backup_todb($info['GRADE_ITEM']['#']['TIMECREATED']['0']['#'], false);
                        if (backup_todb($info['GRADE_ITEM']['#']['SCALEID']['0']['#'], false)) {
                            $scale = backup_getid($restore->backup_unique_code, "scale", backup_todb($info['GRADE_ITEM']['#']['SCALEID']['0']['#'], false));
                            $grade_item->scaleid = $scale->new_id;
                        }
                        if (backup_todb($info['GRADE_ITEM']['#']['OUTCOMEID']['0']['#'], false)) {
                            $outcome = backup_getid($restore->backup_unique_code, "grade_outcomes", backup_todb($info['GRADE_ITEM']['#']['OUTCOMEID']['0']['#'], false));
                            $grade_item->outcomeid = $outcome->new_id;
                        }
                        $grade_item->update('restore');
                        $status = backup_putid($restore->backup_unique_code, "grade_items", $rec->old_id, $grade_item->id) && $status;
                    } else {
                        if ($itemtype != 'mod' and (!$restoreall or $importing)) {
                            // not extra gradebook stuff if restoring individual activities or something already there
                            continue;
                        }
                        $dbrec = new object();
                        $dbrec->courseid = $restore->course_id;
                        $dbrec->itemtype = backup_todb($info['GRADE_ITEM']['#']['ITEMTYPE']['0']['#'], false);
                        $dbrec->itemmodule = backup_todb($info['GRADE_ITEM']['#']['ITEMMODULE']['0']['#'], false);
                        if ($itemtype == 'mod') {
                            // iteminstance should point to new mod
                            $olditeminstance = backup_todb($info['GRADE_ITEM']['#']['ITEMINSTANCE']['0']['#'], false);
                            $mod = backup_getid($restore->backup_unique_code, $dbrec->itemmodule, $olditeminstance);
                            $dbrec->iteminstance = $mod->new_id;
                            if (!($cm = get_coursemodule_from_instance($dbrec->itemmodule, $mod->new_id))) {
                                // item not restored - no item
                                continue;
                            }
                            // keep in sync with activity idnumber
                            $dbrec->idnumber = $cm->idnumber;
                        } else {
                            $idnumber = backup_todb($info['GRADE_ITEM']['#']['IDNUMBER']['0']['#'], false);
                            if (grade_verify_idnumber($idnumber, $restore->course_id)) {
                                //make sure the new idnumber is unique
                                $dbrec->idnumber = $idnumber;
                            }
                        }
                        $dbrec->itemname = backup_todb($info['GRADE_ITEM']['#']['ITEMNAME']['0']['#'], false);
                        $dbrec->itemtype = backup_todb($info['GRADE_ITEM']['#']['ITEMTYPE']['0']['#'], false);
                        $dbrec->itemmodule = backup_todb($info['GRADE_ITEM']['#']['ITEMMODULE']['0']['#'], false);
                        $dbrec->itemnumber = backup_todb($info['GRADE_ITEM']['#']['ITEMNUMBER']['0']['#'], false);
                        $dbrec->iteminfo = backup_todb($info['GRADE_ITEM']['#']['ITEMINFO']['0']['#'], false);
                        $dbrec->gradetype = backup_todb($info['GRADE_ITEM']['#']['GRADETYPE']['0']['#'], false);
                        $dbrec->calculation = backup_todb($info['GRADE_ITEM']['#']['CALCULATION']['0']['#'], false);
                        $dbrec->grademax = backup_todb($info['GRADE_ITEM']['#']['GRADEMAX']['0']['#'], false);
                        $dbrec->grademin = backup_todb($info['GRADE_ITEM']['#']['GRADEMIN']['0']['#'], false);
                        $dbrec->gradepass = backup_todb($info['GRADE_ITEM']['#']['GRADEPASS']['0']['#'], false);
                        $dbrec->multfactor = backup_todb($info['GRADE_ITEM']['#']['MULTFACTOR']['0']['#'], false);
                        $dbrec->plusfactor = backup_todb($info['GRADE_ITEM']['#']['PLUSFACTOR']['0']['#'], false);
                        $dbrec->aggregationcoef = backup_todb($info['GRADE_ITEM']['#']['AGGREGATIONCOEF']['0']['#'], false);
                        $dbrec->display = backup_todb($info['GRADE_ITEM']['#']['DISPLAY']['0']['#'], false);
                        $dbrec->decimals = backup_todb($info['GRADE_ITEM']['#']['DECIMALS']['0']['#'], false);
                        $dbrec->hidden = backup_todb($info['GRADE_ITEM']['#']['HIDDEN']['0']['#'], false);
                        $dbrec->locked = backup_todb($info['GRADE_ITEM']['#']['LOCKED']['0']['#'], false);
                        $dbrec->locktime = backup_todb($info['GRADE_ITEM']['#']['LOCKTIME']['0']['#'], false);
                        $dbrec->timecreated = backup_todb($info['GRADE_ITEM']['#']['TIMECREATED']['0']['#'], false);
                        if (backup_todb($info['GRADE_ITEM']['#']['SCALEID']['0']['#'], false)) {
                            $scale = backup_getid($restore->backup_unique_code, "scale", backup_todb($info['GRADE_ITEM']['#']['SCALEID']['0']['#'], false));
                            $dbrec->scaleid = $scale->new_id;
                        }
                        if (backup_todb($info['GRADE_ITEM']['#']['OUTCOMEID']['0']['#'])) {
                            $oldoutcome = backup_todb($info['GRADE_ITEM']['#']['OUTCOMEID']['0']['#']);
                            if (empty($outcomes[$oldoutcome])) {
                                continue;
                                // error!
                            }
                            if (empty($outcomes[$oldoutcome]->id)) {
                                $outcomes[$oldoutcome]->insert('restore');
                                $outcomes[$oldoutcome]->use_in($restore->course_id);
                                backup_putid($restore->backup_unique_code, "grade_outcomes", $oldoutcome, $outcomes[$oldoutcome]->id);
                            }
                            $dbrec->outcomeid = $outcomes[$oldoutcome]->id;
                        }
                        $grade_item = new grade_item($dbrec, false);
                        $grade_item->insert('restore');
                        if ($restoreall) {
                            // set original parent if restored
                            $oldcat = $info['GRADE_ITEM']['#']['CATEGORYID']['0']['#'];
                            if (!empty($cached_categories[$oldcat])) {
                                $grade_item->set_parent($cached_categories[$oldcat]->id);
                            }
                        }
                        $status = backup_putid($restore->backup_unique_code, "grade_items", $rec->old_id, $grade_item->id) && $status;
                    }
                    // no need to restore grades if user data is not selected or importing activities
                    if ($importing or $grade_item->itemtype == 'mod' and !restore_userdata_selected($restore, $grade_item->itemmodule, $olditeminstance)) {
                        // module instance not selected when restored using granular
                        // skip this item
                        continue;
                    }
                    /// now, restore grade_grades
                    if (!empty($info['GRADE_ITEM']['#']['GRADE_GRADES']['0']['#']['GRADE'])) {
                        //Iterate over items
                        foreach ($info['GRADE_ITEM']['#']['GRADE_GRADES']['0']['#']['GRADE'] as $g_info) {
                            $grade = new grade_grade();
                            $grade->itemid = $grade_item->id;
                            $olduser = backup_todb($g_info['#']['USERID']['0']['#'], false);
                            $user = backup_getid($restore->backup_unique_code, "user", $olduser);
                            $grade->userid = $user->new_id;
                            $grade->rawgrade = backup_todb($g_info['#']['RAWGRADE']['0']['#'], false);
                            $grade->rawgrademax = backup_todb($g_info['#']['RAWGRADEMAX']['0']['#'], false);
                            $grade->rawgrademin = backup_todb($g_info['#']['RAWGRADEMIN']['0']['#'], false);
                            // need to find scaleid
                            if (backup_todb($g_info['#']['RAWSCALEID']['0']['#'])) {
                                $scale = backup_getid($restore->backup_unique_code, "scale", backup_todb($g_info['#']['RAWSCALEID']['0']['#'], false));
                                $grade->rawscaleid = $scale->new_id;
                            }
                            if (backup_todb($g_info['#']['USERMODIFIED']['0']['#'])) {
                                if ($modifier = backup_getid($restore->backup_unique_code, "user", backup_todb($g_info['#']['USERMODIFIED']['0']['#'], false))) {
                                    $grade->usermodified = $modifier->new_id;
                                }
                            }
                            $grade->finalgrade = backup_todb($g_info['#']['FINALGRADE']['0']['#'], false);
                            $grade->hidden = backup_todb($g_info['#']['HIDDEN']['0']['#'], false);
                            $grade->locked = backup_todb($g_info['#']['LOCKED']['0']['#'], false);
                            $grade->locktime = backup_todb($g_info['#']['LOCKTIME']['0']['#'], false);
                            $grade->exported = backup_todb($g_info['#']['EXPORTED']['0']['#'], false);
                            $grade->overridden = backup_todb($g_info['#']['OVERRIDDEN']['0']['#'], false);
                            $grade->excluded = backup_todb($g_info['#']['EXCLUDED']['0']['#'], false);
                            $grade->feedback = backup_todb($g_info['#']['FEEDBACK']['0']['#'], false);
                            $grade->feedbackformat = backup_todb($g_info['#']['FEEDBACKFORMAT']['0']['#'], false);
                            $grade->information = backup_todb($g_info['#']['INFORMATION']['0']['#'], false);
                            $grade->informationformat = backup_todb($g_info['#']['INFORMATIONFORMAT']['0']['#'], false);
                            $grade->timecreated = backup_todb($g_info['#']['TIMECREATED']['0']['#'], false);
                            $grade->timemodified = backup_todb($g_info['#']['TIMEMODIFIED']['0']['#'], false);
                            $grade->insert('restore');
                            backup_putid($restore->backup_unique_code, "grade_grades", backup_todb($g_info['#']['ID']['0']['#']), $grade->id);
                            $counter++;
                            if ($counter % 20 == 0) {
                                if (!defined('RESTORE_SILENTLY')) {
                                    echo ".";
                                    if ($counter % 400 == 0) {
                                        echo "<br />";
                                    }
                                }
                                backup_flush(300);
                            }
                        }
                    }
                }
            }
        }
    }
    /// add outcomes that are not used when doing full restore
    if ($status and $restoreall) {
        foreach ($outcomes as $oldoutcome => $grade_outcome) {
            if (empty($grade_outcome->id)) {
                $grade_outcome->insert('restore');
                $grade_outcome->use_in($restore->course_id);
                backup_putid($restore->backup_unique_code, "grade_outcomes", $oldoutcome, $grade_outcome->id);
            }
        }
    }
    if ($status and !$importing and $restore_histories) {
        /// following code is very inefficient
        $gchcount = count_records('backup_ids', 'backup_code', $restore->backup_unique_code, 'table_name', 'grade_categories_history');
        $gghcount = count_records('backup_ids', 'backup_code', $restore->backup_unique_code, 'table_name', 'grade_grades_history');
        $gihcount = count_records('backup_ids', 'backup_code', $restore->backup_unique_code, 'table_name', 'grade_items_history');
        $gohcount = count_records('backup_ids', 'backup_code', $restore->backup_unique_code, 'table_name', 'grade_outcomes_history');
        // Number of records to get in every chunk
        $recordset_size = 2;
        // process histories
        if ($gchcount && $status) {
            if (!defined('RESTORE_SILENTLY')) {
                echo '<li>' . get_string('gradecategoryhistory', 'grades') . '</li>';
            }
            $counter = 0;
            while ($counter < $gchcount) {
                //Fetch recordset_size records in each iteration
                $recs = get_records_select("backup_ids", "table_name = 'grade_categories_history' AND 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, 'grade_categories_history', $rec->old_id);
                        if ($data) {
                            //Now get completed xmlized object
                            $info = $data->info;
                            //traverse_xmlize($info);                            //Debug
                            //print_object ($GLOBALS['traverse_array']);         //Debug
                            //$GLOBALS['traverse_array']="";                     //Debug
                            $oldobj = backup_getid($restore->backup_unique_code, "grade_categories", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['OLDID']['0']['#']));
                            if (empty($oldobj->new_id)) {
                                // if the old object is not being restored, can't restoring its history
                                $counter++;
                                continue;
                            }
                            $dbrec->oldid = $oldobj->new_id;
                            $dbrec->action = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['ACTION']['0']['#']);
                            $dbrec->source = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['SOURCE']['0']['#']);
                            $dbrec->timemodified = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
                            // loggeduser might not be restored, e.g. admin
                            if ($oldobj = backup_getid($restore->backup_unique_code, "user", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
                                $dbrec->loggeduser = $oldobj->new_id;
                            }
                            // this item might not have a parent at all, do not skip it if no parent is specified
                            if (backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PARENT']['0']['#'])) {
                                $oldobj = backup_getid($restore->backup_unique_code, "grade_categories", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PARENT']['0']['#']));
                                if (empty($oldobj->new_id)) {
                                    // if the parent category not restored
                                    $counter++;
                                    continue;
                                }
                            }
                            $dbrec->parent = $oldobj->new_id;
                            $dbrec->depth = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['DEPTH']['0']['#']);
                            // path needs to be rebuilt
                            if ($path = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PATH']['0']['#'])) {
                                // to preserve the path and make it work, we need to replace the categories one by one
                                // we first get the list of categories in current path
                                if ($paths = explode("/", $path)) {
                                    $newpath = '';
                                    foreach ($paths as $catid) {
                                        if ($catid) {
                                            // find the new corresponding path
                                            $oldpath = backup_getid($restore->backup_unique_code, "grade_categories", $catid);
                                            $newpath .= "/{$oldpath->new_id}";
                                        }
                                    }
                                    $dbrec->path = $newpath;
                                }
                            }
                            $dbrec->fullname = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['FULLNAME']['0']['#']);
                            $dbrec->aggregation = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['AGGRETGATION']['0']['#']);
                            $dbrec->keephigh = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['KEEPHIGH']['0']['#']);
                            $dbrec->droplow = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['DROPLOW']['0']['#']);
                            $dbrec->aggregateonlygraded = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['AGGREGATEONLYGRADED']['0']['#']);
                            $dbrec->aggregateoutcomes = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['AGGREGATEOUTCOMES']['0']['#']);
                            $dbrec->aggregatesubcats = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['AGGREGATESUBCATS']['0']['#']);
                            $dbrec->courseid = $restore->course_id;
                            insert_record('grade_categories_history', $dbrec);
                            unset($dbrec);
                        }
                        //Increment counters
                        $counter++;
                        //Do some output
                        if ($counter % 1 == 0) {
                            if (!defined('RESTORE_SILENTLY')) {
                                echo ".";
                                if ($counter % 20 == 0) {
                                    echo "<br />";
                                }
                            }
                            backup_flush(300);
                        }
                    }
                }
            }
        }
        // process histories
        if ($gghcount && $status) {
            if (!defined('RESTORE_SILENTLY')) {
                echo '<li>' . get_string('gradegradeshistory', 'grades') . '</li>';
            }
            $counter = 0;
            while ($counter < $gghcount) {
                //Fetch recordset_size records in each iteration
                $recs = get_records_select("backup_ids", "table_name = 'grade_grades_history' AND 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, 'grade_grades_history', $rec->old_id);
                        if ($data) {
                            //Now get completed xmlized object
                            $info = $data->info;
                            //traverse_xmlize($info);                            //Debug
                            //print_object ($GLOBALS['traverse_array']);         //Debug
                            //$GLOBALS['traverse_array']="";                     //Debug
                            $oldobj = backup_getid($restore->backup_unique_code, "grade_grades", backup_todb($info['GRADE_GRADES_HISTORY']['#']['OLDID']['0']['#']));
                            if (empty($oldobj->new_id)) {
                                // if the old object is not being restored, can't restoring its history
                                $counter++;
                                continue;
                            }
                            $dbrec->oldid = $oldobj->new_id;
                            $dbrec->action = backup_todb($info['GRADE_GRADES_HISTORY']['#']['ACTION']['0']['#']);
                            $dbrec->source = backup_todb($info['GRADE_GRADES_HISTORY']['#']['SOURCE']['0']['#']);
                            $dbrec->timemodified = backup_todb($info['GRADE_GRADES_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
                            if ($oldobj = backup_getid($restore->backup_unique_code, "user", backup_todb($info['GRADE_GRADES_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
                                $dbrec->loggeduser = $oldobj->new_id;
                            }
                            $oldobj = backup_getid($restore->backup_unique_code, "grade_items", backup_todb($info['GRADE_GRADES_HISTORY']['#']['ITEMID']['0']['#']));
                            $dbrec->itemid = $oldobj->new_id;
                            if (empty($dbrec->itemid)) {
                                $counter++;
                                continue;
                                // grade item not being restored
                            }
                            $oldobj = backup_getid($restore->backup_unique_code, "user", backup_todb($info['GRADE_GRADES_HISTORY']['#']['USERID']['0']['#']));
                            $dbrec->userid = $oldobj->new_id;
                            $dbrec->rawgrade = backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWGRADE']['0']['#']);
                            $dbrec->rawgrademax = backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWGRADEMAX']['0']['#']);
                            $dbrec->rawgrademin = backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWGRADEMIN']['0']['#']);
                            if ($oldobj = backup_getid($restore->backup_unique_code, "user", backup_todb($info['GRADE_GRADES_HISTORY']['#']['USERMODIFIED']['0']['#']))) {
                                $dbrec->usermodified = $oldobj->new_id;
                            }
                            if (backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWSCALEID']['0']['#'])) {
                                $scale = backup_getid($restore->backup_unique_code, "scale", backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWSCALEID']['0']['#']));
                                $dbrec->rawscaleid = $scale->new_id;
                            }
                            $dbrec->finalgrade = backup_todb($info['GRADE_GRADES_HISTORY']['#']['FINALGRADE']['0']['#']);
                            $dbrec->hidden = backup_todb($info['GRADE_GRADES_HISTORY']['#']['HIDDEN']['0']['#']);
                            $dbrec->locked = backup_todb($info['GRADE_GRADES_HISTORY']['#']['LOCKED']['0']['#']);
                            $dbrec->locktime = backup_todb($info['GRADE_GRADES_HISTORY']['#']['LOCKTIME']['0']['#']);
                            $dbrec->exported = backup_todb($info['GRADE_GRADES_HISTORY']['#']['EXPORTED']['0']['#']);
                            $dbrec->overridden = backup_todb($info['GRADE_GRADES_HISTORY']['#']['OVERRIDDEN']['0']['#']);
                            $dbrec->excluded = backup_todb($info['GRADE_GRADES_HISTORY']['#']['EXCLUDED']['0']['#']);
                            $dbrec->feedback = backup_todb($info['GRADE_TEXT_HISTORY']['#']['FEEDBACK']['0']['#']);
                            $dbrec->feedbackformat = backup_todb($info['GRADE_TEXT_HISTORY']['#']['FEEDBACKFORMAT']['0']['#']);
                            $dbrec->information = backup_todb($info['GRADE_TEXT_HISTORY']['#']['INFORMATION']['0']['#']);
                            $dbrec->informationformat = backup_todb($info['GRADE_TEXT_HISTORY']['#']['INFORMATIONFORMAT']['0']['#']);
                            insert_record('grade_grades_history', $dbrec);
                            unset($dbrec);
                        }
                        //Increment counters
                        $counter++;
                        //Do some output
                        if ($counter % 1 == 0) {
                            if (!defined('RESTORE_SILENTLY')) {
                                echo ".";
                                if ($counter % 20 == 0) {
                                    echo "<br />";
                                }
                            }
                            backup_flush(300);
                        }
                    }
                }
            }
        }
        // process histories
        if ($gihcount && $status) {
            if (!defined('RESTORE_SILENTLY')) {
                echo '<li>' . get_string('gradeitemshistory', 'grades') . '</li>';
            }
            $counter = 0;
            while ($counter < $gihcount) {
                //Fetch recordset_size records in each iteration
                $recs = get_records_select("backup_ids", "table_name = 'grade_items_history' AND 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, 'grade_items_history', $rec->old_id);
                        if ($data) {
                            //Now get completed xmlized object
                            $info = $data->info;
                            //traverse_xmlize($info);                            //Debug
                            //print_object ($GLOBALS['traverse_array']);         //Debug
                            //$GLOBALS['traverse_array']="";                     //Debug
                            $oldobj = backup_getid($restore->backup_unique_code, "grade_items", backup_todb($info['GRADE_ITEM_HISTORY']['#']['OLDID']['0']['#']));
                            if (empty($oldobj->new_id)) {
                                // if the old object is not being restored, can't restoring its history
                                $counter++;
                                continue;
                            }
                            $dbrec->oldid = $oldobj->new_id;
                            $dbrec->action = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ACTION']['0']['#']);
                            $dbrec->source = backup_todb($info['GRADE_ITEM_HISTORY']['#']['SOURCE']['0']['#']);
                            $dbrec->timemodified = backup_todb($info['GRADE_ITEM_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
                            if ($oldobj = backup_getid($restore->backup_unique_code, "user", backup_todb($info['GRADE_ITEM_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
                                $dbrec->loggeduser = $oldobj->new_id;
                            }
                            $dbrec->courseid = $restore->course_id;
                            $oldobj = backup_getid($restore->backup_unique_code, 'grade_categories', backup_todb($info['GRADE_ITEM_HISTORY']['#']['CATEGORYID']['0']['#']));
                            $oldobj->categoryid = $category->new_id;
                            if (empty($oldobj->categoryid)) {
                                $counter++;
                                continue;
                                // category not restored
                            }
                            $dbrec->itemname = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMNAME']['0']['#']);
                            $dbrec->itemtype = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMTYPE']['0']['#']);
                            $dbrec->itemmodule = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMMODULE']['0']['#']);
                            // code from grade_items restore
                            $iteminstance = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMINSTANCE']['0']['#']);
                            // do not restore if this grade_item is a mod, and
                            if ($dbrec->itemtype == 'mod') {
                                if (!restore_userdata_selected($restore, $dbrec->itemmodule, $iteminstance)) {
                                    // module instance not selected when restored using granular
                                    // skip this item
                                    $counter++;
                                    continue;
                                }
                                // iteminstance should point to new mod
                                $mod = backup_getid($restore->backup_unique_code, $dbrec->itemmodule, $iteminstance);
                                $dbrec->iteminstance = $mod->new_id;
                            } else {
                                if ($dbrec->itemtype == 'category') {
                                    // the item instance should point to the new grade category
                                    // only proceed if we are restoring all grade items
                                    if ($restoreall) {
                                        $category = backup_getid($restore->backup_unique_code, 'grade_categories', $iteminstance);
                                        $dbrec->iteminstance = $category->new_id;
                                    } else {
                                        // otherwise we can safely ignore this grade item and subsequent
                                        // grade_raws, grade_finals etc
                                        continue;
                                    }
                                } elseif ($dbrec->itemtype == 'course') {
                                    // We don't restore course type to avoid duplicate course items
                                    if ($restoreall) {
                                        // TODO any special code needed here to restore course item without duplicating it?
                                        // find the course category with depth 1, and course id = current course id
                                        // this would have been already restored
                                        $cat = get_record('grade_categories', 'depth', 1, 'courseid', $restore->course_id);
                                        $dbrec->iteminstance = $cat->id;
                                    } else {
                                        $counter++;
                                        continue;
                                    }
                                }
                            }
                            $dbrec->itemnumber = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMNUMBER']['0']['#']);
                            $dbrec->iteminfo = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMINFO']['0']['#']);
                            $dbrec->idnumber = backup_todb($info['GRADE_ITEM_HISTORY']['#']['IDNUMBER']['0']['#']);
                            $dbrec->calculation = backup_todb($info['GRADE_ITEM_HISTORY']['#']['CALCULATION']['0']['#']);
                            $dbrec->gradetype = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADETYPE']['0']['#']);
                            $dbrec->grademax = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADEMAX']['0']['#']);
                            $dbrec->grademin = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADEMIN']['0']['#']);
                            if ($oldobj = backup_getid($restore->backup_unique_code, "scale", backup_todb($info['GRADE_ITEM_HISTORY']['#']['SCALEID']['0']['#']))) {
                                // scaleid is optional
                                $dbrec->scaleid = $oldobj->new_id;
                            }
                            if ($oldobj = backup_getid($restore->backup_unique_code, "grade_outcomes", backup_todb($info['GRADE_ITEM_HISTORY']['#']['OUTCOMEID']['0']['#']))) {
                                // outcome is optional
                                $dbrec->outcomeid = $oldobj->new_id;
                            }
                            $dbrec->gradepass = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADEPASS']['0']['#']);
                            $dbrec->multfactor = backup_todb($info['GRADE_ITEM_HISTORY']['#']['MULTFACTOR']['0']['#']);
                            $dbrec->plusfactor = backup_todb($info['GRADE_ITEM_HISTORY']['#']['PLUSFACTOR']['0']['#']);
                            $dbrec->aggregationcoef = backup_todb($info['GRADE_ITEM_HISTORY']['#']['AGGREGATIONCOEF']['0']['#']);
                            $dbrec->sortorder = backup_todb($info['GRADE_ITEM_HISTORY']['#']['SORTORDER']['0']['#']);
                            $dbrec->display = backup_todb($info['GRADE_ITEM_HISTORY']['#']['DISPLAY']['0']['#']);
                            $dbrec->decimals = backup_todb($info['GRADE_ITEM_HISTORY']['#']['DECIMALS']['0']['#']);
                            $dbrec->hidden = backup_todb($info['GRADE_ITEM_HISTORY']['#']['HIDDEN']['0']['#']);
                            $dbrec->locked = backup_todb($info['GRADE_ITEM_HISTORY']['#']['LOCKED']['0']['#']);
                            $dbrec->locktime = backup_todb($info['GRADE_ITEM_HISTORY']['#']['LOCKTIME']['0']['#']);
                            $dbrec->needsupdate = backup_todb($info['GRADE_ITEM_HISTORY']['#']['NEEDSUPDATE']['0']['#']);
                            insert_record('grade_items_history', $dbrec);
                            unset($dbrec);
                        }
                        //Increment counters
                        $counter++;
                        //Do some output
                        if ($counter % 1 == 0) {
                            if (!defined('RESTORE_SILENTLY')) {
                                echo ".";
                                if ($counter % 20 == 0) {
                                    echo "<br />";
                                }
                            }
                            backup_flush(300);
                        }
                    }
                }
            }
        }
        // process histories
        if ($gohcount && $status) {
            if (!defined('RESTORE_SILENTLY')) {
                echo '<li>' . get_string('gradeoutcomeshistory', 'grades') . '</li>';
            }
            $counter = 0;
            while ($counter < $gohcount) {
                //Fetch recordset_size records in each iteration
                $recs = get_records_select("backup_ids", "table_name = 'grade_outcomes_history' AND 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, 'grade_outcomes_history', $rec->old_id);
                        if ($data) {
                            //Now get completed xmlized object
                            $info = $data->info;
                            //traverse_xmlize($info);                            //Debug
                            //print_object ($GLOBALS['traverse_array']);         //Debug
                            //$GLOBALS['traverse_array']="";                     //Debug
                            $oldobj = backup_getid($restore->backup_unique_code, "grade_outcomes", backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['OLDID']['0']['#']));
                            if (empty($oldobj->new_id)) {
                                // if the old object is not being restored, can't restoring its history
                                $counter++;
                                continue;
                            }
                            $dbrec->oldid = $oldobj->new_id;
                            $dbrec->action = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['ACTION']['0']['#']);
                            $dbrec->source = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['SOURCE']['0']['#']);
                            $dbrec->timemodified = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
                            if ($oldobj = backup_getid($restore->backup_unique_code, "user", backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
                                $dbrec->loggeduser = $oldobj->new_id;
                            }
                            $dbrec->courseid = $restore->course_id;
                            $dbrec->shortname = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['SHORTNAME']['0']['#']);
                            $dbrec->fullname = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['FULLNAME']['0']['#']);
                            $oldobj = backup_getid($restore->backup_unique_code, "scale", backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['SCALEID']['0']['#']));
                            $dbrec->scaleid = $oldobj->new_id;
                            $dbrec->description = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['DESCRIPTION']['0']['#']);
                            insert_record('grade_outcomes_history', $dbrec);
                            unset($dbrec);
                        }
                        //Increment counters
                        $counter++;
                        //Do some output
                        if ($counter % 1 == 0) {
                            if (!defined('RESTORE_SILENTLY')) {
                                echo ".";
                                if ($counter % 20 == 0) {
                                    echo "<br />";
                                }
                            }
                            backup_flush(300);
                        }
                    }
                }
            }
        }
    }
    if (!defined('RESTORE_SILENTLY')) {
        //End ul
        echo '</ul>';
    }
    return $status;
}
Exemple #18
0
/**
 * Remove all grade related course data - history is kept
 *
 * @global object
 * @param int $courseid
 * @param bool $showfeedback print feedback
 */
function remove_course_grades($courseid, $showfeedback) {
    global $DB, $OUTPUT;

    $strdeleted = get_string('deleted');

    $course_category = grade_category::fetch_course_category($courseid);
    $course_category->delete('coursedelete');
    if ($showfeedback) {
        echo $OUTPUT->notification($strdeleted.' - '.get_string('grades', 'grades').', '.get_string('items', 'grades').', '.get_string('categories', 'grades'));
    }

    if ($outcomes = grade_outcome::fetch_all(array('courseid'=>$courseid))) {
        foreach ($outcomes as $outcome) {
            $outcome->delete('coursedelete');
        }
    }
    $DB->delete_records('grade_outcomes_courses', array('courseid'=>$courseid));
    if ($showfeedback) {
        echo $OUTPUT->notification($strdeleted.' - '.get_string('outcomes', 'grades'));
    }

    if ($scales = grade_scale::fetch_all(array('courseid'=>$courseid))) {
        foreach ($scales as $scale) {
            $scale->delete('coursedelete');
        }
    }
    if ($showfeedback) {
        echo $OUTPUT->notification($strdeleted.' - '.get_string('scales'));
    }

    $DB->delete_records('grade_settings', array('courseid'=>$courseid));
    if ($showfeedback) {
        echo $OUTPUT->notification($strdeleted.' - '.get_string('settings', 'grades'));
    }
}
/**
 * Remove all grade related course data - history is kept
 * @param int $courseid
 * @param bool @showfeedback print feedback
 */
function remove_course_grades($courseid, $showfeedback)
{
    $strdeleted = get_string('deleted');
    $course_category = grade_category::fetch_course_category($courseid);
    $course_category->delete('coursedelete');
    if ($showfeedback) {
        notify($strdeleted . ' - ' . get_string('grades', 'grades') . ', ' . get_string('items', 'grades') . ', ' . get_string('categories', 'grades'));
    }
    if ($outcomes = grade_outcome::fetch_all(array('courseid' => $courseid))) {
        foreach ($outcomes as $outcome) {
            $outcome->delete('coursedelete');
        }
    }
    delete_records('grade_outcomes_courses', 'courseid', $courseid);
    if ($showfeedback) {
        notify($strdeleted . ' - ' . get_string('outcomes', 'grades'));
    }
    if ($scales = grade_scale::fetch_all(array('courseid' => $courseid))) {
        foreach ($scales as $scale) {
            $scale->delete('coursedelete');
        }
    }
    if ($showfeedback) {
        notify($strdeleted . ' - ' . get_string('scales'));
    }
}
Exemple #20
0
 protected function process_grade_item($data)
 {
     global $DB;
     $data = (object) $data;
     $oldid = $data->id;
     $data->course = $this->get_courseid();
     $data->courseid = $this->get_courseid();
     if ($data->itemtype == 'manual') {
         // manual grade items store category id in categoryid
         $data->categoryid = $this->get_mappingid('grade_category', $data->categoryid, NULL);
         // if mapping failed put in course's grade category
         if (NULL == $data->categoryid) {
             $coursecat = grade_category::fetch_course_category($this->get_courseid());
             $data->categoryid = $coursecat->id;
         }
     } else {
         if ($data->itemtype == 'course') {
             // course grade item stores their category id in iteminstance
             $coursecat = grade_category::fetch_course_category($this->get_courseid());
             $data->iteminstance = $coursecat->id;
         } else {
             if ($data->itemtype == 'category') {
                 // category grade items store their category id in iteminstance
                 $data->iteminstance = $this->get_mappingid('grade_category', $data->iteminstance, NULL);
             } else {
                 throw new restore_step_exception('unexpected_grade_item_type', $data->itemtype);
             }
         }
     }
     $data->scaleid = $this->get_mappingid('scale', $data->scaleid, NULL);
     $data->outcomeid = $this->get_mappingid('outcome', $data->outcomeid, NULL);
     $data->locktime = $this->apply_date_offset($data->locktime);
     $data->timecreated = $this->apply_date_offset($data->timecreated);
     $data->timemodified = $this->apply_date_offset($data->timemodified);
     $coursecategory = $newitemid = null;
     //course grade item should already exist so updating instead of inserting
     if ($data->itemtype == 'course') {
         //get the ID of the already created grade item
         $gi = new stdclass();
         $gi->courseid = $this->get_courseid();
         $gi->itemtype = $data->itemtype;
         //need to get the id of the grade_category that was automatically created for the course
         $category = new stdclass();
         $category->courseid = $this->get_courseid();
         $category->parent = null;
         //course category fullname starts out as ? but may be edited
         //$category->fullname  = '?';
         $coursecategory = $DB->get_record('grade_categories', (array) $category);
         $gi->iteminstance = $coursecategory->id;
         $existinggradeitem = $DB->get_record('grade_items', (array) $gi);
         if (!empty($existinggradeitem)) {
             $data->id = $newitemid = $existinggradeitem->id;
             $DB->update_record('grade_items', $data);
         }
     } else {
         if ($data->itemtype == 'manual') {
             // Manual items aren't assigned to a cm, so don't go duplicating them in the target if one exists.
             $gi = array('itemtype' => $data->itemtype, 'courseid' => $data->courseid, 'itemname' => $data->itemname, 'categoryid' => $data->categoryid);
             $newitemid = $DB->get_field('grade_items', 'id', $gi);
         }
     }
     if (empty($newitemid)) {
         //in case we found the course category but still need to insert the course grade item
         if ($data->itemtype == 'course' && !empty($coursecategory)) {
             $data->iteminstance = $coursecategory->id;
         }
         $newitemid = $DB->insert_record('grade_items', $data);
     }
     $this->set_mapping('grade_item', $oldid, $newitemid);
 }
Exemple #21
0
 protected function process_grade_item($data)
 {
     global $DB;
     $data = (object) $data;
     $oldid = $data->id;
     // We'll need these later
     $oldparentid = $data->categoryid;
     $courseid = $this->get_courseid();
     // make sure top course category exists, all grade items will be associated
     // to it. Later, if restoring the whole gradebook, categories will be introduced
     $coursecat = grade_category::fetch_course_category($courseid);
     $coursecatid = $coursecat->id;
     // Get the categoryid to be used
     $idnumber = null;
     if (!empty($data->idnumber)) {
         // Don't get any idnumber from course module. Keep them as they are in grade_item->idnumber
         // Reason: it's not clear what happens with outcomes->idnumber or activities with multiple items (workshop)
         // so the best is to keep the ones already in the gradebook
         // Potential problem: duplicates if same items are restored more than once. :-(
         // This needs to be fixed in some way (outcomes & activities with multiple items)
         // $data->idnumber     = get_coursemodule_from_instance($data->itemmodule, $data->iteminstance)->idnumber;
         // In any case, verify always for uniqueness
         $sql = "SELECT cm.id\n                      FROM {course_modules} cm\n                     WHERE cm.course = :courseid AND\n                           cm.idnumber = :idnumber AND\n                           cm.id <> :cmid";
         $params = array('courseid' => $courseid, 'idnumber' => $data->idnumber, 'cmid' => $this->task->get_moduleid());
         if (!$DB->record_exists_sql($sql, $params) && !$DB->record_exists('grade_items', array('courseid' => $courseid, 'idnumber' => $data->idnumber))) {
             $idnumber = $data->idnumber;
         }
     }
     unset($data->id);
     $data->categoryid = $coursecatid;
     $data->courseid = $this->get_courseid();
     $data->iteminstance = $this->task->get_activityid();
     $data->idnumber = $idnumber;
     $data->scaleid = $this->get_mappingid('scale', $data->scaleid);
     $data->outcomeid = $this->get_mappingid('outcome', $data->outcomeid);
     $data->timecreated = $this->apply_date_offset($data->timecreated);
     $data->timemodified = $this->apply_date_offset($data->timemodified);
     $gradeitem = new grade_item($data, false);
     $gradeitem->insert('restore');
     //sortorder is automatically assigned when inserting. Re-instate the previous sortorder
     $gradeitem->sortorder = $data->sortorder;
     $gradeitem->update('restore');
     // Set mapping, saving the original category id into parentitemid
     // gradebook restore (final task) will need it to reorganise items
     $this->set_mapping('grade_item', $oldid, $gradeitem->id, false, null, $oldparentid);
 }
Exemple #22
0
 /**
  * Tests grade_report_user::inject_rowspans()
  *
  * inject_rowspans() returns the count of the number of elements, sets maxdepth on the
  *  report object and sets the rowspan property on any element that has children.
  */
 public function test_inject_rowspans()
 {
     global $CFG, $USER, $DB;
     parent::setUp();
     $this->resetAfterTest(true);
     $CFG->enableavailability = 1;
     $CFG->enablecompletion = 1;
     // Create a course.
     $course = $this->getDataGenerator()->create_course();
     $coursecategory = grade_category::fetch_course_category($course->id);
     $coursecontext = context_course::instance($course->id);
     // Create and enrol test users.
     $student = $this->getDataGenerator()->create_user(array('username' => 'Student Sam'));
     $role = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
     $this->getDataGenerator()->enrol_user($student->id, $course->id, $role->id);
     $teacher = $this->getDataGenerator()->create_user(array('username' => 'Teacher T'));
     $role = $DB->get_record('role', array('shortname' => 'editingteacher'), '*', MUST_EXIST);
     $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $role->id);
     // An array so we can test with both users in a loop.
     $users = array($student, $teacher);
     // Make the student the current user.
     $this->setUser($student);
     // Test an empty course.
     $report = $this->create_report($course, $student, $coursecontext);
     // a lead column that spans all children + course grade item = 2
     $this->assertEquals(2, $report->inject_rowspans($report->gtree->top_element));
     $this->assertEquals(2, $report->gtree->top_element['rowspan']);
     $this->assertEquals(2, $report->maxdepth);
     // Only elements with children should have rowspan set.
     if (array_key_exists('rowspan', $report->gtree->top_element['children'][1])) {
         $this->fail('Elements without children should not have rowspan set');
     }
     // Add 2 activities.
     $data1 = $this->getDataGenerator()->create_module('data', array('assessed' => 1, 'scale' => 100, 'course' => $course->id));
     $forum1 = $this->getDataGenerator()->create_module('forum', array('assessed' => 1, 'scale' => 100, 'course' => $course->id));
     $forum1cm = get_coursemodule_from_id('forum', $forum1->cmid);
     // Switch the stdClass instance for a grade item instance so grade_item::set_parent() is available.
     $forum1 = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'forum', 'iteminstance' => $forum1->id, 'courseid' => $course->id));
     $report = $this->create_report($course, $student, $coursecontext);
     // Lead column + course + (2 x activity) = 4
     $this->assertEquals(4, $report->inject_rowspans($report->gtree->top_element));
     $this->assertEquals(4, $report->gtree->top_element['rowspan']);
     // Lead column + 1 level (course + 2 activities) = 2
     $this->assertEquals(2, $report->maxdepth);
     // Only elements with children should have rowspan set.
     if (array_key_exists('rowspan', $report->gtree->top_element['children'][1])) {
         $this->fail('Elements without children should not have rowspan set');
     }
     // Hide the forum activity.
     set_coursemodule_visible($forum1cm->id, 0);
     foreach ($users as $user) {
         $this->setUser($user);
         $message = 'Testing with ' . $user->username;
         accesslib_clear_all_caches_for_unit_testing();
         $report = $this->create_report($course, $user, $coursecontext);
         // Lead column + course + (2 x activity) = 4 (element count isn't affected by hiding)
         $this->assertEquals(4, $report->inject_rowspans($report->gtree->top_element), $message);
         $this->assertEquals(4, $report->gtree->top_element['rowspan'], $message);
         // Lead column -> 1 level containing the course + 2 activities = 2
         $this->assertEquals(2, $report->maxdepth, $message);
     }
     // Unhide the forum activity.
     set_coursemodule_visible($forum1cm->id, 1);
     // Create a category and put the forum in it.
     $params = new stdClass();
     $params->courseid = $course->id;
     $params->fullname = 'unittestcategory';
     $params->parent = $coursecategory->id;
     $gradecategory = new grade_category($params, false);
     $gradecategory->insert();
     $forum1->set_parent($gradecategory->id);
     $report = $this->create_report($course, $student, $coursecontext);
     // Lead column + course + (category + category grade item) + (2 x activity) = 6
     $this->assertEquals(6, $report->inject_rowspans($report->gtree->top_element));
     $this->assertEquals(6, $report->gtree->top_element['rowspan']);
     // Lead column -> the category -> the forum activity = 3
     $this->assertEquals(3, $report->maxdepth);
     // Check rowspan on the category. The category itself + category grade item + forum = 3
     $this->assertEquals(3, $report->gtree->top_element['children'][4]['rowspan']);
     // check the forum doesn't have rowspan set
     if (array_key_exists('rowspan', $report->gtree->top_element['children'][4]['children'][3])) {
         $this->fail('The forum has no children so should not have rowspan set');
     }
     // Conditional activity tests.
     // Note: I have ported this test to the new conditional availability
     // system, but it does not appear to actually test anything - in fact,
     // if you remove the code that sets the condition, it still passes
     // because it apparently is intended to have the same number of rows
     // even when some are hidden. The  same is true of the
     // set_coursemodule_visible test above. I don't feel this is a very
     // good test; somebody with more knowledge of this report might want to
     // fix it to check that the row actually is being hidden.
     $DB->set_field('course_modules', 'availability', '{"op":"|","show":false,"c":[' . '{"type":"grade","min":5.5,"id":37}]}', array('id' => $forum1cm->id));
     get_fast_modinfo($course->id, 0, true);
     foreach ($users as $user) {
         $this->setUser($user);
         $message = 'Testing with ' . $user->username;
         accesslib_clear_all_caches_for_unit_testing();
         $report = $this->create_report($course, $user, $coursecontext);
         // Lead column + course + (category + category grade item) + (2 x activity) = 6
         $this->assertEquals(6, $report->inject_rowspans($report->gtree->top_element), $message);
         $this->assertEquals(6, $report->gtree->top_element['rowspan'], $message);
         // Lead column -> the category -> the forum activity = 3
         $this->assertEquals(3, $report->maxdepth, $message);
     }
 }