Add a custom variable validator + protected props (#98)

This commit is contained in:
Matthijs Meulenbrug 2022-04-25 16:50:51 +02:00 committed by GitHub
parent a0ff7a79af
commit ef82911187
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 10 deletions

View file

@ -31,27 +31,32 @@ class MathExecutor
*
* @var array<string, float|string>
*/
private $variables = [];
protected $variables = [];
/**
* @var callable|null
*/
private $onVarNotFound = null;
protected $onVarNotFound = null;
/**
* @var callable|null
*/
protected $onVarValidation = null;
/**
* @var Operator[]
*/
private $operators = [];
protected $operators = [];
/**
* @var array<string, CustomFunction>
*/
private $functions = [];
protected $functions = [];
/**
* @var array<string, Token[]>
*/
private $cache = [];
protected $cache = [];
/**
* Base math operators
@ -74,6 +79,8 @@ class MathExecutor
foreach ($this->defaultFunctions() as $name => $callable) {
$this->addFunction($name, $callable);
}
$this->onVarValidation = [$this, 'defaultVarValidation'];
$this->variables = $this->defaultVars();
}
@ -507,21 +514,35 @@ class MathExecutor
}
/**
* Add variable to executor
* Add variable to executor. To set a custom validator use setVarValidationHandler.
*
* @param string $variable
* @param int|float $value
* @param $value
* @return MathExecutor
* @throws MathExecutorException if the value is invalid based on the default or custom validator
*/
public function setVar(string $variable, $value): self
{
if ($this->onVarValidation) {
call_user_func($this->onVarValidation, $variable, $value);
}
$this->variables[$variable] = $value;
return $this;
}
/**
* Default variable validation, ensures that the value is a scalar.
* @param string $variable
* @param $value
* @throws MathExecutorException if the value is not a scalar
*/
protected function defaultVarValidation(string $variable, $value): void
{
if (!is_scalar($value) && $value !== null) {
$type = gettype($value);
throw new MathExecutorException("Variable ({$variable}) type ({$type}) is not scalar");
}
$this->variables[$variable] = $value;
return $this;
}
/**
@ -567,6 +588,21 @@ class MathExecutor
return $this;
}
/**
* Define a validation method that will be invoked when a variable is set using setVar.
* The first parameter will be the variable name, and the second will be the variable value.
* Set to null to disable validation.
*
* @param ?callable $handler throws a MathExecutorException in case of an invalid variable
*
* @return MathExecutor
*/
public function setVarValidationHandler(?callable $handler): self
{
$this->onVarValidation = $handler;
return $this;
}
/**
* Remove variable from executor
*

View file

@ -589,6 +589,21 @@ class MathTest extends TestCase
$calculator->setVar('resource', tmpfile());
}
public function testSetCustomVarValidator()
{
$calculator = new MathExecutor();
$calculator->setVarValidationHandler(function ($name, $variable) {
if ($name === 'invalidVar' && $variable === 'invalid') {
throw new MathExecutorException("Invalid variable");
}
});
$calculator->setVar('valid', $this);
$this->expectException(MathExecutorException::class);
$calculator->setVar('invalidVar', 'invalid');
}
public function testVarExists()
{
$calculator = new MathExecutor();