Skip to content

[Form] Missing Data Handling (checkbox edge cases) #45081

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

Open
wants to merge 13 commits into
base: 7.4
Choose a base branch
from

Conversation

filiplikavcan
Copy link
Contributor

@filiplikavcan filiplikavcan commented Jan 19, 2022

Q A
Branch? 6.2
Bug fix? yes
New feature? yes
Deprecations? no
Tickets Fix #20179, #14938
License MIT
  • write description of this PR

@carsonbot carsonbot added this to the 4.4 milestone Jan 19, 2022
@carsonbot carsonbot changed the title [WIP][Form] Missing Data Handling (checkbox edge cases) [Form] [WIP] Missing Data Handling (checkbox edge cases) Jan 19, 2022
@SHTIKOV

This comment was marked as off-topic.

@nicolas-grekas

This comment was marked as outdated.

@nicolas-grekas nicolas-grekas force-pushed the handle-unchecked-checkbox branch from bb97fdb to adb9016 Compare August 2, 2022 10:42
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

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

Sorry for the delay reviewing this, it's definitely interesting!

I force-pushed on your fork to turn the trait into a class. Please fetch + reset --hard before reopening the branch. There are some tests failing that need to be addressed.

I'm just wondering if this shouldn't go on 6.2: yes, this can be seen as a bug fix, but it's also a new behavior to me.

/cc @symfony/mergers WDYT?

@nicolas-grekas nicolas-grekas changed the title [Form] [WIP] Missing Data Handling (checkbox edge cases) [Form] Missing Data Handling (checkbox edge cases) Aug 2, 2022
@yceruto
Copy link
Member

yceruto commented Aug 2, 2022

Agree for 6.2

@filiplikavcan
Copy link
Contributor Author

Tests for php >=8.1 are all green.

@nicolas-grekas
Copy link
Member

Great thanks. OK to rebase+retarget for 6.2?

@filiplikavcan filiplikavcan changed the base branch from 4.4 to 6.2 August 2, 2022 15:46
@filiplikavcan filiplikavcan force-pushed the handle-unchecked-checkbox branch from d939f4f to ecce817 Compare August 2, 2022 16:09
nicolas-grekas
nicolas-grekas previously approved these changes Aug 2, 2022
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

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

LGTM thanks!

@xabbuh
Copy link
Member

xabbuh commented Aug 2, 2022

the test failures look related

return $data;
}
}
} catch (\Error $error) {
Copy link
Member

Choose a reason for hiding this comment

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

Catching type errors here doesn't look like the right solution to me. We should investigate instead why the $type property in FormConfigBuilder isn't initialized at this point and fix that root issue instead.

Copy link
Contributor Author

@filiplikavcan filiplikavcan Aug 3, 2022

Choose a reason for hiding this comment

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

I don't like it either.

Another solution could be to make FormConfigBuilderInterface::getType() nullable. Then null state would have to be handled in these methods where getType() is called:

ValidatorDataCollector#getCasters
FormDataExtractor#extractConfiguration
FormDataCollector#getCasters
FormTypeCsrfExtension#finishView
FormTypeCsrfExtension#buildForm
BaseType#buildView
Button#createView

I don't know if null/undefined type is a valid case or not.

Copy link
Member

Choose a reason for hiding this comment

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

I can look into why we run into this error here. But that will probably not happen before the weekend.

Copy link
Contributor Author

@filiplikavcan filiplikavcan Aug 3, 2022

Choose a reason for hiding this comment

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

Thank you. When I created this PR on Jan 19 it worked. These commits look related: a53b450d 488a262a

@nicolas-grekas nicolas-grekas dismissed their stale review August 3, 2022 08:20

(code is not ready)

@nicolas-grekas
Copy link
Member

Status: needs work

@nicolas-grekas
Copy link
Member

Can you please rebase @filiplikavcan?

@mpdude
Copy link
Contributor

mpdude commented Sep 29, 2022

A form that consists of unchecked checkboxes only will not be recognized as being submitted with the standard $form->handleRequest(...); if ($form->isSubmitted() ...) { ... } pattern. Does this PR intend to address this, or does it cover other edge cases I am not aware of?

If yes, you might want to mention #20210 in the list of tickets as well.

Update: I have been looking at this code for over 10 minutes now and I am unable to figure out how it would be able to tell whether we're GET-requesting a page that contains a checkbox-only form, or if this form has been submitted with method="GET" and no checkbox was checked.

Comment on lines 63 to 65
$missingData = $this->missingDataHandler->missingData;

if ($missingData === $data = $this->missingDataHandler->handle($form, $request->query->all()[$name] ?? $missingData)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I cannot follow this code and would love if we could break this down into smaller chunks, maybe using expressive variable names.

Copy link
Contributor Author

@filiplikavcan filiplikavcan Oct 4, 2022

Choose a reason for hiding this comment

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

Done. Is it easier to follow?

$missingData = $this->missingDataHandler->missingData;
$queryData = $request->query->all()[$name] ?? $missingData;
$data = $this->missingDataHandler->handle($form, $queryData);
if ($missingData === $data) {
// Don't submit GET requests if the form's name does not exist
// in the request
return;
}

@filiplikavcan filiplikavcan force-pushed the handle-unchecked-checkbox branch from 5aad0a4 to 4dcd5a4 Compare October 4, 2022 17:50
@filiplikavcan
Copy link
Contributor Author

filiplikavcan commented Oct 4, 2022

Update: I have been looking at this code for over 10 minutes now and I am unable to figure out how it would be able to tell whether we're GET-requesting a page that contains a checkbox-only form, or if this form has been submitted with method="GET" and no checkbox was checked.

I think it would not be possible to tell the two situations apart. Look at this test:

public function testSubmitSimpleCheckboxFormWithEmptyData($method)
{
$form = $this->factory->createNamed('checkbox', CheckboxType::class, true, [
'method' => $method,
]);
$this->setRequestData($method, []);
$this->requestHandler->handleRequest($form, $this->request);
$this->assertFalse($form->getData());
}

@nicolas-grekas nicolas-grekas modified the milestones: 6.2, 6.3 Nov 5, 2022
@nicolas-grekas nicolas-grekas modified the milestones: 6.3, 6.4 May 23, 2023
@nicolas-grekas nicolas-grekas modified the milestones: 6.4, 7.1 Nov 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cannot uncheck checkbox field mapped to the entity
8 participants