Exemple #1
0
 /**
  * Generates and saves final grades in associated category grade item.
  * These immediate children must already have their own final grades.
  * The category's aggregation method is used to generate final grades.
  *
  * Please note that category grade is either calculated or aggregated, not both at the same time.
  *
  * This method must be used ONLY from grade_item::regrade_final_grades(),
  * because the calculation must be done in correct order!
  *
  * Steps to follow:
  *  1. Get final grades from immediate children
  *  3. Aggregate these grades
  *  4. Save them in final grades of associated category grade item
  *
  * @param int $userid The user ID if final grade generation should be limited to a single user
  * @return bool
  */
 public function generate_grades($userid = null)
 {
     global $CFG, $DB;
     $this->load_grade_item();
     if ($this->grade_item->is_locked()) {
         return true;
         // no need to recalculate locked items
     }
     // find grade items of immediate children (category or grade items) and force site settings
     $depends_on = $this->grade_item->depends_on();
     if (empty($depends_on)) {
         $items = false;
     } else {
         list($usql, $params) = $DB->get_in_or_equal($depends_on);
         $sql = "SELECT *\n                      FROM {grade_items}\n                     WHERE id {$usql}";
         $items = $DB->get_records_sql($sql, $params);
     }
     // needed mostly for SUM agg type
     $this->auto_update_max($items);
     $grade_inst = new grade_grade();
     $fields = 'g.' . implode(',g.', $grade_inst->required_fields);
     // where to look for final grades - include grade of this item too, we will store the results there
     $gis = array_merge($depends_on, array($this->grade_item->id));
     list($usql, $params) = $DB->get_in_or_equal($gis);
     if ($userid) {
         $usersql = "AND g.userid=?";
         $params[] = $userid;
     } else {
         $usersql = "";
     }
     $sql = "SELECT {$fields}\n                  FROM {grade_grades} g, {grade_items} gi\n                 WHERE gi.id = g.itemid AND gi.id {$usql} {$usersql}\n              ORDER BY g.userid";
     // group the results by userid and aggregate the grades for this user
     $rs = $DB->get_recordset_sql($sql, $params);
     if ($rs->valid()) {
         $prevuser = 0;
         $grade_values = array();
         $excluded = array();
         $oldgrade = null;
         foreach ($rs as $used) {
             if ($used->userid != $prevuser) {
                 $this->aggregate_grades($prevuser, $items, $grade_values, $oldgrade, $excluded);
                 $prevuser = $used->userid;
                 $grade_values = array();
                 $excluded = array();
                 $oldgrade = null;
             }
             $grade_values[$used->itemid] = $used->finalgrade;
             if ($used->excluded) {
                 $excluded[] = $used->itemid;
             }
             if ($this->grade_item->id == $used->itemid) {
                 $oldgrade = $used;
             }
         }
         $this->aggregate_grades($prevuser, $items, $grade_values, $oldgrade, $excluded);
         //the last one
     }
     $rs->close();
     return true;
 }
Exemple #2
0
 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.
     $deps = $grade_item->depends_on();
     sort($deps, SORT_NUMERIC);
     // For comparison.
     $this->assertEquals(array($this->grade_items[0]->id), $deps);
     // Simulate depends on returns none when locked.
     $grade_item->locked = time();
     $grade_item->update();
     $deps = $grade_item->depends_on();
     sort($deps, SORT_NUMERIC);
     // For comparison.
     $this->assertEquals(array(), $deps);
     // Category dependency.
     $grade_item = new grade_item($this->grade_items[3], false);
     $deps = $grade_item->depends_on();
     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;
 }
