* SPDX-License-Identifier: AGPL-3.0-only ************************************/ require_once("include/events/SqlResultIterator.inc"); class VTModuleExpressionsManager{ function __construct($adb){ $this->adb = $adb; } /** Caching logic **/ private static $cache = array(); static function addToCache($key, $value) { self::$cache[$key] = $value; } static function fromCache($key) { if(isset(self::$cache[$key])) return self::$cache[$key]; return false; } static function clearCache() { self::$cache = array(); } /** END **/ function retrieve($moduleName){ global $table_prefix; $adb = $this->adb; // Look at cache if we have the information $cachedinfo = self::fromCache($moduleName); if($cachedinfo === false) { $result = $adb->pquery('select * from '.$table_prefix.'_fieldformulas where modulename=?', array($moduleName)); if($adb->num_rows($result)==0){ self::addToCache($moduleName, array() ); }else{ $ee = unserialize(decode_html($adb->query_result($result, 0, "expression_engine"))); $id = $adb->query_result($result, 0, "expressionid"); self::addToCache($moduleName, array('expressionid'=>$id, 'expression_engine'=>$ee)); } // Retrieve information from cache for consistency $cachedinfo = self::fromCache($moduleName); } $me = new VTModuleExpressions($moduleName, new VTExpressionEngine()); if(!empty($cachedinfo)) { $me = new VTModuleExpressions($moduleName, $cachedinfo['expression_engine']); $me->id = $cachedinfo['expressionid']; } return $me; } function save($moduleExpressions){ global $table_prefix; $adb = $this->adb; if(isset($moduleExpressions->id)){ $adb->pquery('update '.$table_prefix.'_fieldformulas set expression_engine=? where expressionid=?', array(serialize($moduleExpressions->expressionEngine), $moduleExpressions->id)); }else{ $id = $adb->getUniqueId($table_prefix.'_fieldformulas'); $adb->pquery('insert into '.$table_prefix.'_fieldformulas (expressionid, modulename, expression_engine) values(?,?,?)', array($id, $moduleExpressions->moduleName, serialize($moduleExpressions->expressionEngine))); $moduleExpressions->id = $id; } // Invalidate cache information self::clearCache(); } function expressionFields($moduleName){ global $current_user; $result = vtws_describe($moduleName, $current_user); $fields = $result['fields']; $arr = array(); foreach($fields as $field){ //Use the field name to figure out the custom field if (substr($field['name'], 0, 3) === 'cf_' && // crmv@201026 in_array($field['type']['name'], array('text', 'string','integer', 'double'))){ $arr[$field['name']] = getTranslatedString($field['label'], $moduleName); } } return $arr; } function fields($moduleName){ global $current_user; $result = vtws_describe($moduleName, $current_user); $fields = $result['fields']; $arr = array(); foreach($fields as $field){ $arr[$field['name']] = $field['label']; } return $arr; } function expressionFunctions(){ return array('concat' => 'concat(a,b)', 'time_diffdays' => 'time_diffdays(a,b)', 'time_diff' => 'time_diff(a,b)'); } private function fieldNames($query, $moduleName){ $adb = $this->adb; $result = $adb->pquery($query, array($moduleName)); $it = new SqlResultIterator($adb, $result); $arr = array(); foreach($it as $row){ $arr[$row->fieldname]=$row->fieldlabel; } return $arr; } function expressionsForModule($moduleName){ return $this->retrieve($moduleName)->asArray(); } } class VTModuleExpressions{ function __construct($moduleName, $expressionEngine){ $this->moduleName=$moduleName; $this->expressionEngine=$expressionEngine; } function add($fieldName, $expression){ try{ $this->expressionEngine->loadExpressions(array($fieldName=>$expression)); $this->state='savable'; }catch(VTExpressionException $e){ $this->state='error'; $this->message=$e->getMessage(); } } function remove($fieldName){ $this->expressionEngine->removeExpression($fieldName); } function asArray(){ return $this->expressionEngine->unparsedExpressions; } function parseExpression($expr){ $parser = new VTParser(new SpaceFilter(new VTTokenizer($expr))); return $parser->expression(); } function update($entity){ $bound = $this->expressionEngine->evaluate($entity->getData()); foreach($bound as $field => $value){ $entity->set($field, $value); } } function getFieldsFromExpr($expr){ function __getFieldsFromExpr($expr, &$arr){ switch(get_class($expr)){ case 'VTTreeNode': $params = $expr->getParams(); foreach($params as $param){ __vtGetFieldsFromExpr($param, $arr); } return; case 'Symbol': $arr[$expr->value] = $expr; return; default: return; } } __vtGetFieldsFromExpr($expr, $arr); return array_keys($arr); } } ?>