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
[BUGFIX] Shallow copy RenderingContext before each ViewHelper #77
Conversation
f14b311
to
c1ec9b0
Compare
The problem is setting new renderingContext on one viewhelper instance over and over again. We should either use own instances for each rendering or introduce a renderingContextStash for viewhelper as well! |
\TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\ViewHelperNode::evaluate is using the same instance for the same viewhelper class. this means the renderingContext for one viewhelperclass is changed over and over again (vendor/typo3fluid/fluid/src/Core/ViewHelper/ViewHelperInvoker.php:73) to ensure always an uninitialized instance is taken i changed the evaluation function to |
We've also experimented with the There is a bit of back story for that which may be relevant to know:
I created this sequence diagram to try to illustrate the problem: There clearly is an issue with the RenderingContext not being the expected one - but I'm sorry to say we are no closer to finding the solution. |
damnit claus, i was 1 sec away from writing almost the same message :P :D yea, i have no clear idea how to go about it right now as well. i'm kinda leaning to say, screw cycle, let's do it right and find a "proper" solution to make cycle work again. |
In my honest opinion: using a fresh instance for every call (and being smart about the cost of creating an instance, analysing arguments etc) like #25 tries to implement is, although less performant, a much more predictable solution. Since currently There is also the somewhat long perspective that we currently have two modes of rendering where we should ideally be moving toward a single way (which is closer to the compiled mode than the uncompiled one, e.g. static calls). In this perspective, having instances become reused is not desired. |
On a side note: doing so would affect TYPO3 CMS Fluid performance of uncompilable templates adversely, the main reason being the need to perform dependency injection on every instance creation. Once compiled (which almost every template can be now) the performance hit is gone again. |
i asked bastian for his 2 cents in the #25 cycle issue, to see if we can "resurrect" it :) |
As I suggested there is even the other way to introduce a kind of stash for the viewhelpers renderingContext which adds one before rendering and removes it afterwards. Maybe a smarter way? |
c1ec9b0
to
525a3e5
Compare
Did some voodoo. |
525a3e5
to
4611a70
Compare
I cannot follow the technical details, but can anybody who is deeper in the code explain to me why the cycle VH and recursive rendering worked in previous versions of Fluid? Can't we re-use this knowledge to fix this? |
To define "voodoo": looks like something dark and mysterious happens when a rendering children closure is built and a variable is assigned to contain a reference to |
@helhum Due to the way templates were treated in the old Fluid I would induce that when sections were rendered recursively back then, the section's template source would actually be re-parsed every time, unless compilable - and this doesn't affect compiled templates. Now, we store the parsed template and use that same state each time rendering a section. |
Just a quick proposal how to fix the cycleViewHelper IchHabRecht@469ded0 |
Fixes an issue where recursively calling a ViewHelper caused the RenderingContext reference to become incorrect after ViewHelper renders a nested instance of itself. Expressed for example by recursively rendering a section with a loop - after exiting the loop and returning to the parent section variables would have unexpected values because the RenderingContext was replaced. Cloning (shallow copying) the ViewHelper instance before creating the render children closure solves this issue.
4611a70
to
819ca24
Compare
Thanks for the effort Nicole - but I think after this latest update to this patch, it should solve the issue in the right way without needing to change the cycle ViewHelper. If you could test and confirm this that would be great! PS: we're ready to make a release after this. |
This still fails for me. Either the tests and in TYPO3 |
Failed asserting that 'Item: 1.
|
And by reading the code it doesn't prevent setting different renderingContexts to the same object |
okay, seems to work now. found the error (not up-to-date resources) |
Excellent - I was just about to suggest taking a fresh checkout since I've force-pushed this a few times now. |
[BUGFIX] Shallow copy RenderingContext before each ViewHelper
Some third party ViewHelpers may depend on the presence of a rendering context while parsing - although it technically is an incorrect expectation to have the context available at this point, making it available allows third parties to access various secondary aspects of the rendering context. Specifically, the lack of this parse-time rendering context setting affects Widgets used in TYPO3 CMS when the template is uncompilable. Followup for TYPO3#77 which removed this line as it was evidently redundant. Line restored now along with a comment linking to this pull request.
Some third party ViewHelpers may depend on the presence of a rendering context while parsing - although it technically is an incorrect expectation to have the context available at this point, making it available allows third parties to access various secondary aspects of the rendering context. Specifically, the lack of this parse-time rendering context setting affects Widgets used in TYPO3 CMS when the template is uncompilable. Followup for TYPO3#77 which removed this line as it was evidently redundant. Line restored now along with a comment linking to this pull request.
Fixes the following issues: * TYPO3/Fluid#76 BUG Possibly NULL value in SpacelessViewHelper * TYPO3/Fluid#80 PERFORMANCE Internal cache of resolved ViewHelpers * TYPO3/Fluid#82 BUG Key used in ForViewHelper defaults to NULL * TYPO3/Fluid#84 BUG Improper array accessing * TYPO3/Fluid#85 BUG/TASK Prefix to avoid reserving "sections" variable name * TYPO3/Fluid#72 BUG Windows paths support in TemplatePaths * TYPO3/Fluid#87 BUG Avoid invalid class name in compiled code when using non-file template sources * TYPO3/Fluid#77 BUG Recursive section rendering accesses incorrect RenderingContext (see https://forge.typo3.org/issues/74393) * TYPO3/Fluid#94 BUG Avoid double HTML encoding on chained view helpers (see https://forge.typo3.org/issues/75133) Change-Id: I30062eb4a7fee1c2745a8067764f18d0753db88e Releases: master Resolves: #75135 Resolves: #74393 Reviewed-on: https://review.typo3.org/47279 Reviewed-by: Andreas Fernandez <typo3@scripting-base.de> Tested-by: Andreas Fernandez <typo3@scripting-base.de> Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl> Reviewed-by: Frank Naegler <frank.naegler@typo3.org> Reviewed-by: Benni Mack <benni@typo3.org> Tested-by: Benni Mack <benni@typo3.org>
Fixes an issue where recursively calling a ViewHelper caused the RenderingContext reference to become incorrect after ViewHelper renders a nested instance of itself. Expressed for example by recursively rendering a section with a loop - after exiting the loop and returning to the parent section variables would have unexpected values because the RenderingContext was replaced.
Cloning (shallow copying) the ViewHelper instance before creating the render children closure solves this issue.