• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List

E:/E/GEAMP/www/openbiz/openbiz/bin/Expression.php

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         // replace [field] with field value
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                 // get field value
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                 //$script .= substr($expression, $pos0, $pos1 - $pos0);
00072                 //return "fail to evaluate $expression";
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         // replace [field] with field value
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                 // get field value
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                 //$script .= substr($expression, $pos0, $pos1 - $pos0);
00123                 //return "fail to evaluate $expression";
00124                     return $expression;  // return the original expression once it can't find element
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         // read service symbols from global var.
00148         if (isset($g_ServiceAlias) && empty(self::$services))
00149             self::$services = $g_ServiceAlias;
00150 
00151         // replace @objname:property to GetObject()->getProperty(property)
00152         while (true)
00153         {
00154         // TODO: one clause must be separated by whitespace
00155         //modified by jixian for support package full name of a object
00156         //e.g : shared.objects.compaines.objCompany:Field[Id].Value
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             {  // @profile:attribute is reserved
00164                 $profileAttribute = BizSystem::getUserProfile($propExpr);
00165                 $expression = str_replace($macro, $profileAttribute, $expression);
00166                 continue;
00167             }
00168             if ($objName == "home")
00169             {  // @home:url is reserved
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             { // reserved keywords
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             { // in case of @objname:field[fldname].property
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 // in case of @objname:property
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         // replace macro @var:key to $userProfile[$key]
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             // throw error
00264             $expression = str_replace($macro, $val, $expression);
00265         }
00266         return $expression;
00267     }
00268 
00288     public static function evaluateExpression($expression, $object)
00289     {
00290     // TODO: check if it's "\[", "\]", "\{" or "\}"
00291         $script = "";
00292         $start = 0;
00293 
00294         if (strpos($expression, "{", $start) === false)    // do nothing if no { symbol
00295             return $expression;
00296 
00297         if($expression=="{@}"){
00298               return $object;
00299         }
00300         // evaluate the expression between {}
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                     //BizSystem::log(LOG_DEBUG, "EXPRESSION", "###expression 1: ".$section."");
00318                     $section = Expression::replaceVarExpr($section, $object);  // replace variable expr;
00319                     //BizSystem::log(LOG_DEBUG, "EXPRESSION", "###expression 2: ".$section.""); 
00320                     if ($_section == $section) {
00321                         if ((is_subclass_of($object, "BizDataObj") || get_class($object)=="BizDataObj") AND strstr($section, '['))
00322                             $section = Expression::replaceFieldsExpr($section, $object);  // replace [field] with its value
00323 
00324                         if ((is_subclass_of($object, "EasyForm")|| get_class($object)=="EasyForm") AND strstr($section, '['))
00325                             $section = Expression::replaceElementsExpr($section, $object);  // replace [field] with its value
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                     //if (Expression::eval_syntax("\$ret = $section;"))
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; // Unbalanced braces would break the eval below
00385         else
00386         {
00387             ob_start(); // Catch potential parse error messages
00388            // if(preg_match("/.*?\= '.*?'/si",$code)){
00389             //if(!preg_match("/,/si",$code) && !preg_match("/\//si",$code)){
00390             //if( !preg_match("/\//si",$code)){
00391                      $r = eval('if(0){' . $code . '}'); // Put $code in a dead code sandbox to prevent its execution
00392             //}else{
00393             //       return false;
00394             //}
00395             $error = ob_get_contents();
00396             if ($r === false)
00397             {
00398             //trigger_error("EVAL: $code ".$error, E_USER_ERROR);
00399             //BizSystem::log(LOG_ERR, "ERROR", "EVAL: $code. ".$error);
00400             }
00401             ob_end_clean();
00402 
00403             return false !== $r;
00404         }
00405     }
00406 
00407 }
00408 
00409 ?>

Generated on Thu Apr 19 2012 17:09:13 for openbiz by  doxygen 1.7.2