/** * 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 \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode $node * @return array * @see convert() */ protected function convertViewHelperNode(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\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) { $converted = $this->convert($argumentValue); $initializationPhpCode .= $converted['initialization']; $initializationPhpCode .= sprintf('%s[\'%s\'] = %s;', $argumentsVariableName, $argumentName, $converted['execution']) . chr(10); $alreadyBuiltArguments[$argumentName] = TRUE; } foreach ($node->getUninitializedViewHelper()->prepareArguments() 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->wrapChildNodesInClosure($node)) . chr(10); if ($node->getUninitializedViewHelper() instanceof \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface) { // ViewHelper is compilable $viewHelperInitializationPhpCode = ''; $convertedViewHelperExecutionCode = $node->getUninitializedViewHelper()->compile($argumentsVariableName, $renderChildrenClosureVariableName, $viewHelperInitializationPhpCode, $node, $this); $initializationPhpCode .= $viewHelperInitializationPhpCode; if ($convertedViewHelperExecutionCode !== self::SHOULD_GENERATE_VIEWHELPER_INVOCATION) { return array('initialization' => $initializationPhpCode, 'execution' => $convertedViewHelperExecutionCode); } } // ViewHelper is not compilable, so we need to instanciate it directly and render it. $viewHelperVariableName = $this->variableName('viewHelper'); $initializationPhpCode .= sprintf('%s = $self->getViewHelper(\'%s\', $renderingContext, \'%s\');', $viewHelperVariableName, $viewHelperVariableName, $node->getViewHelperClassName()) . chr(10); $initializationPhpCode .= sprintf('%s->setArguments(%s);', $viewHelperVariableName, $argumentsVariableName) . chr(10); $initializationPhpCode .= sprintf('%s->setRenderingContext($renderingContext);', $viewHelperVariableName) . chr(10); $initializationPhpCode .= sprintf('%s->setRenderChildrenClosure(%s);', $viewHelperVariableName, $renderChildrenClosureVariableName) . chr(10); $initializationPhpCode .= '// End of ViewHelper ' . $node->getViewHelperClassName() . chr(10); return array('initialization' => $initializationPhpCode, 'execution' => sprintf('%s->initializeArgumentsAndRender()', $viewHelperVariableName)); }