Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUGFIX] Fix ternary condition behaviors #394

Merged
merged 2 commits into from
Jul 9, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion examples/Resources/Private/Singles/Conditions.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
<f:else>Not touched</f:else>
</f:if>

Ternary expression: {checkTernary ? ternaryTrue : ternaryFalse}
Ternary expression without then case: {ternaryTrue ? : ternaryFalse}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this also works with ?: instead of ? :? If yes, then we should prefer that since that's the common notation in PHP.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works both without and with any number and type of spaces between the parts.

Negated ternary expression without then case: {!checkTernary ? : ternaryFalse}
Standard ternary expression: {checkTernary ? ternaryTrue : ternaryFalse}
Negated ternary expression: {!checkTernary ? ternaryTrue : ternaryFalse}
Ternary expression with dotted variable paths: {asArray.nested.true ? asArray.nested.then : asArray.nested.else}
Ternary expression with dotted variable paths without then case: {asArray.nested.then ? : asArray.nested.else}

<f:if condition="0" else="0 === FALSE" />
<f:if condition="1" then="1 === TRUE" />
Expand Down
7 changes: 7 additions & 0 deletions examples/example_conditions.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@
$view->assign('checkTernary', true);
$view->assign('ternaryTrue', 'The ternary expression is TRUE');
$view->assign('ternaryFalse', 'The ternary expression is FALSE');
$view->assign('asArray', [
'nested' => [
'then' => 'Dotted variable TRUE',
'else' => 'Dotted variable FALSE',
'check' => true
]
]);

// Assigning the template path and filename to be rendered. Doing this overrides
// resolving normally done by the TemplatePaths and directly renders this file.
Expand Down
16 changes: 11 additions & 5 deletions src/Core/Parser/SyntaxTree/Expression/TernaryExpressionNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ class TernaryExpressionNode extends AbstractExpressionNode
(
{ # Start of shorthand syntax
(?: # Math expression is composed of...
[a-zA-Z0-9.\(\)\!\|\&\\\'\'\"\=\<\>\%\s\{\}\:\,]+ # Check variable side
[\s]+\?[\s]+
[a-zA-Z0-9.\s\'\"]+ # Then variable side
[\s]*:[\s]*
[a-zA-Z0-9.\s\'\"]+ # Else variable side
[\\!a-zA-Z0-9.\(\)\!\|\&\\\'\'\"\=\<\>\%\s\{\}\:\,]+ # Check variable side
[\s]?\?[\s]?
[a-zA-Z0-9.\s\'\"\\.]* # Then variable side, optional
[\s]?:[\s]?
[a-zA-Z0-9.\s\'\"\\.]+ # Else variable side
)
} # End of shorthand syntax
)/x';
Expand All @@ -50,12 +50,18 @@ public static function evaluateExpression(RenderingContextInterface $renderingCo
{
$parts = preg_split('/([\?:])/s', $expression);
$parts = array_map([__CLASS__, 'trimPart'], $parts);
$negated = false;
list ($check, $then, $else) = $parts;

if ($then === '') {
$then = $check{0} === '!' ? $else : $check;
}

$context = static::gatherContext($renderingContext, $expression);

$parser = new BooleanParser();
$checkResult = $parser->evaluate($check, $context);

if ($checkResult) {
return static::getTemplateVariableOrValueItself($renderingContext->getTemplateParser()->unquoteString($then), $renderingContext);
} else {
Expand Down
3 changes: 3 additions & 0 deletions src/Core/Parser/TemplateParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,9 @@ protected function buildArgumentObjectTree($argumentString)
public function unquoteString($quotedValue)
{
$value = $quotedValue;
if ($value === '') {
return $value;
}
if ($quotedValue{0} === '"') {
$value = str_replace('\\"', '"', preg_replace('/(^"|"$)/', '', $quotedValue));
} elseif ($quotedValue{0} === '\'') {
Expand Down
4 changes: 4 additions & 0 deletions tests/Functional/ExamplesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ public function getExampleScriptTestValues()
'example_conditions.php' => [
'example_conditions.php',
[
'Standard ternary expression: The ternary expression is TRUE',
'Negated ternary expression without then case: The ternary expression is FALSE',
'Negated ternary expression: The ternary expression is FALSE',
'Ternary expression without then case: The ternary expression is TRUE',
'1 === TRUE',
'(0) === FALSE',
'(1) === TRUE',
Expand Down