/**
* {@inheritdoc}
*
* @param EvaluatedValue $value
*
* @throws UnresolvableValueException
*/
public function resolve(ValueInterface $value, FixtureInterface $fixture, ResolvedFixtureSet $fixtureSet, array $scope, GenerationContext $context) : ResolvedValueWithFixtureSet
{
// Scope exclusive to the evaluated expression
// We make use of the underscore prefix (`_`) here to limit the possible conflicts with the variables injected
// in the scope.
$_scope = $scope;
try {
$_scope['current'] = $fixture->getValueForCurrent();
} catch (NoValueForCurrentException $exception) {
// Continue
}
$expression = $this->replacePlaceholders($value->getValue());
// Closure in which the expression is evaluated; This is done in a closure to avoid the expression to have
// access to this method variables (which should remain unknown) and we injected only the variables of the
// closure.
$evaluateExpression = function ($_expression) use($_scope) {
foreach ($_scope as $_scopeVariableName => $_scopeVariableValue) {
${$_scopeVariableName} = $_scopeVariableValue;
}
return eval("return {$_expression};");
};
try {
$evaluatedExpression = $evaluateExpression($expression);
} catch (\Throwable $throwable) {
throw UnresolvableValueExceptionFactory::createForCouldNotEvaluateExpression($value, 0, $throwable);
}
return new ResolvedValueWithFixtureSet($evaluatedExpression, $fixtureSet);
}