Skip to content

Commit 2ed1135

Browse files
committed
Only remove variables if they were local
1 parent c6f6886 commit 2ed1135

File tree

3 files changed

+27
-68
lines changed

3 files changed

+27
-68
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 & 63 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'
@@ -791,55 +777,6 @@ public function test_nested_table_components(): void
791777
HTML, $html);
792778
}
793779

794-
public function test_same_variable_can_be_passed_to_multiple_components(): void
795-
{
796-
$this->registerViewComponent(
797-
'x-my-aside',
798-
'<aside><x-template :foreach="$items as $item"><a href="$item[\'id\']">{{$item[\'label\']}}</a></x-template></aside>',
799-
);
800-
801-
$this->registerViewComponent(
802-
'x-my-main',
803-
'<main><x-template :foreach="$items as $item"><div>{{$item$item[\'label\']}}</div></x-template></main>',
804-
);
805-
806-
$this->registerViewComponent(
807-
'x-my-footer',
808-
'<footer><x-template :foreach="$items as $item"><p>{{$item[\'label\']}}</p></x-template></footer>',
809-
);
810-
811-
$html = $this->render(
812-
view(
813-
<<<'HTML'
814-
<x-my-aside :items="$items" />
815-
<x-my-main :items="$items" />
816-
<x-my-footer :items="$items" />
817-
HTML,
818-
)
819-
->data(
820-
items: [
821-
['id' => '1', 'label' => 'Item 1'],
822-
['id' => '2', 'label' => 'Item 2'],
823-
],
824-
),
825-
);
826-
827-
$this->assertSnippetsMatch(<<<HTML
828-
<aside>
829-
<a href="1">Item 1</a>
830-
<a href="2">Item 2</a>
831-
</aside>
832-
<main>
833-
<div>Item 1</div>
834-
<div>Item 2</div>
835-
</main>
836-
<footer>
837-
<p>Item 1</p>
838-
<p>Item 2</p>
839-
</footer>
840-
HTML, $html);
841-
}
842-
843780
private function assertSnippetsMatch(string $expected, string $actual): void
844781
{
845782
$expected = str_replace([PHP_EOL, ' '], '', $expected);

0 commit comments

Comments
 (0)