-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Form] Default values set according to another options don't work anymore for children #3354
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
Comments
I have run into this with any custom collection types - they return arrays instead of the specified dataclass in each FormType. The workaround is to supply it as an option to the parent form type: <?php
$builder->add('parts', 'collection', array(
'type' => new OrderPartType(),
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'options' => array('data_class' => 'Ibms\\PartBundle\\Entity\\OrderPart'),
)); |
This is true for any custom type setting a default value for the data_class. |
Any update about this? |
Spent about 6 hours looking for a bug in my code. Finally arrived here ;) Would be great if it will be fixed soon! |
@stof can you be any more specific about the change that created this regression? |
Could we get a fix for this soon? It's quite disturbing being unable to follow the master branch for almost a month now because of this issue. |
@jmikola: Unfortunately, I'm not familiar with writing such tests yet. |
Is simply reverting 88ef52d an option? Obviously not in symfony master, but in our own forks? |
I came up with a temporary work-around the This is hardly a proper fix, but this is working for me, as the most significant issues in my application the |
Actually, I'd like to see it reverted in the master branch as it introduces a bug/regression which seems to be unfixable. I asked @bschussek about that some time ago but got no response yet. |
@craue we need to be sure that reverting it does not break the other changes in the Form component. So it should not be reverted in symfony master directly |
btw, I tried reverting this commit and it makes the testsuite fail so reverting only this commit is not the solution |
Just keeping it as-is is not satisfying either. ;) |
@craue true, but reverting the whole Form refactoring is not good either as it was fixing half of the pending Form issues. |
We are unable to follow the master branch because of this bug :( |
I'm sorry for introducing this regression. Unfortunately we cannot simply revert the commit, since then we are facing a different bug. I will commit myself to finding a solution this and next week, even though this might have to be a BC breaking one. |
@bschussek Thanks for popping in. I haven't look at this at all, but it might save some time to examine #3512 before you attempt a fix. That PR has worked for a number of folks afflicted by this bug. |
For reference, this issue was introduced in #3290, AFAIR also in order to fix #3299. Unfortunately the problem is a lot more complex than the solution in @Burgov's commit. The problem is that we want to be able to declare the default value of options dynamically, depending on the value of some other option. To give an example: Assume the option "empty_data" is set in type "FooType" depending on the value of option "data_class".
So both approaches are flawed. Declaring options as arrays is flawed and it has been so since symfony 1. We need some mechanism that
This sounds complex, and it is. PHP however offers a simple, native solution that mostly achieves what we want:
A different approach could be to replace the options array by an Options object that allows to set closures as options that are only resolved upon access. Then we could do something like:
However, I'm not confident that such an approach would not uncover yet more problems. Clever ideas? |
@bschussek the issue with PHP inheritance is that it requires dropping the dynamic inheritance between types, which is a powerful feature of the Form component. |
@stof I'm aware of that. I'm currently experimenting with the other approach. |
This demonstrates the issue described in symfony#3354. FieldType no longer has access to the child type's data_class option, which makes it unable to create the default closure for empty_data.
Commits ------- 8329087 [Form] Moved calculation of ChoiceType options to closures 5adec19 [Form] Fixed typos cb87ccb [Form] Failing test for empty_data option BC break b733045 [Form] Fixed option support in Form component Discussion ---------- [Form] Fixed option support in Form component Bug fix: yes Feature addition: no Backwards compatibility break: yes Symfony2 tests pass: yes Fixes the following tickets: #3354, #3512, #3685, #3694 Todo: -  This PR also introduces a new helper `DefaultOptions` for solving option graphs. It accepts default options to be defined on various layers of your class hierarchy. These options can then be merged with the options passed by the user. This is called *resolving*. The important feature of this utility is that it lets you define *lazy options*. Lazy options are specified using closures that are evaluated when resolving and thus have access to the resolved values of other (potentially lazy) options. The class detects cyclic option dependencies and fails with an exception in this case. For more information, check the inline documentation of the `DefaultOptions` class and the UPGRADE file. @fabpot: Might this be worth a separate component? (in total the utility consists of five classes with two associated tests) --------------------------------------------------------------------------- by beberlei at 2012-04-05T08:54:10Z "The important feature of this utility is that it lets you define lazy options. Lazy options are specified using closures" What about options that are closures? are those differentiated? --------------------------------------------------------------------------- by bschussek at 2012-04-05T08:57:35Z @beberlei Yes. Closures for lazy options receive a Symfony\Component\Form\Options instance as first argument. All other closures are interpreted as normal values. --------------------------------------------------------------------------- by stof at 2012-04-05T11:09:49Z I'm wondering if these classes should go in the Config component. My issue with it is that it would add a required dependency to the Config component and that the Config component mixes many different things in it already (the loader part, the resource part, the definition part...) --------------------------------------------------------------------------- by sstok at 2012-04-06T13:36:36Z Sharing the Options class would be great, and its more then one class so why not give it its own Component folder? Filesystem is just one class, and that has its own folder. Great job on the class bschussek :clap: --------------------------------------------------------------------------- by bschussek at 2012-04-10T12:32:34Z @fabpot Any input? --------------------------------------------------------------------------- by bschussek at 2012-04-10T13:54:13Z @fabpot Apart from the decision about the final location of DefaultOptions et al., could you merge this soon? This would make my work a bit easier since this one is a blocker. --------------------------------------------------------------------------- by fabpot at 2012-04-10T18:08:18Z @bschussek: Can you rebase on master? I will merge afterwards. Thanks.
This demonstrates the issue described in symfony/symfony#3354. FieldType no longer has access to the child type's data_class option, which makes it unable to create the default closure for empty_data.
Since the recent refactoring of the way default options are merged for a Form, setting a default value according to the value of another option does not work anymore for the hierarchy as the parent type will apply this default with its own default value even if the child type changed the default value. This is because the way the defaults are applied changed so the child type is applied only later.
A good way to see this is to define a type setting a default value for the
data_class
property. Theempty_data
default value set by the FieldType won't be set properly in the form (we would expect getting a closure crating an instance of the class).This is a BC break and makes the type inheritance less powerful IMO.
/cc @bschussek
The text was updated successfully, but these errors were encountered: