Skip to content

Commit 9aeb727

Browse files
erikaraujobrendt
andauthored
fix(view): prevent $var from being nulled after passing to component (#1160)
Co-authored-by: brendt <[email protected]>
1 parent 96f3149 commit 9aeb727

File tree

3 files changed

+27
-19
lines changed

3 files changed

+27
-19
lines changed

src/Tempest/View/src/Elements/PhpDataElement.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,16 @@ public function getWrappingElement(): Element
2626

2727
public function compile(): string
2828
{
29-
$variableName = str($this->name)->ltrim(':')->camel()->toString();
29+
$localVariableName = str($this->name)->ltrim(':')->camel()->toString();
3030
$isExpression = str_starts_with($this->name, ':');
3131
$value = $this->value ?? '';
3232

3333
// We'll declare the variable in PHP right before the actual element
3434
$variableDeclaration = sprintf(
35-
'$%s ??= %s ?? null;',
36-
$variableName,
35+
'$_%sIsLocal = isset($%s) === false; $%s ??= %s ?? null;',
36+
$localVariableName,
37+
$localVariableName,
38+
$localVariableName,
3739
$isExpression
3840
? ($value ?: 'null')
3941
: var_export($value, true), // @mago-expect best-practices/no-debug-symbols
@@ -42,8 +44,9 @@ public function compile(): string
4244
// And we'll remove it right after the element, this way we've created a "local scope"
4345
// where the variable is only available to that specific element.
4446
$variableRemoval = sprintf(
45-
'unset($%s);',
46-
$variableName,
47+
'if ($_%sIsLocal) { unset($%s); }',
48+
$localVariableName,
49+
$localVariableName,
4750
);
4851

4952
// Support for boolean attributes. When an expression attribute has a falsy value, it won't be rendered at all.

tests/Integration/View/TempestViewRendererDataPassingTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,4 +371,23 @@ public function test_boolean_attributes_in_view_component(): void
371371

372372
$this->assertStringContainsString(' href="hi"', $html);
373373
}
374+
375+
public function test_global_variables_are_kept(): void
376+
{
377+
$this->registerViewComponent('x-test', <<<'HTML'
378+
<div>{{ $item }}</div>
379+
HTML);
380+
381+
$html = $this->render(<<<'HTML'
382+
<x-test :item="$item"></x-test>
383+
<x-test :item="$item"></x-test>
384+
<x-test :item="$item"></x-test>
385+
HTML, item: 'foo');
386+
387+
$this->assertSnippetsMatch(<<<'HTML'
388+
<div>foo</div>
389+
<div>foo</div>
390+
<div>foo</div>
391+
HTML, $html);
392+
}
374393
}

tests/Integration/View/ViewComponentTest.php

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -652,20 +652,6 @@ public function test_merge_class(): void
652652
HTML, $html);
653653
}
654654

655-
public function test_attribute_precedence(): void
656-
{
657-
$this->markTestSkipped('TODO');
658-
659-
// Order should be: upperB > upperA > innerB > innerA
660-
// $this->registerViewComponent('x-test', <<<'HTML'
661-
// <div data-foo="innerA" :data-foo="'innerB'"></div>
662-
// HTML);
663-
// $html = $this->render(<<<'HTML'
664-
// <x-test data-foo="upperA" :data-foo="'upperB'"></x-test>
665-
// HTML);
666-
// $this->assertStringEqualsStringIgnoringLineEndings('<div data-foo="upperB"></div>', $html);
667-
}
668-
669655
public function test_does_not_duplicate_br(): void
670656
{
671657
$this->registerViewComponent('x-html-base', <<<'HTML'

0 commit comments

Comments
 (0)