. */ declare(strict_types=1); namespace FireflyIII\TransactionRules\Expressions; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; use Symfony\Component\ExpressionLanguage\SyntaxError; class ActionExpression { private static array $NAMES = array("transaction"); private ExpressionLanguage $expressionLanguage; private string $expr; private bool $isExpression; private ?SyntaxError $validationError; public function __construct(string $expr) { $this->expressionLanguage = app(ExpressionLanguage::class); $this->expr = $expr; $this->isExpression = self::isExpression($expr); $this->validationError = $this->validate(); } private static function isExpression(string $expr): bool { return str_starts_with($expr, "="); } private function validate(): ?SyntaxError { if (!$this->isExpression) { return null; } try { $this->lint(); return null; } catch (SyntaxError $e) { return $e; } } private function lintExpression(string $expr): void { $this->expressionLanguage->lint($expr, self::$NAMES); } private function lint(): void { if (!$this->isExpression) { return; } $this->lintExpression(substr($this->expr, 1)); } public function isValid(): bool { return $this->validationError === null; } public function getValidationError() { return $this->validationError; } private function evaluateExpression(string $expr, array $journal): string { $result = $this->expressionLanguage->evaluate($expr, [ "transaction" => $journal ]); return strval($result); } public function evaluate(array $journal): string { if (!$this->isExpression) { return $this->expr; } return $this->evaluateExpression(substr($this->expr, 1), $journal); } }