Exemple #3
0
 /**
  * Some aggregation types may need to update their max grade.
  *
  * This must be executed after updating the weights as it relies on them.
  *
  * @return void
  */
 private function auto_update_max()
 {
     global $DB;
     if ($this->aggregation != GRADE_AGGREGATE_SUM) {
         // not needed at all
         return;
     }
     // Find grade items of immediate children (category or grade items) and force site settings.
     $this->load_grade_item();
     $depends_on = $this->grade_item->depends_on();
     $items = false;
     if (!empty($depends_on)) {
         list($usql, $params) = $DB->get_in_or_equal($depends_on);
         $sql = "SELECT *\n                      FROM {grade_items}\n                     WHERE id {$usql}";
         $items = $DB->get_records_sql($sql, $params);
     }
     if (!$items) {
         if ($this->grade_item->grademax != 0 or $this->grade_item->gradetype != GRADE_TYPE_VALUE) {
             $this->grade_item->grademax = 0;
             $this->grade_item->grademin = 0;
             $this->grade_item->gradetype = GRADE_TYPE_VALUE;
             $this->grade_item->update('aggregation');
         }
         return;
     }
     //find max grade possible
     $maxes = array();
     foreach ($items as $item) {
         if ($item->aggregationcoef > 0) {
             // extra credit from this activity - does not affect total
             continue;
         } else {
             if ($item->aggregationcoef2 <= 0) {
                 // Items with a weight of 0 do not affect the total.
                 continue;
             }
         }
         if ($item->gradetype == GRADE_TYPE_VALUE) {
             $maxes[$item->id] = $item->grademax;
         } else {
             if ($item->gradetype == GRADE_TYPE_SCALE) {
                 $maxes[$item->id] = $item->grademax;
                 // 0 = nograde, 1 = first scale item, 2 = second scale item
             }
         }
     }
     if ($this->can_apply_limit_rules()) {
         // Apply droplow and keephigh.
         $this->apply_limit_rules($maxes, $items);
     }
     $max = array_sum($maxes);
     // update db if anything changed
     if ($this->grade_item->grademax != $max or $this->grade_item->grademin != 0 or $this->grade_item->gradetype != GRADE_TYPE_VALUE) {
         $this->grade_item->grademax = $max;
         $this->grade_item->grademin = 0;
         $this->grade_item->gradetype = GRADE_TYPE_VALUE;
         $this->grade_item->update('aggregation');
     }
 }
 protected function sub_test_grade_item_depends_on()
 {
     $grade_item = new grade_item($this->grade_items[1], false);
     // calculated grade dependency
     $deps = $grade_item->depends_on();
     sort($deps, SORT_NUMERIC);
     // for comparison
     $this->assertEquals(array($this->grade_items[0]->id), $deps);
     // simulate depends on returns none when locked
     $grade_item->locked = time();
     $grade_item->update();
     $deps = $grade_item->depends_on();
     sort($deps, SORT_NUMERIC);
     // for comparison
     $this->assertEquals(array(), $deps);
     // category dependency
     $grade_item = new grade_item($this->grade_items[3], false);
     $deps = $grade_item->depends_on();
     sort($deps, SORT_NUMERIC);
     // for comparison
     $res = array($this->grade_items[4]->id, $this->grade_items[5]->id);
     $this->assertEquals($res, $deps);
 }
 /**
  * Some aggregation types may need to update their max grade.
  *
  * This must be executed after updating the weights as it relies on them.
  *
  * @return void
  */
 private function auto_update_max()
 {
     global $DB;
     if ($this->aggregation != GRADE_AGGREGATE_SUM) {
         // not needed at all
         return;
     }
     // Find grade items of immediate children (category or grade items) and force site settings.
     $this->load_grade_item();
     $depends_on = $this->grade_item->depends_on();
     // Check to see if the gradebook is frozen. This allows grades to not be altered at all until a user verifies that they
     // wish to update the grades.
     $gradebookcalculationsfreeze = get_config('core', 'gradebook_calculations_freeze_' . $this->courseid);
     // Only run if the gradebook isn't frozen.
     if ($gradebookcalculationsfreeze && (int) $gradebookcalculationsfreeze <= 20150627) {
         // Do nothing.
     } else {
         // Don't automatically update the max for calculated items.
         if ($this->grade_item->is_calculated()) {
             return;
         }
     }
     $items = false;
     if (!empty($depends_on)) {
         list($usql, $params) = $DB->get_in_or_equal($depends_on);
         $sql = "SELECT *\n                      FROM {grade_items}\n                     WHERE id {$usql}";
         $items = $DB->get_records_sql($sql, $params);
     }
     if (!$items) {
         if ($this->grade_item->grademax != 0 or $this->grade_item->gradetype != GRADE_TYPE_VALUE) {
             $this->grade_item->grademax = 0;
             $this->grade_item->grademin = 0;
             $this->grade_item->gradetype = GRADE_TYPE_VALUE;
             $this->grade_item->update('aggregation');
         }
         return;
     }
     //find max grade possible
     $maxes = array();
     foreach ($items as $item) {
         if ($item->aggregationcoef > 0) {
             // extra credit from this activity - does not affect total
             continue;
         } else {
             if ($item->aggregationcoef2 <= 0) {
                 // Items with a weight of 0 do not affect the total.
                 continue;
             }
         }
         if ($item->gradetype == GRADE_TYPE_VALUE) {
             $maxes[$item->id] = $item->grademax;
         } else {
             if ($item->gradetype == GRADE_TYPE_SCALE) {
                 $maxes[$item->id] = $item->grademax;
                 // 0 = nograde, 1 = first scale item, 2 = second scale item
             }
         }
     }
     if ($this->can_apply_limit_rules()) {
         // Apply droplow and keephigh.
         $this->apply_limit_rules($maxes, $items);
     }
     $max = array_sum($maxes);
     // update db if anything changed
     if ($this->grade_item->grademax != $max or $this->grade_item->grademin != 0 or $this->grade_item->gradetype != GRADE_TYPE_VALUE) {
         $this->grade_item->grademax = $max;
         $this->grade_item->grademin = 0;
         $this->grade_item->gradetype = GRADE_TYPE_VALUE;
         $this->grade_item->update('aggregation');
     }
 }
Exemple #6
0
 protected function scales_outcomes_test_grade_item_depends_on()
 {
     $CFG->enableoutcomes = 1;
     $origgradeincludescalesinaggregation = $CFG->grade_includescalesinaggregation;
     $CFG->grade_includescalesinaggregation = 1;
     // Scale item in category with $CFG->grade_includescalesinaggregation = 1.
     $grade_item = new grade_item($this->grade_items[14], false);
     $deps = $grade_item->depends_on();
     sort($deps, SORT_NUMERIC);
     $res = array($this->grade_items[16]->id);
     $this->assertEquals($res, $deps);
     // Scale item in category with $CFG->grade_includescalesinaggregation = 0.
     $CFG->grade_includescalesinaggregation = 0;
     $grade_item = new grade_item($this->grade_items[14], false);
     $deps = $grade_item->depends_on();
     $res = array();
     $this->assertEquals($res, $deps);
     $CFG->grade_includescalesinaggregation = 1;
     // Outcome item in category with outcomes disabled.
     $CFG->enableoutcomes = 0;
     $grade_item = new grade_item($this->grade_items[14], false);
     $deps = $grade_item->depends_on();
     sort($deps, SORT_NUMERIC);
     $res = array($this->grade_items[16]->id, $this->grade_items[17]->id);
     $this->assertEquals($res, $deps);
     $CFG->enableoutcomes = $origenableoutcomes;
     $CFG->grade_includescalesinaggregation = $origgradeincludescalesinaggregation;
 }