MDL-10364 calcualtion validation improvements

This commit is contained in:
skodak 2007-07-12 17:23:29 +00:00
parent 64480c7dff
commit 9029762c3c
2 changed files with 59 additions and 4 deletions

View File

@ -115,7 +115,11 @@ class edit_item_form extends moodleform {
if ($data['calculation'] != '') {
if (strpos($data['calculation'], '=') !== 0) {
$errors['calculation'] = get_string('calculationerror', 'grades');
//TODO: add better formula validation
} else {
$grade_item = new grade_item(array('id'=>$data['id'], 'itemtype'=>$data['itemtype'], 'courseid'=>$data['courseid']));
if (!$grade_item->validate_formula($data['calculation'])) {
$errors['calculation'] = get_string('calculationerror', 'grades');
}
}
}

View File

@ -457,7 +457,7 @@ class grade_item extends grade_object {
}
}
/**
* Set the locktime for this grade.
*
@ -468,9 +468,9 @@ class grade_item extends grade_object {
if ($locktime) {
// if current locktime is before, no need to reset
if ($this->locktime && $this->locktime <= $locktime) {
return true;
return true;
}
/*
@ -894,6 +894,7 @@ class grade_item extends grade_object {
/**
* Denormalizes the calculation formula to [idnumber] form
* @static
* @param string $formula
* @return string denormalized string
*/
@ -919,6 +920,7 @@ class grade_item extends grade_object {
/**
* Normalizes the calculation formula to [#giXX#] form
* @static
* @param string $formula
* @return string normalized string
*/
@ -1466,5 +1468,54 @@ class grade_item extends grade_object {
}
/**
* Validate the formula.
* @param string $formula
* @return boolean true if calculation possible, false otherwise
*/
function validate_formula($formula) {
global $CFG;
require_once($CFG->libdir.'/mathslib.php');
$formula = grade_item::normalize_formula($formula, $this->courseid);
if (empty($formula)) {
return true;
}
// prepare formula and init maths library
$formula = preg_replace('/\[#(gi[0-9]+)#\]/', '\1', $formula);
$formula = new calc_formula($formula);
// get used items
$useditems = $this->depends_on();
$gis = implode(',', $useditems);
$sql = "SELECT gi.*
FROM {$CFG->prefix}grade_items gi
WHERE gi.id IN ($gis) and gi.courseid={$this->courseid}"; // from the same course only!
if (!$grade_items = get_records_sql($sql)) {
$grade_items = array();
}
$params = array();
foreach ($useditems as $itemid) {
// make sure all grade items exist in this course
if (!array_key_exists($itemid, $grade_items)) {
return false;
}
// use max grade when testing formula, this should be ok in 99.9%
// division by 0 is one of possible problems
$params['gi'.$grade_items[$itemid]->id] = $grade_items[$itemid]->grademax;
}
// do the calculation
$formula->set_params($params);
$result = $formula->evaluate();
// false as result indicates some problem
return ($result !== false);
}
}
?>