diff --git a/lib/grade/grade_item.php b/lib/grade/grade_item.php index 8c37efc85c6..474028ec064 100644 --- a/lib/grade/grade_item.php +++ b/lib/grade/grade_item.php @@ -1372,18 +1372,20 @@ class grade_item extends grade_object { if ($grade_category->aggregatesubcats) { // return all children excluding category items + $params[] = $this->courseid; $params[] = '%/' . $grade_category->id . '/%'; $sql = "SELECT gi.id FROM {grade_items} gi + JOIN {grade_categories} gc ON gi.categoryid = gc.id WHERE $gtypes $outcomes_sql - AND gi.categoryid IN ( - SELECT gc.id - FROM {grade_categories} gc - WHERE gc.path LIKE ?)"; + AND gi.courseid = ? + AND gc.path LIKE ?"; } else { $params[] = $grade_category->id; + $params[] = $this->courseid; $params[] = $grade_category->id; + $params[] = $this->courseid; if (empty($CFG->grade_includescalesinaggregation)) { $params[] = GRADE_TYPE_VALUE; } else { @@ -1394,6 +1396,7 @@ class grade_item extends grade_object { FROM {grade_items} gi WHERE $gtypes AND gi.categoryid = ? + AND gi.courseid = ? $outcomes_sql UNION @@ -1401,6 +1404,7 @@ class grade_item extends grade_object { FROM {grade_items} gi, {grade_categories} gc WHERE (gi.itemtype = 'category' OR gi.itemtype = 'course') AND gi.iteminstance=gc.id AND gc.parent = ? + AND gi.courseid = ? AND $gtypes $outcomes_sql"; } diff --git a/lib/grade/tests/fixtures/lib.php b/lib/grade/tests/fixtures/lib.php index b7d90ef3202..40e78b16f35 100644 --- a/lib/grade/tests/fixtures/lib.php +++ b/lib/grade/tests/fixtures/lib.php @@ -171,13 +171,13 @@ abstract class grade_base_testcase extends advanced_testcase { * category structure: course category | - +--------+-------------+ - | | - unittestcategory1 level1category - | - +--------+-------------+ - | | - unittestcategory2 unittestcategory3 + +--------+-------------+-----------------------+ + | | | + unittestcategory1 level1category aggregatesubcatscategory + | | + +--------+-------------+ +------------+---------------+ + | | | | + unittestcategory2 unittestcategory3 unittestcategory5 unittestcategory6 */ private function load_grade_categories() { global $DB; @@ -257,6 +257,61 @@ abstract class grade_base_testcase extends advanced_testcase { $grade_category->path = '/'.$course_category->id.'/'.$grade_category->id.'/'; $DB->update_record('grade_categories', $grade_category); $this->grade_categories[3] = $grade_category; + + $grade_category = new stdClass(); + + $grade_category->fullname = 'aggregatesubcatscategory'; + $grade_category->courseid = $this->course->id; + $grade_category->aggregation = GRADE_AGGREGATE_MEAN; + $grade_category->aggregateonlygraded = 1; + $grade_category->aggregatesubcats = 1; + $grade_category->keephigh = 0; + $grade_category->droplow = 0; + $grade_category->parent = $course_category->id; + $grade_category->timecreated = time(); + $grade_category->timemodified = time(); + $grade_category->depth = 2; + + $grade_category->id = $DB->insert_record('grade_categories', $grade_category); + $grade_category->path = '/'.$course_category->id.'/'.$grade_category->id.'/'; + $DB->update_record('grade_categories', $grade_category); + $this->grade_categories[4] = $grade_category; + + $grade_category = new stdClass(); + + $grade_category->fullname = 'unittestcategory5'; + $grade_category->courseid = $this->course->id; + $grade_category->aggregation = GRADE_AGGREGATE_MEAN; + $grade_category->aggregateonlygraded = 1; + $grade_category->keephigh = 0; + $grade_category->droplow = 0; + $grade_category->parent = $this->grade_categories[4]->id; + $grade_category->timecreated = time(); + $grade_category->timemodified = time(); + $grade_category->depth = 3; + + $grade_category->id = $DB->insert_record('grade_categories', $grade_category); + $grade_category->path = $this->grade_categories[4]->path.$grade_category->id.'/'; + $DB->update_record('grade_categories', $grade_category); + $this->grade_categories[5] = $grade_category; + + $grade_category = new stdClass(); + + $grade_category->fullname = 'unittestcategory6'; + $grade_category->courseid = $this->course->id; + $grade_category->aggregation = GRADE_AGGREGATE_MEAN; + $grade_category->aggregateonlygraded = 1; + $grade_category->keephigh = 0; + $grade_category->droplow = 0; + $grade_category->parent = $this->grade_categories[4]->id; + $grade_category->timecreated = time(); + $grade_category->timemodified = time(); + $grade_category->depth = 3; + + $grade_category->id = $DB->insert_record('grade_categories', $grade_category); + $grade_category->path = $this->grade_categories[4]->path.$grade_category->id.'/'; + $DB->update_record('grade_categories', $grade_category); + $this->grade_categories[6] = $grade_category; } /** @@ -520,6 +575,107 @@ abstract class grade_base_testcase extends advanced_testcase { $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. } /** @@ -796,5 +952,26 @@ abstract class grade_base_testcase extends advanced_testcase { $grade_outcome->id = $DB->insert_record('grade_outcomes', $grade_outcome); $this->grade_outcomes[] = $grade_outcome; + + // Manual grade_item with outcome + $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 with outcome used for unit testing'; + $grade_item->timecreated = time(); + $grade_item->timemodified = time(); + $grade_item->outcomeid = $this->grade_outcomes[2]->id; + $grade_item->sortorder = 17; + + $grade_item->id = $DB->insert_record('grade_items', $grade_item); + $this->grade_items[17] = $grade_item; } } diff --git a/lib/grade/tests/grade_item_test.php b/lib/grade/tests/grade_item_test.php index 702a2689e6b..d5bca17a4a0 100644 --- a/lib/grade/tests/grade_item_test.php +++ b/lib/grade/tests/grade_item_test.php @@ -100,7 +100,7 @@ class grade_item_testcase extends grade_base_testcase { $last_grade_item = end($this->grade_items); $this->assertEquals($grade_item->id, $last_grade_item->id + 1); - $this->assertEquals(12, $grade_item->sortorder); + $this->assertEquals(18, $grade_item->sortorder); //keep our reference collection the same as what is in the database $this->grade_items[] = $grade_item; @@ -464,6 +464,10 @@ class grade_item_testcase extends grade_base_testcase { } protected function sub_test_grade_item_depends_on() { + global $CFG; + + $origenableoutcomes = $CFG->enableoutcomes; + $CFG->enableoutcomes = 0; $grade_item = new grade_item($this->grade_items[1], false); // calculated grade dependency @@ -484,6 +488,37 @@ class grade_item_testcase extends grade_base_testcase { sort($deps, SORT_NUMERIC); // for comparison $res = array($this->grade_items[4]->id, $this->grade_items[5]->id); $this->assertEquals($res, $deps); + + $CFG->enableoutcomes = 1; + $origgradeincludescalesinaggregation = $CFG->grade_includescalesinaggregation; + $CFG->grade_includescalesinaggregation = 1; + + // Item in category with aggregate sub categories + $CFG->grade_includescalesinaggregation = 1. + $grade_item = new grade_item($this->grade_items[12], false); + $deps = $grade_item->depends_on(); + sort($deps, SORT_NUMERIC); + $res = array($this->grade_items[15]->id, $this->grade_items[16]->id); + $this->assertEquals($res, $deps); + + // Item in category with aggregate sub categories + $CFG->grade_includescalesinaggregation = 0. + $CFG->grade_includescalesinaggregation = 0; + $grade_item = new grade_item($this->grade_items[12], false); + $deps = $grade_item->depends_on(); + sort($deps, SORT_NUMERIC); + $res = array($this->grade_items[15]->id); + $this->assertEquals($res, $deps); + $CFG->grade_includescalesinaggregation = 1; + + // Outcome item in category with with aggregate sub categories. + $CFG->enableoutcomes = 0; + $grade_item = new grade_item($this->grade_items[12], false); + $deps = $grade_item->depends_on(); + sort($deps, SORT_NUMERIC); + $res = array($this->grade_items[15]->id, $this->grade_items[16]->id, $this->grade_items[17]->id); + $this->assertEquals($res, $deps); + + $CFG->enableoutcomes = $origenableoutcomes; + $CFG->grade_includescalesinaggregation = $origgradeincludescalesinaggregation; } protected function sub_test_refresh_grades() {