Esempio n. 1
0
 /**
  * @test
  */
 public function testEvaluateCallsInvoker()
 {
     $invoker = $this->getMock(ViewHelperInvoker::class, ['invoke']);
     $invoker->expects($this->once())->method('invoke')->willReturn('test');
     $this->renderingContext->setViewHelperInvoker($invoker);
     $node = new ViewHelperNode($this->renderingContext, 'f', 'vh', ['foo' => 'bar'], new ParsingState());
     $result = $node->evaluate($this->renderingContext);
     $this->assertEquals('test', $result);
 }
Esempio n. 2
0
 /**
  * @test
  */
 public function processReenablesEscapingInterceptorOnClosingViewHelperTagIfItWasDisabledBefore()
 {
     $interceptorPosition = InterceptorInterface::INTERCEPT_CLOSING_VIEWHELPER;
     $this->mockViewHelper->expects($this->any())->method('isOutputEscapingEnabled')->will($this->returnValue(false));
     $this->mockNode->expects($this->any())->method('getUninitializedViewHelper')->will($this->returnValue($this->mockViewHelper));
     $this->escapeInterceptor->_set('childrenEscapingEnabled', false);
     $this->escapeInterceptor->_set('viewHelperNodesWhichDisableTheInterceptor', [$this->mockNode]);
     $this->escapeInterceptor->process($this->mockNode, $interceptorPosition, $this->mockParsingState);
     $this->assertTrue($this->escapeInterceptor->_get('childrenEscapingEnabled'));
 }
Esempio n. 3
0
 /**
  * @test
  */
 public function testEvaluateCallsInvoker()
 {
     $resolver = $this->getMock('TYPO3Fluid\\Fluid\\Core\\ViewHelper\\ViewHelperResolver', array('resolveViewHelperInvoker'));
     $invoker = $this->getMock('TYPO3Fluid\\Fluid\\Core\\ViewHelper\\ViewHelperInvoker', array('invoke'), array($resolver));
     $resolver->expects($this->once())->method('resolveViewHelperInvoker')->willReturn($invoker);
     $invoker->expects($this->once())->method('invoke')->willReturn('test');
     $node = new ViewHelperNode($resolver, 'f', 'count', array(), new ParsingState());
     $context = new RenderingContext();
     $context->setViewHelperResolver($resolver);
     $result = $node->evaluate($context);
     $this->assertEquals('test', $result);
 }
 /**
  * @test
  * @dataProvider getCompileTestValues
  * @param array $childNodes
  * @param $expected
  */
 public function testCompileReturnsAndAssignsExpectedVariables(array $childNodes, $expected)
 {
     $node = new ViewHelperNode(new ViewHelperResolver(), 'f', 'if', array(), new ParsingState());
     foreach ($childNodes as $childNode) {
         $node->addChildNode($childNode);
     }
     $compiler = $this->getMock('TYPO3Fluid\\Fluid\\Core\\Compiler\\TemplateCompiler', array('wrapChildNodesInClosure', 'wrapViewHelperNodeArgumentEvaluationInClosure'));
     $compiler->expects($this->any())->method('wrapChildNodesInClosure')->willReturn('closure');
     $compiler->expects($this->any())->method('wrapViewHelperNodeArgumentEvaluationInClosure')->willReturn('arg-closure');
     $init = '';
     $this->viewHelper->compile('foobar-args', 'foobar-closure', $init, $node, $compiler);
     $this->assertEquals($expected, $init);
 }
 /**
  * @test
  * @dataProvider getCompileTestValues
  * @param array $childNodes
  * @param string $expected
  */
 public function testCompileReturnsAndAssignsExpectedVariables(array $childNodes, $expected)
 {
     $node = new ViewHelperNode($this->renderingContext, 'f', 'if', [], new ParsingState());
     foreach ($childNodes as $childNode) {
         $node->addChildNode($childNode);
     }
     $compiler = $this->getMock(TemplateCompiler::class, ['wrapChildNodesInClosure', 'wrapViewHelperNodeArgumentEvaluationInClosure']);
     $compiler->setRenderingContext($this->renderingContext);
     $compiler->expects($this->any())->method('wrapChildNodesInClosure')->willReturn('closure');
     $compiler->expects($this->any())->method('wrapViewHelperNodeArgumentEvaluationInClosure')->willReturn('arg-closure');
     $init = '';
     $this->viewHelper->compile('foobar-args', 'foobar-closure', $init, $node, $compiler);
     $this->assertEquals($expected, $init);
 }
Esempio n. 6
0
 /**
  * Helper method which triggers the rendering of everything between the
  * opening and the closing tag.
  *
  * @return mixed The finally rendered child nodes.
  * @api
  */
 public function renderChildren()
 {
     if ($this->renderChildrenClosure !== null) {
         $closure = $this->renderChildrenClosure;
         return $closure();
     }
     return $this->viewHelperNode->evaluateChildNodes($this->renderingContext);
 }
 /**
  * @param string $argumentsName
  * @param string $closureName
  * @param string $initializationPhpCode
  * @param ViewHelperNode $node
  * @param TemplateCompiler $compiler
  */
 public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler)
 {
     if (count($node->getChildNodes())) {
         throw new StopCompilingException();
     }
 }
