/**
* Calculates the grade to be pushed to the gradebook
*
- * @return int the valid grade from $this->get_controller()->get_grade_range()
+ * @return float|int the valid grade from $this->get_controller()->get_grade_range()
*/
public function get_grade() {
- global $DB, $USER;
$grade = $this->get_guide_filling();
if (!($scores = $this->get_controller()->get_min_max_score()) || $scores['maxscore'] <= $scores['minscore']) {
foreach ($grade['criteria'] as $record) {
$curscore += $record['score'];
}
- return round(($curscore-$scores['minscore'])/($scores['maxscore']-$scores['minscore'])*
- ($maxgrade-$mingrade), 0) + $mingrade;
+ $gradeoffset = ($curscore-$scores['minscore'])/($scores['maxscore']-$scores['minscore'])*
+ ($maxgrade-$mingrade);
+ if ($this->get_controller()->get_allow_grade_decimals()) {
+ return $gradeoffset + $mingrade;
+ }
+ return round($gradeoffset, 0) + $mingrade;
}
/**
/** @var array graderange array of valid grades for this area. Use set_grade_range and get_grade_range to access this */
private $graderange = null;
+ /** @var bool if decimal values are allowed as grades. */
+ private $allowgradedecimals = false;
+
/** @var boolean|null cached result of function has_active_instances() */
protected $hasactiveinstances = null;
/**
* Sets the range of grades used in this area. This is usually either range like 0-100
- * or the scale where keys start from 1. Typical use:
- * $controller->set_grade_range(make_grades_menu($gradingtype));
+ * or the scale where keys start from 1.
+ *
+ * Typically modules will call it:
+ * $controller->set_grade_range(make_grades_menu($gradingtype), $gradingtype > 0);
+ * Negative $gradingtype means that scale is used and the grade must be rounded
+ * to the nearest int. Positive $gradingtype means that range 0..$gradingtype
+ * is used for the grades and in this case grade does not have to be rounded.
+ *
+ * Sometimes modules always expect grade to be rounded (like mod_assignment does).
*
- * @param array $graderange
+ * @param array $graderange array where first _key_ is the minimum grade and the
+ * last key is the maximum grade.
+ * @param bool $allowgradedecimals if decimal values are allowed as grades.
*/
- public final function set_grade_range(array $graderange) {
+ public final function set_grade_range(array $graderange, $allowgradedecimals = false) {
$this->graderange = $graderange;
+ $this->allowgradedecimals = $allowgradedecimals;
}
/**
return $this->graderange;
}
+ /**
+ * Returns if decimal values are allowed as grades
+ *
+ * @return bool
+ */
+ public final function get_allow_grade_decimals() {
+ return $this->allowgradedecimals;
+ }
+
/**
* Overridden by sub classes that wish to make definition details available to web services.
* When not overridden, only definition data common to all grading methods is made available.
/**
* Calculates the grade to be pushed to the gradebook
*
- * @return int the valid grade from $this->get_controller()->get_grade_range()
+ * Returned grade must be in range $this->get_controller()->get_grade_range()
+ * Plugins must returned grade converted to int unless
+ * $this->get_controller()->get_allow_grade_decimals() is true.
+ *
+ * @return float|int
*/
abstract public function get_grade();
/**
* Calculates the grade to be pushed to the gradebook
*
- * @return int the valid grade from $this->get_controller()->get_grade_range()
+ * @return float|int the valid grade from $this->get_controller()->get_grade_range()
*/
public function get_grade() {
- global $DB, $USER;
$grade = $this->get_rubric_filling();
if (!($scores = $this->get_controller()->get_min_max_score()) || $scores['maxscore'] <= $scores['minscore']) {
foreach ($grade['criteria'] as $id => $record) {
$curscore += $this->get_controller()->get_definition()->rubric_criteria[$id]['levels'][$record['levelid']]['score'];
}
- return round(($curscore-$scores['minscore'])/($scores['maxscore']-$scores['minscore'])*($maxgrade-$mingrade), 0) + $mingrade;
+ $gradeoffset = ($curscore-$scores['minscore'])/($scores['maxscore']-$scores['minscore'])*($maxgrade-$mingrade);
+ if ($this->get_controller()->get_allow_grade_decimals()) {
+ return $gradeoffset + $mingrade;
+ }
+ return round($gradeoffset, 0) + $mingrade;
}
/**
--- /dev/null
+This files describes API changes in /grade/grading/form/* - Advanced grading methods
+information provided here is intended especially for developers.
+
+=== 2.5.2 ===
+
+* Grading methods now can return grade with decimals. See API functions
+ gradingform_controller::set_grade_range() and
+ gradingform_controller::get_allow_grade_decimals(), and also examples
+ in gradingform_rubric_instance::get_grade().
// Only show the grade if it is not hidden in gradebook.
if (!empty($gradebookgrade->grade) && ($cangrade || !$gradebookgrade->hidden)) {
if ($controller = $gradingmanager->get_active_controller()) {
- $controller->set_grade_range(make_grades_menu($this->get_instance()->grade));
+ $controller->set_grade_range(make_grades_menu($this->get_instance()->grade), $this->get_instance()->grade > 0);
$gradefordisplay = $controller->render_grade($PAGE,
$grade->id,
$gradingitem,
// Now get the gradefordisplay.
if ($controller) {
- $controller->set_grade_range(make_grades_menu($this->get_instance()->grade));
+ $controller->set_grade_range(make_grades_menu($this->get_instance()->grade), $this->get_instance()->grade > 0);
$grade->gradefordisplay = $controller->render_grade($PAGE,
$grade->id,
$gradingitem,
global $CFG, $USER;
$grademenu = make_grades_menu($this->get_instance()->grade);
+ $allowgradedecimals = $this->get_instance()->grade > 0;
$advancedgradingwarning = false;
$gradingmanager = get_grading_manager($this->context, 'mod_assign', 'submissions');
}
}
if ($gradinginstance) {
- $gradinginstance->get_controller()->set_grade_range($grademenu);
+ $gradinginstance->get_controller()->set_grade_range($grademenu, $allowgradedecimals);
}
return $gradinginstance;
}