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] Fixed edge case where empty data may not be a string and throws TransformationFailedException#13598

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

Conversation

@guilhermeblanco
Copy link
Contributor

QA
Bug fix?yes
New feature?no
BC breaks?no
Deprecations?no
Tests pass?yes
LicenseMIT

I just can't recreate this error, by any means.
I somehow have a form with an integer type which happens to submit "null" asviewData (somehow) and it reusesempty_data option. Now my field was configured like:

$builder->add('page','integer',array('empty_data' =>1,));

And since the assignment ofviewData is theempty_data, one of the normalizers (while callingviewToNorm()) throws aTransformationFailedException with the following message:Expected a string.

… it throws a TransformationFailedException with message: 'Expected a string.'.
@guilhermeblanco
Copy link
ContributorAuthor

After investigating more on how I hit this corner case, I have more information.
I have a form with 2 fields integer fields. I'm submitting a GET request with 1 field only and forcing$clearMissing = true, which will then call$form->submit() for the second field withNULL data.
When it requires to fetchempty_data, it retrieves the integer value, but theviewToNorm transformation fails because it expects a string.
That's how I think I hit this very interesting weird corner case. =)

@Tobion
Copy link
Contributor

Definitely needs tests

@Tobion
Copy link
Contributor

Also see#5939
What you probably need is a string in view data via'empty_data' => '1'

@guilhermeblanco
Copy link
ContributorAuthor

@Tobion I completely understand that quoted value leads to proper response. That's what I'm using internally in address this issue.
However, this patch introduces the same behavior as$submittedData, which means that likely some of the previously reported issues would be addressed by this patch. Please understand that currentlyempty_data option exposes itself supporting mixed values.http://symfony.com/doc/current/reference/forms/types/integer.html#empty-data

@fabpotfabpot added the Form labelFeb 5, 2015
@stof
Copy link
Member

In any case, this cannot be accepted without tests

@fabpot
Copy link
Member

@guilhermeblanco Any chance you can add some tests?

@guilhermeblanco
Copy link
ContributorAuthor

@fabpot I need to remember the situation that I hit it, but yes, I can add tests for this. =)
IIRC it's due to the fact that empty_data must be an string to work, otherwise it sets the form value to null. According to the docs, it's supposed to support mixed.
I'll double check and add tests for this. =)

@webmozart
Copy link
Contributor

Thank you for submitting this PR@guilhermeblanco! This is a duplicate of#12470. The underlying problem here is#4715, which can't be fixed without breaking BC. Every other solution is unfortunately a hack. I recommend that you use a custom model transformer that sets your default value instead until#4715 is fixed.

@guilhermeblanco
Copy link
ContributorAuthor

@webmozart Yes, it is a duplicate. However, can you explain me how does this solution qualify as a BC break?
Currently, it is the same approach taken a few lines beforehttps://github.com/symfony/symfony/blob/2.8/src/Symfony/Component/Form/Form.php#L535 and there's no way to get non-string values to work. The only BC I can realize here is a not working situation to a working situation.

@webmozartwebmozart reopened thisNov 6, 2015
@webmozart
Copy link
Contributor

Reopened after talking to@guilhermeblanco in person. This solution makes sense. Could you please rebase this on 2.3 and add tests?

@fabpot
Copy link
Member

@guilhermeblanco Any news on this one?

@guilhermeblanco
Copy link
ContributorAuthor

@fabpot should be able to do it in the next few days. =)

@fabpot
Copy link
Member

@guilhermeblanco Sorry for being pushy, but we try hard to merge/close old PRs. Any chance you can have a look at this one?

@guilhermeblanco
Copy link
ContributorAuthor

@fabpot I've spent a substantial amount of hours trying to recreate this scenario on both SimpleFormTest and CompoundFormTest without success.
The issue is however easily reproducible if followed the steps I detailed in the ticket and first comment. Feel free to close if you think appropriate, but this patch solves the bug in my app.

@HeahDude
Copy link
Contributor

I've tried to add tests inIntegerTypeTest but phpunit skip them... I don't understand.

Here's what I've tried :

publicfunctiontestSubmitNull(){$form =$this->factory->create('integer');$form->submit(null);$this->assertNull($form->getData());$this->assertNull($form->getViewData());}publicfunctiontestSubmitNullWithEmptyData(){$form =$this->factory->create('integer',null,array('empty_data' =>1,    ));$form->submit(null);$this->assertSame(1,$form->getData());$this->assertSame('1',$form->getViewData());}publicfunctiontestSubmitNullWithEmptyDataWhenNested(){$form =$this->factory->create('form')        ->add('age','integer',array('empty_data' =>1,        ));$form->submit(null);$this->assertSame(1,$form->get('age')->getData());$this->assertSame('1',$form->get('age')->getViewData());}

