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
Fix/bug with multiple view renders #581
base: master
Are you sure you want to change the base?
Conversation
PHPUnit 9.6.19 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.18 ............................................................... 63 / 290 ( 21%) Time: 00:03.610, Memory: 10.00 MB OK (290 tests, 485 assertions) PHPUnit 9.6.19 by Sebastian Bergmann and contributors. Runtime: PHP 7.4.33 ............................................................... 63 / 290 ( 21%) Time: 00:03.168, Memory: 10.00 MB OK (290 tests, 485 assertions) |
Don't merge yetThere should still be an exception to it not being executed regardless of the flag and that is if you provide a key to render |
Surely #577 must be considered a straight-up bug? It does seem strange to me to preserve the buggy behaviour with a flag. |
What happens is that Flight tries as much as possible not to produce backward compatible changes and even less so in a bug fix, we are preparing the changes that will be breaking for version 4 |
The current behavior, although technically it is a bug, you can take advantage of it, such as rendering a piece of UI with certain variables, and save yourself from having to repeat them in consecutive renders of the same component |
So we assume that at least half of Flight::render users do it like this, and that's why we don't want to break that code, but you are given the option to disable that behavior of preserve variables between renders |
The current draft would remove existing items from I would suggest this code instead: \extract($this->vars);
if (\is_array($data)) {
\extract($data);
if ($this->preserveVars) {
$this->vars = \array_merge($this->vars, $data);
}
} (we might add the |
Also, a test might be added for this. Something like: $view->preserveVars = false;
$view->set('foo', 'bar');
$view->render('template', ['foo' => 'qux']);
$view->render('template'); // expected: $foo still exists, and equals 'bar' |
@vlakoff I don't hate the code you suggested. I would make sure it fits in the unit tests (and add your unit test you suggested as well). The only thing I don't like about it is that I hate One other thought I had..... what if we added to this code similar to https://github.com/flightphp/core/blob/master/flight/net/Router.php#L255-L264 If you can't find your variable name, scan through the array keys of |
Just checking in on this. What do you think @fadrian06 ? |
I've been testing the development branch of this PR and it's apparently working as expected |
Obviously when I activated the flag my views broke due to the bad behavior of preserving state between renders |
You can see the project I'm using it in Aime309/sarco at v3 here I am activating the flag sarco/app/configurations/views.php at v3 · Aime309/sarco here an implementation of an input component sarco/views/components/Input.php at v3 · Aime309/sarco Note that there are component attributes that are required and others optional, but with the flag it is always reset to that state by default here a login implementation sarco/vistas/paginas/ingreso.php at v3 · Aime309/sarco |
Thank you for your contribution, seeing it in detail accompanied by the test, if it makes sense to keep the vars that are assigned with ->set(...), I have to review it because there are many more cases to test |
@n0nag0n a var_dump before extract and that's it, it's not like extract will get variables out of nowhere, it will always take the keys from the array... for me the fewer lines the better, fewer bytes and more flight.. Also, there was a tip that is usually given in Python that I liked. |
I noticed a possible source of confusion. The undesired behavior may be encountered on the next render() call actually, as the unset() are called after the rendering of the view. Proper version of my snippet from #581 (comment): Current behavior: $view->preserveVars = false;
$view->set('foo', 'bar');
$view->render('template', ['foo' => 'qux']);
$view->render('template'); // in the view rendered here, $foo equals 'qux' (set from previous call)
$view->render('template'); // in the view rendered here, $foo doesn't exist (deleted from previous call) Expected behavior: $view->preserveVars = false;
$view->set('foo', 'bar');
$view->render('template', ['foo' => 'qux']);
$view->render('template'); // in the view rendered here, $foo still exists, and equals 'bar', from the ->set() Using the |
See problem #577
Component
Before: this is by default
After: activable through a flag
To enable just: