/**
  * 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);
 }
예제 #2
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 \\NamelessCoder\\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;
 }
예제 #3
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');
     $initializationPhpCode .= sprintf('%s = array();', $argumentsVariableName) . chr(10);
     $alreadyBuiltArguments = array();
     foreach ($node->getArguments() as $argumentName => $argumentValue) {
         if ($argumentValue instanceof NodeInterface) {
             $converted = $this->convert($argumentValue);
         } else {
             $converted = array('initialization' => '', 'execution' => $argumentValue);
         }
         $initializationPhpCode .= $converted['initialization'];
         $initializationPhpCode .= sprintf('%s[\'%s\'] = %s;', $argumentsVariableName, $argumentName, $converted['execution']) . chr(10);
         $alreadyBuiltArguments[$argumentName] = TRUE;
     }
     $arguments = $node->getArgumentDefinitions();
     foreach ($arguments as $argumentName => $argumentDefinition) {
         if (!isset($alreadyBuiltArguments[$argumentName])) {
             $initializationPhpCode .= sprintf('%s[\'%s\'] = %s;', $argumentsVariableName, $argumentName, var_export($argumentDefinition->getDefaultValue(), TRUE)) . chr(10);
         }
     }
     // Build up closure which renders the child nodes
     $renderChildrenClosureVariableName = $this->variableName('renderChildrenClosure');
     $initializationPhpCode .= sprintf('%s = %s;', $renderChildrenClosureVariableName, $this->templateCompiler->wrapChildNodesInClosure($node)) . chr(10);
     $viewHelperInitializationPhpCode = '';
     $convertedViewHelperExecutionCode = $node->getUninitializedViewHelper()->compile($argumentsVariableName, $renderChildrenClosureVariableName, $viewHelperInitializationPhpCode, $node, $this->templateCompiler);
     $initializationPhpCode .= $viewHelperInitializationPhpCode;
     $initializationArray = array('initialization' => $initializationPhpCode, 'execution' => $convertedViewHelperExecutionCode);
     return $initializationArray;
 }