@jakzal
Copy link
Contributor

@HeahDude IntegerTypeTest requires the intl extension (have a look at the setUp() method).

@HeahDude
Copy link
Contributor

@jakzal thanks, will take another look though.

@HeahDude
Copy link
Contributor

@jakzal, I've checked and I have intl installed, but tests are skipped even with my global phpunit.

Any lead ?

@jakzal
Copy link
Contributor

@HeahDude if I remember correctly it needs to be installed in a specific version. You'll need to look into the code that makes the check.

@webmozart
Copy link
Contributor

@HeahDude PHPUnit tells you why a test was skipped if you pass the-v option. In this particular case, the test is skipped because it requires the intl extension with ICU in version 52.1 to be installed. However, current PHP versions ship with ICU 55.1, which is why the tests are being skipped.

#14260 proposes to upgrade to ICU 55.1, which would solve your problem. Would you like to work on that ticket?

@fabpot
Copy link
Member

IIUC, the change is good but we don't know (yet) how to write good unit tests to avoid regressions, is that correct?

@guilhermeblanco
Copy link
ContributorAuthor

@fabpot correct. Patch addresses nicely the problem in the known scenario: 2 integer fields with empty_data as integer values and submitting only one of the values (thus requiring the second to use the empty_data).
The patch also uses the same solution for submitted data conversion already in codebase (https://github.com/symfony/symfony/blob/2.3/src/Symfony/Component/Form/Form.php#L532 ), but in the context of empty data (which means when submitted data is not present).

@fabpot
Copy link
Member

Understood. So, instead of waiting for tests, and because this is a bug fix that is waiting here for so long, I propose to merge this as is for now. ping @symfony/deciders

@webmozart
Copy link
Contributor

@fabpot I'll talk to@guilhermeblanco and try to create some tests. If we don't, chances are that this gets refactored away again when optimizing theForm class.

@HeahDude
Copy link
Contributor

@guilhermeblanco, is the form compound in your scenario ? I think it may be either not relevant or some cause of this problem.

@weaverryan
Copy link
Member

I'm fine to have this merged - as long as we don't have any BC concerns. If this introduces an edge-case behavior change, I'm not clearwhat that change is - I'd like to see the before/after code in an UPGRADE file. I want to avoid this causing upgrade issues - it sounds like something that would be quite hard to track down.

@xabbuhxabbuh mentioned this pull requestMar 7, 2016
@xabbuh
Copy link
Member

I took@guilhermeblanco's commit and the tests suggested by@HeahDude (with a minor change where the view data are not expected to benull but the empty string instead) to finish this PR in#18047. I can confirm that the tests were failing before this change and that they do pass now. Should add a special test for the checkbox type too (as the issue initially talked about checkboxes)? And how would such a test look like?

@HeahDude
Copy link
Contributor

Nice job! I would suggest:

// CheckBoxTypeTest.phppublicfunctiontestSubmitNullWithEmptyDataTrueWhenNested(){$form =$this->factory->create('form')        ->add('agree','checkbox',array('empty_data' =>true,        ));$form->submit(null);$this->assertTrue($form->get('agree')->getData());$this->assertSame('1',$form->get('agree')->getViewData());$view =$form->get('agree')->createView();$this->assertTrue($view->vars['checked']);}publicfunctiontestSubmitNullWithEmptyDataFalseWhenNested(){$form =$this->factory->create('form')        ->add('agree','checkbox',array('empty_data' =>false,        ));$form->submit(null);$this->assertFalse($form->get('agree')->getData());$this->assertEmpty($form->get('agree')->getViewData());$view =$form->get('agree')->createView();$this->assertFalse($view->vars['checked']);}

And I confirm those tests fail without the fix.

@xabbuh
Copy link
Member

@HeahDude Thanks, test added.

@webmozart
Copy link
Contributor

Closed for the reasons discussed in#18047.

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

Reviewers

No reviews

Assignees

No one assigned

Labels

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

10 participants

@guilhermeblanco@Tobion@stof@fabpot@webmozart@HeahDude@jakzal@weaverryan@xabbuh@javiereguiluz

[8]ページ先頭

©2009-2025 Movatter.jp