Esempio n. 8
0
 /**
  * Wraps one ViewHelper argument evaluation in a closure that can be
  * rendered by passing a rendering context.
  *
  * @param ViewHelperNode $node
  * @param string $argumentName
  * @return string
  */
 public function wrapViewHelperNodeArgumentEvaluationInClosure(ViewHelperNode $node, $argumentName)
 {
     $arguments = $node->getArguments();
     $argument = $arguments[$argumentName];
     $closure = 'function() use ($renderingContext, $self) {' . chr(10);
     if ($node->getArgumentDefinition($argumentName)->getType() === 'boolean') {
         // We treat boolean nodes by compiling a closure to evaluate the stack of the boolean argument
         $compiledIfArgumentStack = $this->nodeConverter->convert(new ArrayNode($argument->getStack()));
         $closure .= $compiledIfArgumentStack['initialization'] . chr(10);
         $closure .= sprintf('return \\TYPO3Fluid\\Fluid\\Core\\Parser\\SyntaxTree\\BooleanNode::evaluateStack($renderingContext, %s);', $compiledIfArgumentStack['execution']) . chr(10);
     } else {
         $closure .= sprintf('$argument = unserialize(\'%s\'); return $argument->evaluate($renderingContext);', serialize($argument)) . chr(10);
     }
     $closure .= '}';
     return $closure;
 }
 /**
  * The compiled ViewHelper adds two new ViewHelper arguments: __thenClosure and __elseClosure.
  * These contain closures which are be executed to render the then(), respectively else() case.
  *
  * @param string $argumentsName
  * @param string $closureName
  * @param string $initializationPhpCode
  * @param ViewHelperNode $node
  * @param TemplateCompiler $compiler
  * @return string
  */
 public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler)
 {
     $thenViewHelperEncountered = $elseViewHelperEncountered = false;
     foreach ($node->getChildNodes() as $childNode) {
         if ($childNode instanceof ViewHelperNode) {
             $viewHelperClassName = $childNode->getViewHelperClassName();
             if (substr($viewHelperClassName, -14) === 'ThenViewHelper') {
                 $thenViewHelperEncountered = true;
                 $childNodesAsClosure = $compiler->wrapChildNodesInClosure($childNode);
                 $initializationPhpCode .= sprintf('%s[\'__thenClosure\'] = %s;', $argumentsName, $childNodesAsClosure) . chr(10);
             } elseif (substr($viewHelperClassName, -14) === 'ElseViewHelper') {
                 $elseViewHelperEncountered = true;
                 $childNodesAsClosure = $compiler->wrapChildNodesInClosure($childNode);
                 $initializationPhpCode .= sprintf('%s[\'__elseClosures\'][] = %s;', $argumentsName, $childNodesAsClosure) . chr(10);
                 $arguments = $childNode->getArguments();
                 if (isset($arguments['if'])) {
                     // The "else" has an argument, indicating it has a secondary (elseif) condition.
                     // Compile a closure which will evaluate the condition.
                     $elseIfConditionAsClosure = $compiler->wrapViewHelperNodeArgumentEvaluationInClosure($childNode, 'if');
                     $initializationPhpCode .= sprintf('%s[\'__elseifClosures\'][] = %s;', $argumentsName, $elseIfConditionAsClosure) . chr(10);
                 }
             }
         }
     }
     if (!$thenViewHelperEncountered && !$elseViewHelperEncountered && !isset($node->getArguments()['then'])) {
         $initializationPhpCode .= sprintf('%s[\'__thenClosure\'] = %s;', $argumentsName, $closureName) . chr(10);
     }
     return parent::compile($argumentsName, $closureName, $initializationPhpCode, $node, $compiler);
 }
