-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Form] CollectionType apply prototypeOptions to ResizeFormListener new fields #49835
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
Conversation
src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php
Outdated
Show resolved
Hide resolved
Yeah good point. Fixed! |
src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php
Outdated
Show resolved
Hide resolved
$this->deleteEmpty = \is_bool($deleteEmpty) ? $deleteEmpty : $deleteEmpty(...); | ||
$this->prototypeOptions = $prototypeOptions; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$this->prototypeOptions = array_replace($options, $prototypeOptions);
(and remove the array_replace below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm that seems not right?
I feel like the way the CollectionType gets its prototype options is by doing the array merge on the entry options (line 30 in the CollectionType). But that isn't by definition the way the ResizeFormListener should do it as well?
I'm not sure how it was decided for the CollectionType to handle the prototype options this way. I feel like it would be just as valid to have the prototype options be completely independent of the entry options.
I think it's also important to have the way the options are used in the CollectionType and the way it's passed to the ResizeFormListener be the same. Maybe I should have prevented the double merge? That way if it is decided that behavior is to change, it's always the same for both the CollectionType and the ResizeFormListener.
What do you think?
Thanks so much for the feedback :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then we should fallback to $options when no prototype options are given, to preserve the current behavior:
$this->prototypeOptions = $prototypeOptions ?? $options;
and change the argument to array $prototypeOptions = null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes totally correct. I've changed the default value for the prototypeOptions and fallback to options.
I've also changed the CollectionType constructor to prevent the double merge.
Thanks so much for your help, I'm not very good at this.
Thank you @Thorry84. |
Not sure how exactly, but this fix has crashed some functionality on my sites. It's not a bug report, just wanted to let you know it's a possible BC though. |
Hmmm that's not good. I'm not sure how my changes could be a BC break. However the previous implementation was inherently broken. As I pointed out the example given in the blog post was simply not possible. So in the past the functionality not working might have masked any issues with unmanaged entities. As far as I can see I don't know of any way the ResizeFormListener could cause Entities to become unmanaged. I would suspect an issue with the wrong transformers being applied to the form fields? If you have any code to share I would love to help you investigate the issue. |
It must have been because I used an unmanaged empty Doctrine entity as prototype data
In 6.2.7, the empty detached entity was used only for prototyping. The
But now, in 6.2.8, the
So the blank detached entity comes into play instead of being discarded as before. In other words - does it make sense to use prototype data for populating new collection elements rather than only for prototyping? And even if so, it has not been used until 6.2.8, which seems to be an explicit BC. |
That explains the error you've been getting. In my opinion the previous behavior where all the options were discarded was incorrect. So passing along the options to the new fields is a bug fix and not a BC break. However the Discussions about this in the past I've been able to find point out the data is for initialization only and not on submit. However in the past when passing So I'm not really sure if this would be considered a BC break or a bugfix? Either case sounds valid to me. In your code, why isn't the new data handled? If there are new entries in the form, there are new entities to be persisted? |
The actual entities are loaded by ID from a repository first in a preSubmit hook, and only then updated.
Ok, no problem, I just wanted you to be aware of that possible issue. |
Thanks for letting me know. Happy to help :) |
If somebody comes across this issue from Google: It doesn't work for the use case stated in the blog and my fix didn't solve the issue fully for that use case. The problem is, the prototype options are used for new fields, but only when creating new fields in the UI. So when you have a form, you can disable fields for existing data and have new fields available. This part now works with my fix, but whenever there is a validation error in the form, the submitted data is seen as "old" data and the fields are now disabled. This means the user can't even fix the validation errors and is in a sense soft-locked. So even though the fix did technically fix the functionality, the supposed use-case simply isn't possible using only this feature. YMMV Tagging @javiereguiluz to maybe edit the blog post to point this out. |
Fixes issue 49786
This pull request provides a fix for issue 49786.
By passing the prototypeOptions to the ResizeFormListener from the CollectionType and applying it to new fields it makes the prototypeOptions function as intended. Otherwise the use case such as in this blog aren't possible: https://symfony.com/blog/new-in-symfony-6-1-customizable-collection-prototypes
I've updated the existing ResizeFormListener tests to handle the new signature and added a new test to the CollectionType which would fail without this fix and pass with the fix.