30 '+' => array(
'precedence' => 1 ),
31 '-' => array(
'precedence' => 1 ),
32 '*' => array(
'precedence' => 2 ),
33 '/' => array(
'precedence' => 2 ),
34 '^' => array(
'precedence' => 3 ),
84 if (isset(self::$cache_tokens[$this->field->getId()])) {
85 $tokens = self::$cache_tokens[$this->field->getId()];
88 self::$cache_tokens[$this->field->getId()] = $tokens;
92 foreach ($tokens as $token) {
106 if (strpos($token,
'"') === 0) {
107 $parsed .= strip_tags(trim($token,
'"'));
108 } elseif (strpos($token,
'[[') === 0) {
109 $parsed .= trim(strip_tags($this->substituteFieldValue($token)));
111 throw new ilException(
"Unrecognized string token: '$token'");
126 if ($value >= self::SCIENTIFIC_NOTATION_UPPER) {
127 return sprintf(
"%e", $value);
129 if ($value <= self::SCIENTIFIC_NOTATION_LOWER) {
130 return sprintf(
"%e", $value);
132 if (is_float($value)) {
164 if (isset(self::$cache_math_tokens[$this->field->getId()][$token])) {
165 return self::$cache_math_tokens[$this->field->getId()][$token];
167 if (strpos($token,
'"') === 0) {
170 $operators = array_keys(self::getOperators());
173 self::$cache_math_tokens[$this->field->getId()][$token] =
$result;
188 if (isset(self::$cache_math_function_tokens[$this->field->getId()][$token])) {
189 $result = self::$cache_math_function_tokens[$this->field->getId()][$token];
195 foreach (self::getFunctions() as $function) {
196 $pattern .=
"($function)\\(([^)]*)\\)|";
198 if (!preg_match_all(rtrim($pattern,
'|') .
'#', $token,
$result)) {
200 self::$cache_math_function_tokens[$this->field->getId()][$token] =
false;
206 foreach (
$result[0] as $k => $to_replace) {
208 $function = $function_args[
'function'];
210 $token = str_replace($to_replace, $this->
calculateFunction($function, $args), $token);
230 for ($i = 1; $i < count($data); $i ++) {
232 if ($_data[$index]) {
233 $function = $_data[$index];
234 $args = explode(
';', $data[$i + 1][$index]);
235 $return[
'function'] = $function;
236 $return[
'args'] = $args;
254 foreach ($tokens as $token) {
255 if (strpos($token,
'[[') === 0) {
256 $replaced[] = $this->substituteFieldValue($token);
258 $replaced[] = $token;
274 protected function substituteFieldValue($placeholder) {
275 if (isset(self::$cache_fields[$placeholder])) {
276 $field = self::$cache_fields[$placeholder];
279 $field_title = preg_replace(
'#^\[\[(.*)\]\]#',
"$1", $placeholder);
280 $field = $table->getFieldByTitle($field_title);
283 $field = $table->getField($field_title);
289 $lng->loadLanguageModule(
'dcl');
291 throw new ilException(sprintf($lng->txt(
'dcl_err_formula_field_not_found'), $field_title));
294 self::$cache_fields[$placeholder] =
$field;
297 return $this->record->getRecordFieldHTML(
$field->getId());
315 foreach ($tokens as $token) {
316 if (empty($token) OR is_null($token)) {
319 if (is_numeric($token) OR $token ===
'(') {
320 $stack->push($token);
321 if ($token ===
'(') {
324 } elseif (in_array($token, array_keys(
$operators))) {
325 $new_precedence =
$operators[$token][
'precedence'];
326 if ($new_precedence > $precedence || $in_bracket) {
328 $stack->push($token);
329 $precedences->push($new_precedence);
330 $precedence = $new_precedence;
333 while ($new_precedence <= $precedence && $stack->count() > 1) {
334 $right = (float)$stack->pop();
335 $operator = $stack->pop();
336 $left = (float)$stack->pop();
339 $precedence = $precedences->pop();
341 $stack->push($token);
342 $precedence = $new_precedence;
343 $precedences->push($new_precedence);
345 } elseif ($token ===
')') {
348 $elem = $stack->pop();
349 while ($elem !==
'(' && !$stack->isEmpty()) {
351 $elem = $stack->pop();
354 $stack->push($this->
parseMath(array_reverse($_tokens)));
357 throw new ilException(
"Unrecognized token '$token'");
362 if ($stack->count() == 1) {
365 return (ctype_digit((
string)
$result)) ? $result : number_format($result, self::N_DECIMALS,
'.',
"'");
368 while ($stack->count() >= 3) {
369 $right = $stack->pop();
370 $operator = $stack->pop();
371 $left = $stack->pop();
372 $stack->push($this->
calculate($operator, $left, $right));
393 $count = count($args);
395 return ($count) ? array_sum($args) / $count : 0;
397 return array_sum($args);
403 throw new ilException(
"Unrecognized function '$function'");
416 protected function calculate($operator, $left, $right) {
428 $result = ($right == 0) ? 0 : $left / $right;
434 throw new ilException(
"Unrecognized operator '$operator'");