/** * 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 $argumentsVariableName * @param string $renderChildrenClosureVariableName * @param string $initializationPhpCode * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode * @param \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler * @return string * @internal */ public function compile($argumentsVariableName, $renderChildrenClosureVariableName, &$initializationPhpCode, \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode, \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler) { foreach ($syntaxTreeNode->getChildNodes() as $childNode) { if ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode && $childNode->getViewHelperClassName() === 'TYPO3\\CMS\\Fluid\\ViewHelpers\\ThenViewHelper') { $childNodesAsClosure = $templateCompiler->wrapChildNodesInClosure($childNode); $initializationPhpCode .= sprintf('%s[\'__thenClosure\'] = %s;', $argumentsVariableName, $childNodesAsClosure) . chr(10); } if ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode && $childNode->getViewHelperClassName() === 'TYPO3\\CMS\\Fluid\\ViewHelpers\\ElseViewHelper') { $childNodesAsClosure = $templateCompiler->wrapChildNodesInClosure($childNode); $initializationPhpCode .= sprintf('%s[\'__elseClosure\'] = %s;', $argumentsVariableName, $childNodesAsClosure) . chr(10); } } return \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler::SHOULD_GENERATE_VIEWHELPER_INVOCATION; }
/** * 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 $argumentsVariableName * @param string $renderChildrenClosureVariableName * @param string $initializationPhpCode * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode * @param \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler * @return string * @internal */ public function compile($argumentsVariableName, $renderChildrenClosureVariableName, &$initializationPhpCode, \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode, \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler) { foreach ($syntaxTreeNode->getChildNodes() as $childNode) { if ($childNode instanceof ViewHelperNode && $childNode->getViewHelperClassName() === ThenViewHelper::class) { $childNodesAsClosure = $templateCompiler->wrapChildNodesInClosure($childNode); $initializationPhpCode .= sprintf('%s[\'__thenClosure\'] = %s;', $argumentsVariableName, $childNodesAsClosure) . LF; } if ($childNode instanceof ViewHelperNode && $childNode->getViewHelperClassName() === ElseViewHelper::class) { $childNodesAsClosure = $templateCompiler->wrapChildNodesInClosure($childNode); $initializationPhpCode .= sprintf('%s[\'__elseClosure\'] = %s;', $argumentsVariableName, $childNodesAsClosure) . LF; } } return sprintf('%s::renderStatic(%s, %s, $renderingContext)', get_class($this), $argumentsVariableName, $renderChildrenClosureVariableName); }
/** * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $node * @return array * @see convert() */ public function convertListOfSubNodes(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $node) { switch (count($node->getChildNodes())) { case 0: return array('initialization' => '', 'execution' => 'NULL'); case 1: $converted = $this->convert(current($node->getChildNodes())); return $converted; default: $outputVariableName = $this->variableName('output'); $initializationPhpCode = sprintf('%s = \'\';', $outputVariableName) . chr(10); foreach ($node->getChildNodes() as $childNode) { $converted = $this->convert($childNode); $initializationPhpCode .= $converted['initialization'] . chr(10); $initializationPhpCode .= sprintf('%s .= %s;', $outputVariableName, $converted['execution']) . chr(10); } return array('initialization' => $initializationPhpCode, 'execution' => $outputVariableName); } }
/** * Constructor. Parses the syntax tree node and fills $this->leftSide, $this->rightSide, * $this->comparator and $this->syntaxTreeNode. * * @param \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode * @throws \TYPO3\CMS\Fluid\Core\Parser\Exception */ public function __construct(\TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode) { $childNodes = $syntaxTreeNode->getChildNodes(); if (count($childNodes) > 3) { throw new \TYPO3\CMS\Fluid\Core\Parser\Exception('A boolean expression has more than tree parts.', 1244201848); } elseif (count($childNodes) === 0) { // In this case, we do not have child nodes; i.e. the current SyntaxTreeNode // is a text node with a literal comparison like "1 == 1" $childNodes = array($syntaxTreeNode); } $this->leftSide = new \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\RootNode(); $this->rightSide = new \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\RootNode(); $this->comparator = NULL; foreach ($childNodes as $childNode) { if ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\TextNode && !preg_match(str_replace('COMPARATORS', implode('|', self::$comparators), self::$booleanExpressionTextNodeCheckerRegularExpression), $childNode->getText())) { // $childNode is text node, and no comparator found. $this->comparator = NULL; // skip loop and fall back to classical to boolean conversion. break; } if ($this->comparator !== NULL) { // comparator already set, we are evaluating the right side of the comparator $this->rightSide->addChildNode($childNode); } elseif ($childNode instanceof \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\TextNode && ($this->comparator = $this->getComparatorFromString($childNode->getText()))) { // comparator in current string segment $explodedString = explode($this->comparator, $childNode->getText()); if (isset($explodedString[0]) && trim($explodedString[0]) !== '') { $value = trim($explodedString[0]); if (is_numeric($value)) { $this->leftSide->addChildNode(new \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NumericNode($value)); } else { $this->leftSide->addChildNode(new \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\TextNode(preg_replace('/(^[\'"]|[\'"]$)/', '', $value))); } } if (isset($explodedString[1]) && trim($explodedString[1]) !== '') { $value = trim($explodedString[1]); if (is_numeric($value)) { $this->rightSide->addChildNode(new \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NumericNode($value)); } else { $this->rightSide->addChildNode(new \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\TextNode(preg_replace('/(^[\'"]|[\'"]$)/', '', $value))); } } } else { // comparator not found yet, on the left side of the comparator $this->leftSide->addChildNode($childNode); } } if ($this->comparator === NULL) { // No Comparator found, we need to evaluate the given syntax tree node manually $this->syntaxTreeNode = $syntaxTreeNode; } }