- Added comprehensive AI Assistant system (aiassist/ directory): * Vector search and embedding capabilities * Typebot proxy integration * Elastic search functionality * Message classification and chat history * MCP proxy for external integrations - Implemented Court Status API (GetCourtStatus.php): * Real-time court document status checking * Integration with external court systems * Comprehensive error handling and logging - Enhanced S3 integration: * Improved file backup system with metadata * Batch processing capabilities * Enhanced error logging and recovery * Copy operations with URL fixing - Added Telegram contact creation API - Improved error logging across all modules - Enhanced callback system for AI responses - Extensive backup file storage with timestamps - Updated documentation and README files - File storage improvements: * Thousands of backup files with proper metadata * Fix operations for broken file references * Project-specific backup and recovery systems * Comprehensive file integrity checking Total: 26,461+ files added/modified including AWS SDK, vendor dependencies, and extensive backup system.
178 lines
5.3 KiB
PHP
178 lines
5.3 KiB
PHP
<?php
|
|
/**
|
|
* Created by PhpStorm.
|
|
* User: Stefan
|
|
* Date: 06.04.2016
|
|
* Time: 19:06
|
|
*/
|
|
|
|
namespace Workflow;
|
|
|
|
|
|
class Formula
|
|
{
|
|
private $_formulaId = 0;
|
|
/**
|
|
* @var VTEntity
|
|
*/
|
|
private $_context = null;
|
|
|
|
private $_data = array();
|
|
|
|
private $_formula = '';
|
|
private $_variables = array();
|
|
|
|
private static $EvalAllowed = -1;
|
|
|
|
public function __construct($formulaId, VTEntity $context) {
|
|
$this->_formulaId = intval($formulaId);
|
|
$this->_context = $context;
|
|
|
|
$adb = \PearDatabase::getInstance();
|
|
|
|
$sql = 'SELECT * FROM vtiger_wf_formulas WHERE id = ?';
|
|
$result = $adb->pquery($sql, array($this->_formulaId));
|
|
|
|
if($adb->num_rows($result) == 0) {
|
|
throw new \Exception('Formula '.$this->_formulaId.' not found!');
|
|
}
|
|
|
|
$this->_data = $adb->fetchByAssoc($result);
|
|
|
|
$this->_formula = $this->_data['formula'];
|
|
$this->_variables = unserialize(html_entity_decode($this->_data['variables']));
|
|
}
|
|
|
|
/**
|
|
* @return mixed
|
|
*/
|
|
public function getResult() {
|
|
foreach($this->_variables as $var => $value) {
|
|
$this->_variables[$var] = floatval(VTTemplate::parse($value, $this->_context));
|
|
}
|
|
|
|
$this->_prepareFunction();
|
|
$this->_checkSyntax();
|
|
|
|
$result = eval('return '.$this->_formula.';');
|
|
|
|
return $result;
|
|
}
|
|
|
|
private function isEvalAllowed() {
|
|
if(self::$EvalAllowed !== -1) {
|
|
return self::$EvalAllowed;
|
|
}
|
|
|
|
if(!function_exists("ini_get")) {
|
|
self::$EvalAllowed = false;
|
|
return self::$EvalAllowed;
|
|
}
|
|
|
|
if(ini_get("suhosin.executor.disable_eval") == "1") {
|
|
self::$EvalAllowed = false;
|
|
return self::$EvalAllowed;
|
|
}
|
|
|
|
$check = ini_get("disable_functions")." ".ini_get("suhosin.executor.func.blacklist");
|
|
|
|
if(strpos($check, "eval") !== false) {
|
|
self::$EvalAllowed = false;
|
|
return self::$EvalAllowed;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
private function _checkSyntax() {
|
|
if(substr_count($this->_formula, '(') != substr_count($this->_formula, ')')) {
|
|
throw new \Exception('Opening and Closing Brakets are not correct in this Formula: '.$this->_formula);
|
|
}
|
|
|
|
$inString = @ini_set('log_errors', false);
|
|
$token = @ini_set('display_errors', true);
|
|
ob_start();
|
|
|
|
// If $braces is not zero, then we are sure that $code is broken.
|
|
// We run it anyway in order to catch the error message and line number.
|
|
|
|
// Else, if $braces are correctly balanced, then we can safely put
|
|
// $code in a dead code sandbox to prevent its execution.
|
|
// Note that without this sandbox, a function or class declaration inside
|
|
// $code could throw a "Cannot redeclare" fatal error.
|
|
|
|
#$code = html_entity_decode(htmlspecialchars_decode($code, ENT_NOQUOTES), ENT_NOQUOTES, "UTF-8");
|
|
#var_dump(htmlentities($code, ENT_QUOTES, "UTF-8"), htmlentities( ' return $env[\'url\']; ', ENT_QUOTES, "UTF-8"));
|
|
$code = "if(0){{$this->_formula};\n}";
|
|
|
|
// If eval not allowed, don't execute this
|
|
if(!$this->isEvalAllowed()) {
|
|
throw new \Exception('Formula calculations require the eval feature of PHP. Ask your system administrator!');
|
|
}
|
|
|
|
if (false === eval($code))
|
|
{
|
|
#var_dump(str_replace("&", "-", $code), htmlentities($code, ENT_NOQUOTES, "UTF-8"));exit();
|
|
if ($braces) $braces = PHP_INT_MAX;
|
|
else
|
|
{
|
|
// Get the maximum number of lines in $code to fix a border case
|
|
false !== strpos($code, "\r") && $code = strtr(str_replace("\r\n", "\n", $code), "\r", "\n");
|
|
$braces = substr_count($code, "\n");
|
|
}
|
|
|
|
$code = ob_get_clean();
|
|
$code = strip_tags($code);
|
|
|
|
// Get the error message and line number
|
|
if (preg_match("'syntax error, (.+) in .+ on line (\d+)'s", $code, $code))
|
|
{
|
|
$code[2] = (int) $code[2];
|
|
$code = $code[2] <= $braces
|
|
? array($code[1], $code[2])
|
|
: array('unexpected $end' . substr($code[1], 14), $braces);
|
|
}
|
|
else $code = array('syntax error', 0);
|
|
|
|
$oldHandler = set_error_handler('var_dump', 0);
|
|
@$undef_var;
|
|
if(!empty($oldHandler)) {
|
|
set_error_handler($oldHandler);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
ob_end_clean();
|
|
$code = false;
|
|
}
|
|
|
|
@ini_set('display_errors', $token);
|
|
@ini_set('log_errors', $inString);
|
|
|
|
if($code !== false) {
|
|
throw new \Exception('Error in Formular '.$this->_formula);
|
|
}
|
|
}
|
|
|
|
private function _prepareFunction() {
|
|
$this->_formula = preg_replace_callback('/[a-zA-Z0-9]+/', array($this, '_replaceFormula'), $this->_formula);
|
|
|
|
$this->_formula = preg_replace('/[^0-9\.\+\-\*\/%\*\(\)]/', '', $this->_formula);
|
|
}
|
|
|
|
private function _replaceFormula($match) {
|
|
if(is_numeric($match[0])) {
|
|
return $match[0];
|
|
}
|
|
|
|
if(!isset($this->_variables[$match[0]])) {
|
|
return '';
|
|
}
|
|
|
|
return $this->_variables[$match[0]];
|
|
}
|
|
|
|
|
|
|
|
|
|
} |