/** * Tests the changed params */ function test__changing_params() { $formula = new calc_formula('=a+b+c', array('a'=>10,'b'=>20,'c'=>30)); $res = $formula->evaluate(); $this->assertEqual($res, 60, '10+20+30 is: %s'); $formula->set_params(array('a'=>1,'b'=>2,'c'=>3)); $res = $formula->evaluate(); $this->assertEqual($res, 6, 'changed params 1+2+3 is: %s'); }
/** * 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; } }