Esempio n. 10
0
 /**
  * Convert a single ViewHelperNode into its cached representation. If the ViewHelper implements the "Compilable" facet,
  * the ViewHelper itself is asked for its cached PHP code representation. If not, a ViewHelper is built and then invoked.
  *
  * @param ViewHelperNode $node
  * @return array
  * @see convert()
  */
 protected function convertViewHelperNode(ViewHelperNode $node)
 {
     $initializationPhpCode = '// Rendering ViewHelper ' . $node->getViewHelperClassName() . chr(10);
     // Build up $arguments array
     $argumentsVariableName = $this->variableName('arguments');
     $renderChildrenClosureVariableName = $this->variableName('renderChildrenClosure');
     $viewHelperInitializationPhpCode = '';
     try {
         $convertedViewHelperExecutionCode = $node->getUninitializedViewHelper()->compile($argumentsVariableName, $renderChildrenClosureVariableName, $viewHelperInitializationPhpCode, $node, $this->templateCompiler);
         $arguments = $node->getArgumentDefinitions();
         $argumentInitializationCode = sprintf('%s = array();', $argumentsVariableName) . chr(10);
         foreach ($arguments as $argumentName => $argumentDefinition) {
             if (!isset($alreadyBuiltArguments[$argumentName])) {
                 $argumentInitializationCode .= sprintf('%s[\'%s\'] = %s;%s', $argumentsVariableName, $argumentName, var_export($argumentDefinition->getDefaultValue(), TRUE), chr(10));
             }
         }
         $alreadyBuiltArguments = array();
         foreach ($node->getArguments() as $argumentName => $argumentValue) {
             if ($argumentValue instanceof NodeInterface) {
                 $converted = $this->convert($argumentValue);
             } else {
                 $converted = array('initialization' => '', 'execution' => $argumentValue);
             }
             $argumentInitializationCode .= $converted['initialization'];
             $argumentInitializationCode .= sprintf('%s[\'%s\'] = %s;', $argumentsVariableName, $argumentName, $converted['execution']) . chr(10);
             $alreadyBuiltArguments[$argumentName] = TRUE;
         }
         // Build up closure which renders the child nodes
         $initializationPhpCode .= sprintf('%s = %s;', $renderChildrenClosureVariableName, $this->templateCompiler->wrapChildNodesInClosure($node)) . chr(10);
         $initializationPhpCode .= $argumentInitializationCode . $viewHelperInitializationPhpCode;
     } catch (StopCompilingChildrenException $stopCompilingChildrenException) {
         $convertedViewHelperExecutionCode = '\'' . $stopCompilingChildrenException->getReplacementString() . '\'';
     }
     $initializationArray = array('initialization' => $initializationPhpCode, 'execution' => $convertedViewHelperExecutionCode === NULL ? 'NULL' : $convertedViewHelperExecutionCode);
     return $initializationArray;
 }
Esempio n. 11
0
 /**
  * Compiles the node structure to a native switch
  * statement which evaluates closures for each
  * case comparison and renders child node closures
  * only when value matches.
  *
  * @param string $argumentsName
  * @param string $closureName
  * @param string $initializationPhpCode
  * @param ViewHelperNode $node
  * @param TemplateCompiler $compiler
  * @return string
  */
 public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler)
 {
     $phpCode = 'call_user_func_array(function($arguments) use ($renderingContext, $self) {' . PHP_EOL . 'switch ($arguments[\'expression\']) {' . PHP_EOL;
     foreach ($node->getChildNodes() as $childNode) {
         if ($this->isDefaultCaseNode($childNode)) {
             $childrenClosure = $compiler->wrapChildNodesInClosure($childNode);
             $phpCode .= sprintf('default: return call_user_func(%s);', $childrenClosure) . PHP_EOL;
         } elseif ($this->isCaseNode($childNode)) {
             /** @var ViewHelperNode $childNode */
             $valueClosure = $compiler->wrapViewHelperNodeArgumentEvaluationInClosure($childNode, 'value');
             $childrenClosure = $compiler->wrapChildNodesInClosure($childNode);
             $phpCode .= sprintf('case call_user_func(%s): return call_user_func(%s);', $valueClosure, $childrenClosure, $compiler->getNodeConverter()->convert($childNode)) . PHP_EOL;
         }
     }
     $phpCode .= '}' . PHP_EOL;
     $phpCode .= sprintf('}, array(%s))', $argumentsName);
     return $phpCode;
 }
Esempio n. 12
0
 /**
  * @param string $argumentsName
  * @param string $closureName
  * @param string $initializationPhpCode
  * @param ViewHelperNode $node
  * @param TemplateCompiler $compiler
  */
 public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler)
 {
     $renderedString = $node->evaluateChildNodes($this->renderingContext);
     $stopCompilingChildrenException = new StopCompilingChildrenException();
     $stopCompilingChildrenException->setReplacementString($renderedString);
     throw $stopCompilingChildrenException;
 }
Esempio n. 13
0
 /**
  * Initialize the given ViewHelper and adds it to the current node and to
  * the stack.
  *
  * @param ParsingState $state Current parsing state
  * @param string $namespaceIdentifier Namespace identifier - being looked up in $this->namespaces
  * @param string $methodIdentifier Method identifier
  * @param array $argumentsObjectTree Arguments object tree
  * @return boolean whether the viewHelper was found and added to the stack or not
  * @throws Exception
  */
 protected function initializeViewHelperAndAddItToStack(ParsingState $state, $namespaceIdentifier, $methodIdentifier, $argumentsObjectTree)
 {
     if ($this->viewHelperResolver->isNamespaceValid($namespaceIdentifier, $methodIdentifier) === FALSE) {
         return FALSE;
     }
     $currentViewHelperNode = new ViewHelperNode($this->viewHelperResolver, $namespaceIdentifier, $methodIdentifier, $argumentsObjectTree, $state);
     $viewHelper = $currentViewHelperNode->getUninitializedViewHelper();
     $this->callInterceptor($currentViewHelperNode, InterceptorInterface::INTERCEPT_OPENING_VIEWHELPER, $state);
     $viewHelper::postParseEvent($currentViewHelperNode, $argumentsObjectTree, $state->getVariableContainer());
     $state->pushNodeToStack($currentViewHelperNode);
     return TRUE;
 }