Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[Form] Fix submitting checkboxes and radios with PATCH method#17771

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
HeahDude wants to merge4 commits intosymfony:2.7fromHeahDude:fix-#16802

Conversation

@HeahDude
Copy link
Contributor

@HeahDudeHeahDude commentedFeb 11, 2016
edited
Loading

QA
Bug fix?yes
New feature?no
BC breaks?no
Deprecations?no
Tests pass?yes
Fixed tickets#16802,#17799,#17899,#20179
LicenseMIT
Doc PR-
  • Confirm this is the right fix
  • Update tests for 2.8 with FQCN
  • Update tests for 3.0 by flipping choice keys and values

The bug seems to make it impossible to submit an expandedChoiceType with a PATCH method, see#17799.

nakashu reacted with thumbs up emoji
@javiereguiluzjaviereguiluz changed the title[WIP] [From] Fix submitting data to ChoiceType withclearMissing false[WIP] [Form] Fix submitting data to ChoiceType withclearMissing falseFeb 12, 2016
if (method_exists($child,'getClickedButton') &&null !==$child->getClickedButton()) {
$this->clickedButton =$child->getClickedButton();
}
}elseif (!$isSubmitted && !$clearMissing &&array_key_exists($name,$submittedData)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This never evaluates to TRUE, because $isSubmitted = array_key_exists($name, $submittedData);

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I know, this is a dummy test, seeHeahDude@935b2da#diff-ca5e25b47f3ecc94cd557946aeb486c6R583 for the right fix

@HeahDudeHeahDude changed the title[WIP] [Form] Fix submitting data to ChoiceType withclearMissing false[Form] Fix submitting data to ChoiceType withclearMissing falseFeb 16, 2016
@HeahDudeHeahDude changed the title[Form] Fix submitting data to ChoiceType withclearMissing false[Form] Fix submit a ChoiceType withclearMissing falseFeb 16, 2016
@HeahDudeHeahDude changed the title[Form] Fix submit a ChoiceType withclearMissing false[2.7] [Form] Fix submit a ChoiceType withclearMissing falseFeb 17, 2016
@HeahDudeHeahDude changed the title[2.7] [Form] Fix submit a ChoiceType withclearMissing false[2.7] [Form] Fix submission of ChoiceType withclearMissing falseFeb 17, 2016

foreach ($this->childrenas$name =>$child) {
$isSubmitted =array_key_exists($name,$submittedData);
$clearMissing =$this->getConfig()->getOption('expanded') ?:$clearMissing;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

expanded being an option forChoiceType, it looks weird to "hardcode" this condition here.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@fabpot I have the same feeling, but I miss to find another way... expanded choice type seems to be a really singular case.

Feel free to close this PR if there is a better fix.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@fabpot unless I missed something else,$clearMissing in only used as an argument ofFormType::submit() and there is no way no access its behaviour from a type definition, or it would need to override this method.

Handling a custom submit process for a particular form type would require a big refactoring...

@webmozart any thoughts ?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

a "no fix" is still a solution, but the doc should mention that using a PATCH method is not handled byChoiceType

@HeahDudeHeahDude changed the title[2.7] [Form] Fix submission of ChoiceType withclearMissing false[WIP] [2.7] [Form] Fix submission of ChoiceType withclearMissing falseFeb 23, 2016
@HeahDudeHeahDude changed the title[WIP] [2.7] [Form] Fix submission of ChoiceType withclearMissing false[WIP] [2.7] [Form] Fix submission of nested CheckBox withclearMissing falseFeb 23, 2016
@HeahDude
Copy link
ContributorAuthor

Ok I've updated the fix as it comes from theCheckboxType since theChoiceType got nested ones when expanded and multiple.

@Silverspur
Copy link

I'm unsure this new fix is acceptable because it leads to the opposite problem (if I'm not mistaken):
Let's look at an entity with two boolean attributesb1 andb2. Currently,b1 andb2 aretrue. If now there is a form intended to only manageb1, that is sumbitted with the checkboxunchecked, thenb1 will flip tofalse (this is what the fix corrects, this is the expected behaviour) butb2 will also flip tofalse even though the form is not supposed to affect it.

@HeahDude
Copy link
ContributorAuthor

@Silverspur It wouldn't if there is no field for thatb2 property which should be the case when a form is not supposed to manage it.

@Silverspur
Copy link

You're perfectly right, I got confused. My bad.

@HeahDude
Copy link
ContributorAuthor

Maybe I should add theclear_missing option in theBaseType with a default false value, so it can be overwritten "internally" for nested types needing to force update likeCheckboxType to make this fix global and consistent.

@webmozart, could you confirm ?

@Silverspur
Copy link

@HeahDude Actually theclear_missing option should be also set totrue by default for multiple+expanded 'choice' fields. Otherwise, when submitting the form with zero checkbox checked in the choice field, nothing will happen.

I still find odd the fact that the data related to a fieldpresent in the form type but with no data sent will :

  • not be updated if it is, say, aninteger (which is what I expect, and is the whole reason why $clearMissing is set to false for PATCH requests)
  • be updated tofalse if this is acheckbox.

I know the root of this issues comes from the way HTTP forms are designed, but I still find this discrepancies quite unconsistent, and I think it somehow questions the pertinence of systematically setting $clearMissing to false for PATCH, since the setting will only apply to certain types of fields.

@HeahDude
Copy link
ContributorAuthor

@Silverspur

a field present in the form type but with no data sent will not be updated

I don't agree with you as it actually depends on the mandatory$clearMissing to know what to do with it.
Either is will update it by unsetting the previous data (new data =null when field is missing or has an empty string value)OR it will ignore it (which is the need of the PATCH method). This is precisely the meaning of this option and you're right when you say this is because of the way the HTTP is designed.

Actually the clear_missing option should be also set to true by default for multiple+expanded 'choice' fields

This was the misinterpretation of my first fix, but it's not true as we found out thanks to your issue ;)
There is no need (tests speak for themselves) to set this option for theChoiceType as this new fix is applied on submitted children forms (seehttps://github.com/symfony/symfony/pull/17771/files#diff-ca5e25b47f3ecc94cd557946aeb486c6R567)

@HeahDude
Copy link
ContributorAuthor

Ok so I may need to clarify the patch I propose here, as I really think this time this is the way to fix it, at least for keeping BC in 2.7.

#16802 and#17799 pointed out that the expandedChoiceType was not updated with a PATCH method because$clearMissing isfalse is that case.

Then thanks to#17899, I understood that for onceChoiceType is not in cause.

A PATCH method would fail forany nestedCheckboxType in a form likeRadioType which extends it.
This is their particularity since in contrast with other types they don't map a "property" field (model data) but more accurately the state of a field as a virtual boolean as they might not been sent via HTTP when (virtually) "false".

So to fix this in a BC way for 2.7, we need IMO this "hack" as theclear_missing option is a kind of a feature which should only be used internally. But maybe we should add a note about it in the reference ofCheckboxType and set it as default false inBaseType to handle very edge cases.

What I suggest from here, is to revert this change inmaster and properly implement this (BC break) by addingFormConfigInterface::getClearMissing() and document it as well.

Another option (still BC) formaster would be to introduce a (possibly abstract)BooleanType which would hold theclear_missing option and makeCheckboxType extending it.

What do you think symfony deciders ?

@HeahDude
Copy link
ContributorAuthor

Actually this is the same case for thecompound option as said in the docs as of 2.3 :

    compound    ~~~~~~~~    **type**: ``boolean`` **default**: ``false``    This option specifies whether the type contains child types or not. This option    is managed internally for built-in types, so there is no need to configure    it explicitly.

@fabpot
Copy link
Member

@HeahDude I can see a list of task in the PR description. Are they still accurate? Anything we can do to move this PR forward? Thanks.

@HeahDude
Copy link
ContributorAuthor

@fabpot Yes I guess they are, having aclear_missing option would also help dealing with#18998 with more control fromdisabled option IMHO.

I waited for some feedback, I'm not sure if this is acceptable in 2.7. Any thoughts?

@fabpot
Copy link
Member

Looks like a bug fix to me, so 2.7 seems fine.

@HeahDudeHeahDudeforce-pushed thefix-#16802 branch 2 times, most recently fromb1d922a to096ef21CompareDecember 3, 2016 13:24
@HeahDudeHeahDude changed the title[WIP] [2.7] [Form] Fix submission of nested CheckBox withclearMissing false[2.7] [Form] Fix submitting checkboxes and radios with PATCH methodDec 3, 2016
@HeahDude
Copy link
ContributorAuthor

Ok this one is finally ready 🎉, had the chance to talk about this with@webmozart in person during the Hack Day in SymfonyCon Berlin, and we agreed on keeping this internal for now.

I've just renamed the optionforce_submit and use it only when there initial data is set but missing on submission, so PATCH method now works for nested checkboxes and radios, this allowsChoiceType to work with PATCH too.

Simperfit and SebastienTainon reacted with thumbs up emoji

@HeahDudeHeahDude changed the title[2.7] [Form] Fix submitting checkboxes and radios with PATCH method[Form] Fix submitting checkboxes and radios with PATCH methodDec 3, 2016
@HeahDude
Copy link
ContributorAuthor

status: needs work

@nicolas-grekasnicolas-grekas added this to the2.7 milestoneDec 6, 2016
@Simperfit
Copy link
Contributor

Great work@HeahDude !

$resolver->setNormalizer('force_submit',function (Options$options) {
// If pre set data is true, we need to ensure that $emptyData will be submitted
return (bool)$options['data'];
returnisset($options['data']) &&(bool)$options['data'];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

how about

return !empty($options['data']);

instead?

@xabbuh
Copy link
Member

@HeahDude What is the state here?

@HeahDude
Copy link
ContributorAuthor

@xabbuh I'm still quite reluctant to merge this fix as is, as it makes impossible to ignore checkboxes or radios with PATCH request (they will always be submitted).

I think I should reduce the scope of this PR to act only on parent forms containing such fields like theChoiceType (which is also buggy with POST), then better document the problem and its solutions, and continue the work on this as a feature on master.

I mean actually problems with PATCH method are quite expected and the component should handle only two cases IMHO:

  1. The form contains every possible fields to update:

    • the view is in html and will bug when submitting some checkboxes or radio, adding hidden input should be the way to go (but is not the component responsibility though), this case does not really make sense to me (cf point 2), excepted when it's about compound forms like expandedChoiceType.

    • the data is an array (i.e got from some json data), name should be explicit and empty strings should be used to update any fields tonull (orfalse for boolean types, the conversion is already handled by the component, there are neither report nor bug for this case).

  2. The form contains a subset of the possible fields to update which is actually defining the PATCH context:

    • the view in html should submit all the fields either using the hidden input like in case 1, or we could enforce the behavior with this PR fix (this way should be considered a feature IMO).

    • the data comes from an unserialized array, same as case 1 point 2. There are absolutely no problem with this way of submitting data and nothing to change on this side.

So the problem is really about getting the proper array of submitted data when dealing with HTML form's submission.

Wdyt?

@backbone87
Copy link
Contributor

I am against this PR in its current state

Like i already stated here and explained in#20210 (comment) the problem is not the theFormInterface, but the wayRequestHandlerInterface prepares the HTTP body to be submitted to the form. TheFormInterface isnt responsible to fix shortcomings of the HTTP requestsContent-Type. TheRequestHandlerInterface was extracted out of theFormInterface in 2.3 exactly for this reason.

TheRequestHandlerInterface can traverse theFormInterface tree and decide, if it needs to sanitize specific values, depending on the request (method, content-type, etc) and of course depending onFormConfigInterface (and thereforeFormType's options).

@fabpot
Copy link
Member

To be closed? Updated?

@HeahDude
Copy link
ContributorAuthor

Closing for now.

@ostrolucky
Copy link
Contributor

@HeahDude Any change to continue attempt to fix this? I've taken a look at request handler as suggested in#17771 (comment), but it would require recursive iteration over all form children to find ChoiceType there. It would be quite precedens doing that and I don't think people would be happy to merge something like that

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

1 more reviewer

@ostroluckyostroluckyostrolucky left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

2.7

Development

Successfully merging this pull request may close these issues.

10 participants

@HeahDude@Silverspur@fabpot@Simperfit@xabbuh@backbone87@ostrolucky@javiereguiluz@nicolas-grekas@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp