Skip to content

Commit 39ac87c

Browse files
authored
Merge pull request #581 from flightphp/fix/bug-with-multiple-view-renders
Fix/bug with multiple view renders
2 parents c8a1c88 + a68fc32 commit 39ac87c

File tree

5 files changed

+138
-4
lines changed

5 files changed

+138
-4
lines changed

flight/template/View.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ class View
2020
/** File extension. */
2121
public string $extension = '.php';
2222

23+
public bool $preserveVars = true;
24+
2325
/**
2426
* View variables.
2527
*
@@ -114,12 +116,16 @@ public function render(string $file, ?array $data = null): void
114116
throw new \Exception("Template file not found: {$normalized_path}.");
115117
}
116118

117-
if (\is_array($data)) {
118-
$this->vars = \array_merge($this->vars, $data);
119-
}
120-
121119
\extract($this->vars);
122120

121+
if (\is_array($data) === true) {
122+
\extract($data);
123+
124+
if ($this->preserveVars === true) {
125+
$this->vars = \array_merge($this->vars, $data);
126+
}
127+
}
128+
123129
include $this->template;
124130
}
125131

tests/FlightTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ protected function setUp(): void
2222
$_REQUEST = [];
2323
Flight::init();
2424
Flight::setEngine(new Engine());
25+
Flight::set('flight.views.path', __DIR__ . '/views');
2526
}
2627

2728
protected function tearDown(): void
@@ -354,4 +355,43 @@ public function after()
354355

355356
$this->expectOutputString('Thisisaroutewithhtml');
356357
}
358+
359+
/** @dataProvider \tests\ViewTest::renderDataProvider */
360+
public function testDoesNotPreserveVarsWhenFlagIsDisabled(
361+
string $output,
362+
array $renderParams,
363+
string $regexp
364+
): void
365+
{
366+
Flight::view()->preserveVars = false;
367+
368+
$this->expectOutputString($output);
369+
Flight::render(...$renderParams);
370+
371+
set_error_handler(function (int $code, string $message) use ($regexp): void {
372+
$this->assertMatchesRegularExpression($regexp, $message);
373+
});
374+
375+
Flight::render($renderParams[0]);
376+
377+
restore_error_handler();
378+
}
379+
380+
public function testKeepThePreviousStateOfOneViewComponentByDefault(): void
381+
{
382+
$this->expectOutputString(<<<html
383+
<div>Hi</div>
384+
<div>Hi</div>
385+
386+
<input type="number" />
387+
388+
<input type="number" />
389+
390+
html);
391+
392+
Flight::render('myComponent', ['prop' => 'Hi']);
393+
Flight::render('myComponent');
394+
Flight::render('input', ['type' => 'number']);
395+
Flight::render('input');
396+
}
357397
}

tests/ViewTest.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,4 +152,84 @@ public static function normalizePath(string $path, string $separator = DIRECTORY
152152
$viewMock::normalizePath('C:/xampp/htdocs/libs/Flight\core\index.php', '°')
153153
);
154154
}
155+
156+
/** @dataProvider renderDataProvider */
157+
public function testDoesNotPreserveVarsWhenFlagIsDisabled(
158+
string $output,
159+
array $renderParams,
160+
string $regexp
161+
): void {
162+
$this->view->preserveVars = false;
163+
164+
$this->expectOutputString($output);
165+
$this->view->render(...$renderParams);
166+
167+
set_error_handler(function (int $code, string $message) use ($regexp): void {
168+
$this->assertMatchesRegularExpression($regexp, $message);
169+
});
170+
171+
$this->view->render($renderParams[0]);
172+
173+
restore_error_handler();
174+
}
175+
176+
public function testKeepThePreviousStateOfOneViewComponentByDefault(): void
177+
{
178+
$this->expectOutputString(<<<html
179+
<div>Hi</div>
180+
<div>Hi</div>
181+
182+
<input type="number" />
183+
184+
<input type="number" />
185+
186+
html);
187+
188+
$this->view->render('myComponent', ['prop' => 'Hi']);
189+
$this->view->render('myComponent');
190+
$this->view->render('input', ['type' => 'number']);
191+
$this->view->render('input');
192+
}
193+
194+
public function testKeepThePreviousStateOfDataSettedBySetMethod(): void
195+
{
196+
$this->view->preserveVars = false;
197+
198+
$this->view->set('prop', 'bar');
199+
200+
$this->expectOutputString(<<<html
201+
<div>qux</div>
202+
<div>bar</div>
203+
204+
html);
205+
206+
$this->view->render('myComponent', ['prop' => 'qux']);
207+
$this->view->render('myComponent');
208+
}
209+
210+
public static function renderDataProvider(): array
211+
{
212+
return [
213+
[
214+
<<<html
215+
<div>Hi</div>
216+
<div></div>
217+
218+
html,
219+
['myComponent', ['prop' => 'Hi']],
220+
'/^Undefined variable:? \$?prop$/'
221+
],
222+
[
223+
<<<html
224+
225+
<input type="number" />
226+
227+
<input type="text" />
228+
229+
html,
230+
['input', ['type' => 'number']],
231+
'/^.*$/'
232+
],
233+
];
234+
}
155235
}

tests/views/input.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
$type ??= 'text';
4+
5+
?>
6+
7+
<input type="<?= $type ?>" />

tests/views/myComponent.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div><?= $prop ?></div>

0 commit comments

Comments
 (0)