private function _HandleFunctions($pstrTok, &$pStack, $pdtFormat, &$parrVars) { if (!$pstrTok->isFunction) { throw new Exception("Unsupported function token [" . $pstrTok->val . "]"); } $varTmp = $pstrTok->val; $arrArgs = array(); $varTerm = Toolset_Tokenizer::$ARG_TERMINAL; while (!$pStack->IsEmpty()) { $varTerm = $pStack->Pop(); if (!$varTerm->isArgTerminal) { $arrArgs[] = $varTerm; } else { break; } } switch ($varTmp) { case "ARRAY": $arrArray = array(); $objTmp = 0; $intCntr = count($arrArgs); while (--$intCntr >= 0) { $varTerm = $arrArgs[$intCntr]; if ($varTerm->isVariable) { if (!isset($parrVars[$varTerm->val])) { throw new Exception("Variable [" . $varTerm->val . "] not defined"); } else { $varTerm = $parrVars[$varTerm->val]; } } $arrArray = array_merge($arrArray, Toolset_Tokenizer::toArray($varTerm->val)); } $pStack->Push(Toolset_Tokenizer::makeToken($arrArray, Toolset_Tokenizer::$TOKEN_TYPE['ARRAY'])); break; case "TODAY": $pStack->Push(Toolset_Tokenizer::makeToken(Toolset_DateParser::currentDate(), Toolset_Tokenizer::$TOKEN_TYPE['DATE'])); break; case "ACOS": case "ASIN": case "ATAN": throw new Exception("Function [" . $varTmp . "] is not implemented!"); break; case "ABS": case "CHR": case "COS": case "FIX": case "HEX": case "LOG": case "RAND": case "ROUND": case "SIN": case "SQRT": case "TAN": if ($varTmp != "RAND") { if (count($arrArgs) < 1) { throw new Exception($varTmp . " requires at least one argument!"); } else { if (count($arrArgs) > 1) { throw new Exception($varTmp . " requires only one argument!"); } } } else { if (count($arrArgs) < 1) { throw new Exception($varTmp . " requires at least one argument!"); } else { if (count($arrArgs) > 2) { throw new Exception($varTmp . " requires at most two arguments!"); } } } $varTerm = $arrArgs[0]; if ($varTerm->isVariable) { if (!isset($parrVars[$varTerm->val])) { throw new Exception("Variable [" . $varTerm->val . "] not defined"); } else { $varTerm = $parrVars[$varTerm->val]; } } $objTmp = $varTerm->val; $rand_min = $rand_max = 0; if (is_numeric($objTmp) === false) { throw new Exception($varTmp . " operates on numeric operands only!"); } else { $objTmp = Toolset_Tokenizer::toNumber($varTerm->val); if ($varTmp == "RAND") { $rand_max = floor($objTmp); if (count($arrArgs) == 2) { $varTerm = $arrArgs[1]; if ($varTerm->isVariable) { if (!isset($parrVars[$varTerm->val])) { throw new Exception("Variable [" . $varTerm->val . "] not defined"); } else { $varTerm = $parrVars[$varTerm->val]; } } if (!$varTerm->isNumber) { throw new Exception($varTmp . " operates on numeric operands only!"); } $objTmp = Toolset_Tokenizer::toNumber($varTerm->val); $rand_min = floor($objTmp); } } } if ($varTmp == "ABS") { $pStack->Push(Toolset_Tokenizer::makeToken(abs($objTmp), Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } else { if ($varTmp == "CHR") { // TODO check what happens when $objTmp is empty; what does chr() return? $pStack->Push(Toolset_Tokenizer::makeToken(chr($objTmp), Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL'])); } else { if ($varTmp == "COS") { $pStack->Push(Toolset_Tokenizer::makeToken(cos($objTmp), Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } else { if ($varTmp == "FIX") { $pStack->Push(Toolset_Tokenizer::makeToken(floor($objTmp), Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } else { if ($varTmp == "HEX") { $pStack->Push(Toolset_Tokenizer::makeToken(dechex($objTmp), Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL'])); } else { if ($varTmp == "LOG") { $pStack->Push(Toolset_Tokenizer::makeToken(log($objTmp), Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } else { if ($varTmp == "RAND") { $pStack->Push(Toolset_Tokenizer::makeToken(mt_rand($rand_min, $rand_max), Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } else { if ($varTmp == "ROUND") { $pStack->Push(Toolset_Tokenizer::makeToken(round($objTmp), Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } else { if ($varTmp == "SIN") { $pStack->Push(Toolset_Tokenizer::makeToken(sin($objTmp), Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } else { if ($varTmp == "SQRT") { $pStack->Push(Toolset_Tokenizer::makeToken(sqrt($objTmp), Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } else { if ($varTmp == "TAN") { $pStack->Push(Toolset_Tokenizer::makeToken(tan($objTmp), Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } } } } } } } } } } } break; case "STR": if (count($arrArgs) < 1) { throw new Exception($varTmp . " requires at least one argument!"); } else { if (count($arrArgs) > 2) { throw new Exception($varTmp . " requires at most two arguments!"); } } $varTerm = $arrArgs[count($arrArgs) - 1]; if ($varTerm->isVariable) { if (!isset($parrVars[$varTerm->val])) { throw new Exception("Variable [" . $varTerm->val . "] not defined"); } else { $varTerm = $parrVars[$varTerm->val]; } } // if date, output formated date string if ($varTerm->isDate) { $format = ''; if (count($arrArgs) == 2) { $varFormat = $arrArgs[0]; if ($varFormat->isVariable) { if (!isset($parrVars[$varFormat->val])) { throw new Exception("Variable [" . $varFormat->val . "] not defined"); } else { $varFormat = $parrVars[$varFormat->val]; } } if (!$varFormat->isStringLiteral) { throw new Exception("format argument for " . $varTmp . " must be a string!"); } $format = $varFormat->val; } $pStack->Push(Toolset_Tokenizer::makeToken(Toolset_DateParser::formatDate($varTerm->val, $format), Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL'])); } else { // just convert to string $pStack->Push(Toolset_Tokenizer::makeToken((string) $varTerm->val . '', Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL'])); } break; case "ASC": if (count($arrArgs) > 1) { throw new Exception($varTmp . " requires only one argument!"); } else { if (count($arrArgs) < 1) { throw new Exception($varTmp . " requires at least one argument!"); } } $varTerm = $arrArgs[0]; if ($varTerm->isVariable) { if (!isset($parrVars[$varTerm->val])) { throw new Exception("Variable [" . $varTerm->val . "] not defined"); } else { $varTerm = $parrVars[$varTerm]->val; } } if ($varTerm->isNumber) { $varTerm->val = (string) $varTerm->val; $varTerm->isStringLiteral = true; } if (!$varTerm->isStringLiteral) { throw new Exception($varTmp . " requires a string type operand!"); } else { if (strlen($varTerm->val) > 0) { $ascii_char = ord($varTerm->val[0]); } else { $ascii_char = 0; } $pStack->Push(Toolset_Tokenizer::makeToken($ascii_char, Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } break; case "REGEX": if (count($arrArgs) < 1) { throw new Exception($varTmp . " requires at least one argument!"); } else { if (count($arrArgs) > 2) { throw new Exception($varTmp . " requires at most two arguments!"); } } $varTerm = $arrArgs[count($arrArgs) - 1]; if ($varTerm->isVariable) { if (!isset($parrVars[$varTerm->val])) { throw new Exception("Variable [" . $varTerm->val . "] not defined"); } else { $varTerm = $parrVars[$varTerm->val]; } } if (!$varTerm->isStringLiteral) { throw new Exception($varTmp . " operates on string type operands!"); } $opts = Toolset_Tokenizer::$EMPTY_STRING; if (count($arrArgs) == 2) { $opts = $arrArgs[0]; if ($opts->isVariable) { if (!isset($parrVars[$opts->val])) { throw new Exception("Variable [" . $opts->val . "] not defined"); } else { $opts = $parrVars[$opts->val]; } } if (!$opts->isStringLiteral) { throw new Exception($varTmp . " operates on string type operands!"); } } $pStack->Push(Toolset_Tokenizer::makeToken(Toolset_Functions::Regex($varTerm->val, $opts->val), Toolset_Tokenizer::$TOKEN_TYPE['REGEX'])); break; case "LCASE": case "UCASE": case "NUM": if (count($arrArgs) < 1) { throw new Exception($varTmp . " requires at least one argument!"); } else { if (count($arrArgs) > 1) { throw new Exception($varTmp . " requires only one argument!"); } } $varTerm = $arrArgs[0]; if ($varTerm->isVariable) { if (!isset($parrVars[$varTerm->val])) { throw new Exception("Variable [" . $varTerm->val . "] not defined"); } else { $varTerm = $parrVars[$varTerm->val]; } } if ($varTerm->isNumber) { $varTerm->val = (string) $varTerm->val; $varTerm->isStringLiteral = true; } if (!$varTerm->isStringLiteral && $varTmp != "NUM") { throw new Exception($varTmp . " requires a string type operand!"); } else { if ($varTmp == "LCASE") { $pStack->Push(Toolset_Tokenizer::makeToken(strtolower($varTerm->val), Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL'])); } else { if ($varTmp == "UCASE") { $pStack->Push(Toolset_Tokenizer::makeToken(strtoupper($varTerm->val), Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL'])); } else { if ($varTmp == "NUM") { $objTmp = Toolset_Tokenizer::toNumber($varTerm->val) + 0.0; if (is_nan($objTmp)) { throw new Exception($varTmp . " cannot convert [" . $varTerm->val . "] to number!"); } $pStack->Push(Toolset_Tokenizer::makeToken($objTmp, Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } } } } break; case "LEN": if (count($arrArgs) < 1) { throw new Exception($varTmp . " requires at least one argument!"); } else { if (count($arrArgs) > 1) { throw new Exception($varTmp . " requires only one argument!"); } } $varTerm = $arrArgs[0]; if ($varTerm->isVariable) { if (!isset($parrVars[$varTerm->val])) { throw new Exception("Variable [" . $varTerm->val . "] not defined"); } else { $varTerm = $parrVars[$varTerm->val]; } } if (!$varTerm->isArray && !$varTerm->isStringLiteral) { throw new Exception($varTmp . " requires a string or array type operand!"); } else { if ($varTerm->isStringLiteral) { $pStack->Push(Toolset_Tokenizer::makeToken(strlen($varTerm->val), Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } else { $pStack->Push(Toolset_Tokenizer::makeToken(count($varTerm->val), Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } } break; case "USER": if (count($arrArgs) < 1) { throw new Exception($varTmp . " requires at least one argument!"); } else { if (count($arrArgs) > 1) { throw new Exception($varTmp . " requires only one argument!"); } } $varTerm = $arrArgs[0]; if ($varTerm->isVariable) { if (!isset($parrVars[$varTerm->val])) { throw new Exception("Variable [" . $varTerm->val . "] not defined"); } else { $varTerm = $parrVars[$varTerm->val]; } } if (!$varTerm->isStringLiteral) { throw new Exception($varTmp . " requires a string type operand!"); } else { $pStack->Push(Toolset_Tokenizer::makeToken(Toolset_Functions::User($varTerm->val), Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL'])); } break; case "COOKIE": if (count($arrArgs) < 1) { throw new Exception($varTmp . " requires at least one argument!"); } else { if (count($arrArgs) > 1) { throw new Exception($varTmp . " requires only one argument!"); } } $varTerm = $arrArgs[0]; if ($varTerm->isVariable) { if (!isset($parrVars[$varTerm->val])) { throw new Exception("Variable [" . $varTerm->val . "] not defined"); } else { $varTerm = $parrVars[$varTerm->val]; } } if (!$varTerm->isStringLiteral) { throw new Exception($varTmp . " requires a string type operand!"); } else { $pStack->Push(Toolset_Tokenizer::makeToken(Toolset_Functions::Cookie($varTerm->val), Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL'])); } break; case "CONTAINS": if (count($arrArgs) < 2) { throw new Exception($varTmp . " requires at least two arguments!"); } else { if (count($arrArgs) > 2) { throw new Exception($varTmp . " requires only two arguments!"); } } $varTerm = $arrArgs[1]; if ($varTerm->isVariable) { if (!isset($parrVars[$varTerm->val])) { throw new Exception("Variable [" . $varTerm->val . "] not defined"); } else { $varTerm = $parrVars[$varTerm->val]; } } $varTerm2 = $arrArgs[0]; if ($varTerm2->isVariable) { if (!isset($parrVars[$varTerm2->val])) { throw new Exception("Variable [" . $varTerm2->val . "] not defined"); } else { $varTerm2 = $parrVars[$varTerm2->val]; } } if (!$varTerm->isArray) { throw new Exception($varTmp . " requires an array as first argument!"); } else { $found = Toolset_Functions::Contains($varTerm->val, $varTerm2->val); //in_array($varTerm2->val,$varTerm->val); $pStack->Push(Toolset_Tokenizer::makeToken($found, Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN'])); } break; case "DATE": if (count($arrArgs) < 2) { throw new Exception($varTmp . " requires at least two arguments!"); } else { if (count($arrArgs) > 2) { throw new Exception($varTmp . " requires only two arguments!"); } } $varTerm = $arrArgs[1]; if ($varTerm->isVariable) { if (!isset($parrVars[$varTerm->val])) { throw new Exception("Variable [" . $varTerm->val . "] not defined"); } else { $varTerm = $parrVars[$varTerm->val]; } } $varFormat = $arrArgs[0]; if ($varFormat->isVariable) { if (!isset($parrVars[$varFormat->val])) { throw new Exception("Variable [" . $varFormat->val . "] not defined"); } else { $varFormat = $parrVars[$varFormat->val]; } } $dateobj = array(); if (!$varTerm->isStringLiteral || !$varFormat->isStringLiteral) { throw new Exception($varTmp . " requires string type operands!"); } else { if (!Toolset_Tokenizer::isDate($varTerm->val, $varFormat->val, $dateobj)) { throw new Exception($varTmp . " can not convert [" . $varTerm->val . "] to a valid date with format [" . $varFormat->val . "]!"); } else { if (isset($dateobj['date'])) { $pStack->Push(Toolset_Tokenizer::makeToken($dateobj['date'], Toolset_Tokenizer::$TOKEN_TYPE['DATE'])); } else { throw new Exception($varTmp . " unknown error"); } } } break; case "empty": case "EMPTY": if (count($arrArgs) < 1) { throw new Exception($varTmp . " requires at least one argument!"); } else { if (count($arrArgs) > 1) { throw new Exception($varTmp . " requires only one arguments!"); } } $varFormat = $arrArgs[0]; if ($varFormat->isEmpty) { $pStack->Push(Toolset_Tokenizer::makeToken(true, Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN'])); } elseif ($varFormat->isStringLiteral && $varFormat->val === '') { $pStack->Push(Toolset_Tokenizer::makeToken(true, Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN'])); } elseif ($varFormat->isArray && count($varFormat->val) === 0) { $pStack->Push(Toolset_Tokenizer::makeToken(true, Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN'])); } elseif ($varFormat->isDate && !$varFormat->val) { $pStack->Push(Toolset_Tokenizer::makeToken(true, Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN'])); } else { $pStack->Push(Toolset_Tokenizer::makeToken(false, Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN'])); } break; case "LEFT": case "RIGHT": if (count($arrArgs) < 2) { throw new Exception($varTmp . " requires at least two arguments!"); } else { if (count($arrArgs) > 2) { throw new Exception($varTmp . " requires only two arguments!"); } } for ($intCntr = 0; $intCntr < count($arrArgs); $intCntr++) { $varTerm = $arrArgs[$intCntr]; if ($varTerm->isVariable) { if (!isset($parrVars[$varTerm->val])) { throw new Exception("Variable [" . $varTerm->val . "] not defined"); } else { $varTerm = $parrVars[$varTerm->val]; } } if ($varTerm->isNumber) { $arrArgs[1]->val = (string) $arrArgs[1]->val; $varTerm->isStringLiteral = true; } if ($intCntr == 0 && !$varTerm->isNumber) { throw new Exception($varTmp . " operator requires numeric length!"); } else { if ($intCntr == 1 && !$varTerm->isStringLiteral) { throw new Exception($varTmp . " operator requires a string operand!"); } } $arrArgs[$intCntr] = $varTerm; } $varTerm = $arrArgs[1]->val; $objTmp = Toolset_Tokenizer::toNumber($arrArgs[0]->val); if ($varTmp == "LEFT") { $pStack->Push(Toolset_Tokenizer::makeToken(substr($varTerm, 0, $objTmp), Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL'])); } else { $pStack->Push(Toolset_Tokenizer::makeToken(substr($varTerm, strlen($varTerm) - $objTmp, $objTmp), Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL'])); } break; case "MID": case "IIF": if (count($arrArgs) < 3) { throw new Exception($varTmp . " requires at least three arguments!"); } else { if (count($arrArgs) > 3) { throw new Exception($varTmp . " requires only three arguments!"); } } for ($intCntr = 0; $intCntr < count($arrArgs); $intCntr++) { $varTerm = $arrArgs[$intCntr]; if ($varTerm->isVariable) { if (!isset($parrVars[$varTerm->val])) { throw new Exception("Variable [" . $varTerm->val . "] not defined"); } else { $varTerm = $parrVars[$varTerm->val]; } } if ($varTerm->isNumber) { $arrArgs[2]->val = (string) $arrArgs[2]->val; $varTerm->isStringLiteral = true; } if ($varTmp == "MID" && $intCntr <= 1 && !$varTerm->isNumber) { throw new Exception($varTmp . " operator requires numeric lengths!"); } else { if ($varTmp == "MID" && $intCntr == 2 && !$varTerm->isStringLiteral) { throw new Exception($varTmp . " operator requires a string input!"); } } // else if ($varTmp == "IIF" && $intCntr == 2 && !$varTerm->isBoolean && !$varTerm->isNumber) // throw new Exception($varTmp . " operator requires boolean condition!"); $arrArgs[$intCntr] = $varTerm; } if ($varTmp == "MID") { $varTerm = $arrArgs[2]->val; $objOp1 = Toolset_Tokenizer::toNumber($arrArgs[1]->val); $objOp2 = Toolset_Tokenizer::toNumber($arrArgs[0]->val); $pStack->Push(Toolset_Tokenizer::makeToken(substr($varTerm, $objOp1, $objOp2 - $objOp1), Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL'])); } else { $varTerm = Toolset_Tokenizer::toBoolean($arrArgs[2]->val); if ($varTerm) { $objOp1 = $arrArgs[1]; } else { $objOp1 = $arrArgs[0]; } $pStack->Push($objOp1); } break; case "AVG": case "MAX": case "MIN": if (count($arrArgs) < 1) { throw new Exception($varTmp . " requires at least one operand!"); } $_arr = array(); $intCntr = count($arrArgs); while (--$intCntr >= 0) { $varTerm = $arrArgs[$intCntr]; if ($varTerm->isVariable) { if (!isset($parrVars[$varTerm->val])) { throw new Exception("Variable [" . $varTerm->val . "] not defined"); } else { $varTerm = $parrVars[$varTerm->val]; } } if (!$varTerm->isNumber && !$varTerm->isArray) { throw new Exception($varTmp . " requires numeric or array operands only!"); } if (!$varTerm->isArray) { $_arr = array_merge($_arr, Toolset_Tokenizer::toArray(Toolset_Tokenizer::toNumber($varTerm->val))); } else { $_arr = array_merge($_arr, $varTerm->val); } } $intCntr = -1; $objTmp = 0; while (++$intCntr < count($_arr)) { $varTerm = $_arr[$intCntr]; if ($varTmp == "AVG") { $objTmp += $varTerm; } else { if ($varTmp == "MAX") { if ($intCntr == 0) { $objTmp = $varTerm; } else { if ($objTmp < $varTerm) { $objTmp = $varTerm; } } } else { if ($varTmp == "MIN") { if ($intCntr == 0) { $objTmp = $varTerm; } else { if ($objTmp > $varTerm) { $objTmp = $varTerm; } } } } } } if ($varTmp == "AVG" && !empty($_arr)) { $pStack->Push(Toolset_Tokenizer::makeToken($objTmp / count($_arr), Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } else { if ($varTmp == "AVG") { $pStack->Push(Toolset_Tokenizer::makeToken(0, Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } else { $pStack->Push(Toolset_Tokenizer::makeToken($objTmp, Toolset_Tokenizer::$TOKEN_TYPE['NUMBER'])); } } unset($_arr); break; } }