. /** * @package core * @subpackage lib * @copyright Petr Skoda (skodak) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); /** @see evalmath/evalmath.class.php */ require_once $CFG->dirroot.'/lib/evalmath/evalmath.class.php'; /** * This class abstracts evaluation of spreadsheet formulas. * See unit tests in lib/tests/mathslib_test.php for sample usage. * * @package moodlecore * @copyright Petr Skoda (skodak) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class calc_formula { // private properties var $_em; var $_nfx = false; // postfix notation var $_error = false; // last error /** * Constructor for spreadsheet formula with optional parameters * * @param string $formula with leading = * @param array $params associative array of parameters used in formula. All parameter names must be lowercase! */ public function __construct($formula, $params=false) { $this->_em = new EvalMath(); $this->_em->suppress_errors = true; // no PHP errors! if (strpos($formula, '=') !== 0) { $this->_error = "missing leading '='"; return; } $formula = substr($formula, 1); $this->_nfx = $this->_em->nfx($formula); if ($this->_nfx == false) { $this->_error = $this->_em->last_error; return; } if ($params != false) { $this->set_params($params); } } /** * Old syntax of class constructor. Deprecated in PHP7. * * @deprecated since Moodle 3.1 */ public function calc_formula($formula, $params=false) { debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER); self::__construct($formula, $params); } /** * Raplace parameters used in existing formula, * parameter names must contain only lowercase [a-z] letters, no other characters are allowed! * * @param array $params associative array of parameters used in formula */ function set_params($params) { $this->_em->v = $params; } /** * Evaluate formula * * @return mixed number if ok, false if error */ function evaluate() { if ($this->_nfx == false) { return false; } $res = $this->_em->pfx($this->_nfx); if ($res === false) { $this->_error = $this->_em->last_error; return false; } else { $this->_error = false; return $res; } } /** * Get last error. * TODO: localize the strings from contructor and EvalMath library * * @return mixed string with last error description or false if ok */ function get_error() { return $this->_error; } /** * Similar to format_float, formats the numbers and list separators * according to locale specifics. * @param string $formula * @return string localised formula */ public static function localize($formula) { $formula = str_replace('.', '$', $formula); // temp placeholder $formula = str_replace(',', get_string('listsep', 'langconfig'), $formula); $formula = str_replace('$', get_string('decsep', 'langconfig'), $formula); return $formula; } /** * Similar to unformat_float, converts floats and lists to PHP standards. * @param string $formula localised formula * @return string */ public static function unlocalize($formula) { $formula = str_replace(get_string('decsep', 'langconfig'), '$', $formula); $formula = str_replace(get_string('listsep', 'langconfig'), ',', $formula); $formula = str_replace('$', '.', $formula); // temp placeholder return $formula; } }