Skip to content

Commit

Permalink
BUGFIX: Fusion Runtime lazy-props evaluation confuses `getLastEvaluat…
Browse files Browse the repository at this point in the history
…ionStatus()`

fixes: #3469

doing the check if a render was successful cannot only happen via `$this->getLastEvaluationStatus()`
-> as the render path might contain a lazy-prop (closure) which, when evaluated uses the same runtime.
-> if the last lazy-prop has an `@if` annotation its skipped, but the `$lastEvaluationStatus` is set on the same runtime.
-> there might still be partial successful output (the first values of a lazy-prop eg.) so we need to check additionally if the return value is null.
  • Loading branch information
mhsdesign committed Mar 27, 2022
1 parent 5b856dd commit 1531182
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 5 deletions.
8 changes: 3 additions & 5 deletions Neos.Fusion/Classes/Core/Runtime.php
Original file line number Diff line number Diff line change
Expand Up @@ -773,10 +773,8 @@ protected function evaluateApplyValues($configurationWithEventualProperties, $fu
$singleApplyPath .= '/expression';
}
$singleApplyValues = $this->evaluate($singleApplyPath, null, self::BEHAVIOR_EXCEPTION);
if ($this->getLastEvaluationStatus() !== static::EVALUATION_SKIPPED) {
if ($singleApplyValues === null) {
continue;
} elseif (is_array($singleApplyValues)) {
if ($singleApplyValues !== null || $this->getLastEvaluationStatus() !== static::EVALUATION_SKIPPED) {
if (is_array($singleApplyValues)) {
foreach ($singleApplyValues as $key => $value) {
// skip keys which start with __, as they are purely internal.
if ($key[0] === '_' && $key[1] === '_' && in_array($key, Parser::$reservedParseTreeKeys, true)) {
Expand Down Expand Up @@ -837,7 +835,7 @@ protected function evaluateProcessors($valueToProcess, $configurationWithEventua

$this->pushContext('value', $valueToProcess);
$result = $this->evaluate($processorPath, $contextObject, self::BEHAVIOR_EXCEPTION);
if ($this->getLastEvaluationStatus() !== static::EVALUATION_SKIPPED) {
if ($result !== null || $this->getLastEvaluationStatus() !== static::EVALUATION_SKIPPED) {
$valueToProcess = $result;
}
$this->popContext();
Expand Down
10 changes: 10 additions & 0 deletions Neos.Fusion/Tests/Functional/FusionObjects/ApplyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -286,4 +286,14 @@ public function rendererWithNestedPropsInApply()
$view->setFusionPath('apply/renderWithNestedProps');
self::assertEquals('::example::', $view->render());
}

/**
* @test
*/
public function evaluateLazyPropsWithLastOneSkipped()
{
$view = $this->buildView();
$view->setFusionPath('apply/evaluateLazyPropsWithLastOneSkipped');
self::assertSame(['lazyPropValue' => 'foo'], $view->render());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,15 @@ prototype(Neos.Fusion:TestNestedPropsB) < prototype(Neos.Fusion:Component) {
item_2 = '::'
}
}

// https://github.com/neos/neos-development-collection/issues/3469
apply.evaluateLazyPropsWithLastOneSkipped = Neos.Fusion:Component {
lazyPropValue = "foo"

lazyPropSkipped = "skip"
lazyPropSkipped.@if.1 = false

renderer = Neos.Fusion:DataStructure {
@apply.forceEvaluatedProps = ${Array.filter(props, prop => prop != null)}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,16 @@ processors.newSyntax.usingThisInProcessor = Value {
@process.1 = ${value + this.append}
append = " append"
}

// https://github.com/neos/neos-development-collection/issues/3469
processors.newSyntax.skippedLazyPropsInProcessor = Neos.Fusion:Component {
lazyPropValue = "foo"

lazyPropSkipped = "skip"
lazyPropSkipped.@if.1 = false

renderer = Neos.Fusion:DataStructure {
buz = "bar"
@process.combine = ${Array.concat(value, Array.filter(props, prop => prop != null))}
}
}
10 changes: 10 additions & 0 deletions Neos.Fusion/Tests/Functional/FusionObjects/ProcessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,14 @@ public function usingThisInProcessorWorks()
{
$this->assertFusionPath('my value append', 'processors/newSyntax/usingThisInProcessor');
}

/**
* @test
*/
public function skippedLazyPropsInProcessor()
{
$view = $this->buildView();
$view->setFusionPath('processors/newSyntax/skippedLazyPropsInProcessor');
self::assertSame(['buz' => 'bar', 'lazyPropValue' => 'foo'], $view->render());
}
}

0 comments on commit 1531182

Please sign in to comment.