From 2adbed4cede2d94cbf79038b442ed1734848b6e7 Mon Sep 17 00:00:00 2001 From: Simon Praetorius Date: Thu, 17 Apr 2025 00:17:14 +0200 Subject: [PATCH] [BUGFIX] Ignore f:then/f:else outside condition context Before this change, both `f:then` and `f:else` could be used outside of a condition tag and would then always output the content, regardless of any condition. Now, nothing is outputted. In the future, we might consider throwing an exception here to alert the user about invalid Fluid syntax. However, this would be a breaking change. Resolves: #1020 --- .../AbstractConditionViewHelper.php | 6 +++--- src/ViewHelpers/ElseViewHelper.php | 12 ++++++----- src/ViewHelpers/ThenViewHelper.php | 10 ++++----- .../ViewHelpers/IfThenElseViewHelperTest.php | 21 +++++++++++++++++++ 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/Core/ViewHelper/AbstractConditionViewHelper.php b/src/Core/ViewHelper/AbstractConditionViewHelper.php index 36aa986da..1666d01e1 100644 --- a/src/Core/ViewHelper/AbstractConditionViewHelper.php +++ b/src/Core/ViewHelper/AbstractConditionViewHelper.php @@ -118,7 +118,7 @@ protected function renderThenChild() foreach ($this->viewHelperNode->getChildNodes() as $childNode) { if ($childNode instanceof ViewHelperNode && str_ends_with($childNode->getViewHelperClassName(), 'ThenViewHelper')) { - $data = $childNode->evaluate($this->renderingContext); + $data = $childNode->evaluateChildNodes($this->renderingContext); return $data; } if ($childNode instanceof ViewHelperNode @@ -184,7 +184,7 @@ protected function renderElseChild() $arguments = $childNode->getArguments(); if (isset($arguments['if'])) { if ($arguments['if']->evaluate($this->renderingContext)) { - return $childNode->evaluate($this->renderingContext); + return $childNode->evaluateChildNodes($this->renderingContext); } } elseif ($elseNode === null) { $elseNode = $childNode; @@ -205,7 +205,7 @@ protected function renderElseChild() // If a f:else node exists, evaluate its content if ($elseNode instanceof ViewHelperNode) { - return $elseNode->evaluate($this->renderingContext); + return $elseNode->evaluateChildNodes($this->renderingContext); } // If only the condition is specified, but no then/else handling, the whole ViewHelper should diff --git a/src/ViewHelpers/ElseViewHelper.php b/src/ViewHelpers/ElseViewHelper.php index 8740979d2..b67ed0326 100644 --- a/src/ViewHelpers/ElseViewHelper.php +++ b/src/ViewHelpers/ElseViewHelper.php @@ -50,12 +50,14 @@ public function initializeArguments() } /** - * @return string the rendered string + * Does nothing unless used in context of condition ViewHelper, such as f:if + * * @api + * @todo consider throwing an exception here in future versions */ - public function render() + public function render(): string { - return $this->renderChildren(); + return ''; } /** @@ -64,9 +66,9 @@ public function render() * @param string $initializationPhpCode * @param ViewHelperNode $node * @param TemplateCompiler $compiler - * @return string|null + * @return string */ - public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler) + public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler): string { return '\'\''; } diff --git a/src/ViewHelpers/ThenViewHelper.php b/src/ViewHelpers/ThenViewHelper.php index f2369f5a2..edd0af9b4 100644 --- a/src/ViewHelpers/ThenViewHelper.php +++ b/src/ViewHelpers/ThenViewHelper.php @@ -25,14 +25,14 @@ class ThenViewHelper extends AbstractViewHelper protected $escapeOutput = false; /** - * Just render everything. + * Does nothing unless used in context of condition ViewHelper, such as f:if * - * @return string the rendered string * @api + * @todo consider throwing an exception here in future versions */ - public function render() + public function render(): string { - return $this->renderChildren(); + return ''; } /** @@ -43,7 +43,7 @@ public function render() * @param TemplateCompiler $compiler * @return string */ - public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler) + public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler): string { return '\'\''; } diff --git a/tests/Functional/ViewHelpers/IfThenElseViewHelperTest.php b/tests/Functional/ViewHelpers/IfThenElseViewHelperTest.php index b526af9b5..22fbb1ae8 100644 --- a/tests/Functional/ViewHelpers/IfThenElseViewHelperTest.php +++ b/tests/Functional/ViewHelpers/IfThenElseViewHelperTest.php @@ -566,6 +566,27 @@ public static function renderDataProvider(): \Generator true, ]; + yield 'f:then without f:if context' => [ + 'foo', + [], + '', + ]; + yield 'f:else without f:if context' => [ + 'foo', + [], + '', + ]; + yield 'f:else-if without f:if context, verdict true' => [ + 'foo', + ['verdict' => true], + '', + ]; + yield 'f:else-if without f:if context, verdict false' => [ + 'foo', + ['verdict' => false], + '', + ]; + /* * @todo This should work but doesn't at the moment. This is probably related to the boolean * parser not converting variable nodes correctly. There is a related todo in the BooleanParserTest.