/** * Validate the formula. * @param string $formula * @return boolean true if calculation possible, false otherwise */ function validate_formula($formulastr) { global $CFG; require_once $CFG->libdir . '/mathslib.php'; $formulastr = grade_item::normalize_formula($formulastr, $this->courseid); if (empty($formulastr)) { return true; } if (strpos($formulastr, '=') !== 0) { return get_string('errorcalculationnoequal', 'grades'); } // get used items if (preg_match_all('/##gi(\\d+)##/', $formulastr, $matches)) { $useditems = array_unique($matches[1]); // remove duplicates } else { $useditems = array(); } // MDL-11902 // unset the value if formula is trying to reference to itself // but array keys does not match itemid if (!empty($this->id)) { $useditems = array_diff($useditems, array($this->id)); //unset($useditems[$this->id]); } // prepare formula and init maths library $formula = preg_replace('/##(gi\\d+)##/', '\\1', $formulastr); $formula = new calc_formula($formula); if (empty($useditems)) { $grade_items = array(); } else { $gis = implode(',', $useditems); $sql = "SELECT gi.*\n FROM {$CFG->prefix}grade_items gi\n 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 if ($result === false) { // TODO: add more error hints return get_string('errorcalculationunknown', 'grades'); } else { return true; } }
$item->aggregationcoef = 0; } else { if ($parent_category->aggregation == GRADE_AGGREGATE_SUM) { $item->aggregationcoef = $item->aggregationcoef > 0 ? 1 : 0; $item->aggregationcoef2 = format_float($item->aggregationcoef2 * 100.0); } else { $item->aggregationcoef = format_float($item->aggregationcoef, 4); } } $mform->set_data($item); if ($data = $mform->get_data()) { if (!isset($data->aggregationcoef)) { $data->aggregationcoef = 0; } if (property_exists($data, 'calculation')) { $data->calculation = grade_item::normalize_formula($data->calculation, $course->id); } $hidden = empty($data->hidden) ? 0 : $data->hidden; $hiddenuntil = empty($data->hiddenuntil) ? 0 : $data->hiddenuntil; unset($data->hidden); unset($data->hiddenuntil); $locked = empty($data->locked) ? 0 : $data->locked; $locktime = empty($data->locktime) ? 0 : $data->locktime; unset($data->locked); unset($data->locktime); $convert = array('gradepass', 'aggregationcoef', 'aggregationcoef2'); foreach ($convert as $param) { if (property_exists($data, $param)) { $data->{$param} = unformat_float($data->{$param}); } }