/** * {@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); }
/** * @inheritdoc */ public function getValueForCurrent() { return $this->fixture->getValueForCurrent(); }
/** * @param FixtureInterface $fixture * * @return string */ public static function current(FixtureInterface $fixture) { return $fixture->getValueForCurrent(); }