00001 <?PHP
00026 class Expression
00027 {
00028 static protected $services = array();
00029 static protected $expContainers = array('{fx}'=>'{/fx}','{tx}'=>'{/tx}','{'=>'}');
00030
00031 function __construct(&$xmlArr)
00032 {
00033 }
00034
00042 protected static function replaceFieldsExpr($expression, $bizObj)
00043 {
00044 $script = "";
00045 $start = 0;
00046
00047
00048 while (true)
00049 {
00050 $pos0 = strpos($expression, "[", $start);
00051 $pos1 = strpos($expression, "]", $start);
00052 if ($pos0 === false)
00053 {
00054 $script .= substr($expression, $start);
00055 break;
00056 }
00057 if ($pos0 >= 0 && $pos1 > $pos0)
00058 {
00059 $script .= substr($expression, $start, $pos0 - $start);
00060 $start = $pos1 + 1;
00061 $fieldName = substr($expression, $pos0 + 1, $pos1 - $pos0-1);
00062
00063 $fieldValue = $bizObj->getField($fieldName)->m_Value;
00064 if ($fieldValue == null)
00065 $fieldValue = $bizObj->getFieldValue($fieldName);
00066
00067 if ($fieldValue !== null)
00068 $script .= $fieldValue;
00069 else
00070 {
00071
00072
00073 return "";
00074 }
00075 }
00076 elseif ($pos0 >= 0 && $pos1 <= $pos0)
00077 break;
00078 }
00079 return $script;
00080 }
00081
00089 protected static function replaceElementsExpr($expression, $formObj)
00090 {
00091 $script = "";
00092 $start = 0;
00093
00094
00095 while (true)
00096 {
00097 $pos0 = strpos($expression, "[", $start);
00098 $pos1 = strpos($expression, "]", $start);
00099 if ($pos0 === false)
00100 {
00101 $script .= substr($expression, $start);
00102 break;
00103 }
00104 if ($pos0 >= 0 && $pos1 > $pos0)
00105 {
00106 $script .= substr($expression, $start, $pos0 - $start);
00107 $start = $pos1 + 1;
00108 $elementName = substr($expression, $pos0 + 1, $pos1 - $pos0-1);
00109
00110 $element = $formObj->getElement($elementName);
00111 if($element)
00112 {
00113 $fldval = $element->getValue();
00114 }else
00115 {
00116 $fldval = null;
00117 }
00118 if ($fldval !== null)
00119 $script .= $fldval;
00120 else
00121 {
00122
00123
00124 return $expression;
00125 }
00126 }
00127 elseif ($pos0 >= 0 && $pos1 <= $pos0)
00128 break;
00129 }
00130 return $script;
00131 }
00132
00133
00144 protected static function replaceVarExpr($expression, $object)
00145 {
00146 global $g_ServiceAlias;
00147
00148 if (isset($g_ServiceAlias) && empty(self::$services))
00149 self::$services = $g_ServiceAlias;
00150
00151
00152 while (true)
00153 {
00154
00155
00156
00157 $pattern = "/@([[a-zA-Z0-9_\.]*):([a-zA-Z0-9_\.\[\]]+)/";
00158 if (!preg_match($pattern, $expression, $matches)) { break; }
00159 $macro = $matches[0];
00160 $objName = $matches[1]; $propExpr = $matches[2];
00161 $obj = null;
00162 if ($objName == "profile")
00163 {
00164 $profileAttribute = BizSystem::getUserProfile($propExpr);
00165 $expression = str_replace($macro, $profileAttribute, $expression);
00166 continue;
00167 }
00168 if ($objName == "home")
00169 {
00170 switch($propExpr){
00171 case "url":
00172 $value = "'".APP_INDEX."'";
00173 break;
00174 case "base_url":
00175 $value = "'".APP_URL."'";
00176 break;
00177 }
00178 $expression = str_replace($macro, $value, $expression);
00179 continue;
00180 }
00181 elseif (in_array($objName, array_keys(Expression::$services)))
00182 {
00183 $body = $expression;
00184 $objFunc = '@'.$objName.':'.$propExpr;
00185 $posStart = strpos($body, $objFunc);
00186 $beforeString = substr($body, 0, $posStart);
00187 $paramStart = strpos($body, $objFunc.'(') + strlen($objFunc.'(');
00188 $paramEnd = strpos($body, ')', $paramStart);
00189 $paramLen = $paramEnd-$paramStart;
00190 $function = $propExpr;
00191 $paramString = substr($body, $paramStart, $paramLen);
00192 $restString = substr($body, $paramEnd + 1);
00193
00194 $paramString = Expression::evaluateExpression('{'.$paramString.'}', $object);
00195 $serviceName = Expression::$services[$objName];
00196 $serviceObj = BizSystem::getService($serviceName);
00197
00198 $params = explode(',', $paramString);
00199 for ($i=0; $i < count($params); $i++)
00200 $params[$i] = trim($params[$i]);
00201 $val_result = call_user_func_array(array($serviceObj, $function), $params);
00202 return $beforeString . $val_result . $restString;
00203 }
00204
00205 elseif ($objName == "" || $objName == "this")
00206 $obj = $object;
00207 else
00208 $obj = BizSystem::getObject($objName);
00209
00210 if ($obj == null)
00211 {
00212 throw new Exception("Wrong expression syntax ".$expression.", cannot get object ".$objName);
00213 }
00214
00215 $pos = strpos($propExpr, ".");
00216 if ($pos>0)
00217 {
00218 $property1 = substr($propExpr,0,$pos);
00219 $property2 = substr($propExpr,$pos+1);
00220 $propertyObj = $obj->getProperty($property1);
00221 if ($propertyObj == null)
00222 {
00223 $propertyObj = $obj->getDataObj()->getProperty($property1);
00224 if($propertyObj == null){
00225 throw new Exception("Wrong expression syntax ".$expression.", cannot get property object ".$property1." of object ".$objName);
00226 }else{
00227 $val = $propertyObj->getProperty($property2);
00228
00229 }
00230 }
00231 $val = $propertyObj->getProperty($property2);
00232 }
00233 else
00234 $val = $obj->getProperty($propExpr);
00235 if ($val === null) $val = "";
00236 if (is_string($val))
00237 $val = "'$val'";
00238 $expression = str_replace($macro, $val, $expression);
00239 }
00240 return $expression;
00241 }
00242
00252 protected static function replaceMacrosExpr($expression)
00253 {
00254
00255 while (true)
00256 {
00257 $pattern = "/@(\w+):(\w+)/";
00258 if (!preg_match($pattern, $expression, $matches)) break;
00259 $macro = $matches[0];
00260 $macro_var = $matches[1]; $macro_key = $matches[2];
00261 $val = BizSystem::getMacroValue($macro_var, $macro_key);
00262 if (!$val) $val = "";
00263
00264 $expression = str_replace($macro, $val, $expression);
00265 }
00266 return $expression;
00267 }
00268
00288 public static function evaluateExpression($expression, $object)
00289 {
00290
00291 $script = "";
00292 $start = 0;
00293
00294 if (strpos($expression, "{", $start) === false)
00295 return $expression;
00296
00297 if($expression=="{@}"){
00298 return $object;
00299 }
00300
00301 while (true)
00302 {
00303 list($tag,$pos0,$pos1) = self::getNextContainerPos($expression, $start);
00304 if ($pos0 === false)
00305 {
00306 if (substr($expression, $start))
00307 $script .= substr($expression, $start);
00308 break;
00309 }
00310 if ($pos0 >= 0 && $pos1 > $pos0)
00311 {
00312 $script .= substr($expression, $start, $pos0 - $start);
00313 $start = $pos1 + strlen(self::$expContainers[$tag]);
00314 $section = substr($expression, $pos0 + strlen($tag), $pos1 - $pos0 - strlen($tag));
00315 $_section = $section;
00316 if ($object) {
00317
00318 $section = Expression::replaceVarExpr($section, $object);
00319
00320 if ($_section == $section) {
00321 if ((is_subclass_of($object, "BizDataObj") || get_class($object)=="BizDataObj") AND strstr($section, '['))
00322 $section = Expression::replaceFieldsExpr($section, $object);
00323
00324 if ((is_subclass_of($object, "EasyForm")|| get_class($object)=="EasyForm") AND strstr($section, '['))
00325 $section = Expression::replaceElementsExpr($section, $object);
00326 }
00327 }
00328 if ($section === false)
00329 $script = ($script == '') ? $section : ($script . $section);
00330 if ($section != null AND trim($section) != "" AND $section != false)
00331 {
00332 $ret == null;
00333
00334 if (($tag == '{fx}' || $tag == '{') && Expression::eval_syntax("\$ret = $section;"))
00335 {
00336 eval ("\$ret = $section;");
00337 }
00338 if ($ret === null)
00339 $ret = $section;
00340 $script = ($script == '') ? $ret : ($script . $ret);
00341 unset($ret);
00342 }
00343 }
00344 elseif ($pos0 >= 0 && $pos1 <= $pos0)
00345 break;
00346 }
00347 return $script;
00348 }
00349
00350 protected static function getNextContainerPos($expression, &$start)
00351 {
00352 foreach (self::$expContainers as $left=>$right)
00353 {
00354 $pos0 = strpos($expression, $left, $start);
00355 $pos1 = strpos($expression, $right, $start);
00356 if ($pos0 === false)
00357 continue;
00358 if ($pos0 >= 0 && $pos1 > $pos0)
00359 return array($left, $pos0, $pos1);
00360 if ($pos0 >= 0 && $pos1 <= $pos0)
00361 trigger_error("Incorrect Expression - no matching end tag $right for $left.", E_USER_ERROR);
00362 }
00363 return array(null,false,false);
00364 }
00365
00374 public static function eval_syntax($code)
00375 {
00376 $b = 0;
00377
00378 foreach (token_get_all($code) as $token)
00379 {
00380 if ('{' == $token) ++$b;
00381 else if ('}' == $token) --$b;
00382 }
00383
00384 if ($b) return false;
00385 else
00386 {
00387 ob_start();
00388
00389
00390
00391 $r = eval('if(0){' . $code . '}');
00392
00393
00394
00395 $error = ob_get_contents();
00396 if ($r === false)
00397 {
00398
00399
00400 }
00401 ob_end_clean();
00402
00403 return false !== $r;
00404 }
00405 }
00406
00407 }
00408
00409 ?>