/** * @test * @dataProvider getSomeEvaluationTestValues * @param string $comparison * @param boolean $expected */ public function testSomeEvaluations($comparison, $expected, $variables = array()) { $parser = new BooleanParser(); $this->assertEquals($expected, BooleanNode::convertToBoolean($parser->evaluate($comparison, $variables), $this->renderingContext), 'Expression: ' . $comparison); $compiledEvaluation = $parser->compile($comparison); $functionName = 'expression_' . md5($comparison . rand(0, 100000)); eval('function ' . $functionName . '($context) {return ' . $compiledEvaluation . ';}'); $this->assertEquals($expected, BooleanNode::convertToBoolean($functionName($variables), $this->renderingContext), 'compiled Expression: ' . $compiledEvaluation); }
/** * Takes a stack of nodes evaluates it with the end result * being a single boolean value. Creates new BooleanNodes * recursively to process braced expressions as single units. * * @param RenderingContextInterface $renderingContext * @param array $expressionParts * @return boolean the boolean value */ public static function evaluateStack(RenderingContextInterface $renderingContext, array $expressionParts) { $expression = static::reconcatenateExpression($expressionParts); $context = static::gatherContext($renderingContext, $expressionParts); $parser = new BooleanParser(); return static::convertToBoolean($parser->evaluate($expression, $context), $renderingContext); }
/** * @param BooleanNode $node * @return array * @see convert() */ protected function convertBooleanNode(BooleanNode $node) { $stack = $this->convertArrayNode(new ArrayNode($node->getStack())); $initializationPhpCode = '// Rendering Boolean node' . chr(10); $initializationPhpCode .= $stack['initialization'] . chr(10); $parser = new BooleanParser(); $compiledExpression = $parser->compile(BooleanNode::reconcatenateExpression($node->getStack())); $functionName = $this->variableName('expression'); $initializationPhpCode .= $functionName . ' = function($context) {return ' . $compiledExpression . ';};' . chr(10); return array('initialization' => $initializationPhpCode, 'execution' => sprintf('%s::convertToBoolean( %s( %s::gatherContext($renderingContext, %s) ), $renderingContext )', BooleanNode::class, $functionName, BooleanNode::class, $stack['execution'])); }
/** * Compiles the ExpressionNode, returning an array with * exactly two keys which contain strings: * * - "initialization" which contains variable initializations * - "execution" which contains the execution (that uses the variables) * * The expression and matches can be read from the local * instance - and the RenderingContext and other APIs * can be accessed via the TemplateCompiler. * * @param TemplateCompiler $templateCompiler * @return string */ public function compile(TemplateCompiler $templateCompiler) { $parts = preg_split('/([\\?:])/s', $this->getExpression()); $parts = array_map([__CLASS__, 'trimPart'], $parts); list($check, $then, $else) = $parts; $matchesVariable = $templateCompiler->variableName('array'); $initializationPhpCode = '// Rendering TernaryExpression node' . chr(10); $initializationPhpCode .= sprintf('%s = %s;', $matchesVariable, var_export($this->getMatches(), true)) . chr(10); $parser = new BooleanParser(); $compiledExpression = $parser->compile($check); $functionName = $templateCompiler->variableName('ternaryExpression'); $initializationPhpCode .= sprintf('%s = function($context, $renderingContext) { if (%s::convertToBoolean(' . $compiledExpression . ', $renderingContext) === TRUE) { return %s::getTemplateVariableOrValueItself(%s, $renderingContext); } else { return %s::getTemplateVariableOrValueItself(%s, $renderingContext); } };' . chr(10), $functionName, BooleanNode::class, static::class, var_export($then, true), static::class, var_export($else, true)); return ['initialization' => $initializationPhpCode, 'execution' => sprintf('%s(%s::gatherContext($renderingContext, %s[1]), $renderingContext)', $functionName, static::class, $matchesVariable)]; }