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

Commitadb9016

Browse files
filiplikavcannicolas-grekas
authored andcommitted
[Form] Missing Data Handling (checkbox)
1 parent9f5238d commitadb9016

File tree

4 files changed

+192
-10
lines changed

4 files changed

+192
-10
lines changed

‎src/Symfony/Component/Form/Extension/HttpFoundation/HttpFoundationRequestHandler.php

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
useSymfony\Component\Form\Exception\UnexpectedTypeException;
1515
useSymfony\Component\Form\FormError;
1616
useSymfony\Component\Form\FormInterface;
17+
useSymfony\Component\Form\MissingDataHandler;
1718
useSymfony\Component\Form\RequestHandlerInterface;
1819
useSymfony\Component\Form\Util\ServerParams;
1920
useSymfony\Component\HttpFoundation\File\File;
@@ -29,10 +30,12 @@
2930
class HttpFoundationRequestHandlerimplements RequestHandlerInterface
3031
{
3132
private$serverParams;
33+
privateMissingDataHandler$missingDataHandler;
3234

3335
publicfunction__construct(ServerParams$serverParams =null)
3436
{
3537
$this->serverParams =$serverParams ??newServerParams();
38+
$this->missingDataHandler =newMissingDataHandler();
3639
}
3740

3841
/**
@@ -57,13 +60,13 @@ public function handleRequest(FormInterface $form, $request = null)
5760
if ('' ===$name) {
5861
$data =$request->query->all();
5962
}else {
60-
// Don't submit GET requests if the form's name does not exist
61-
// in the request
62-
if (!$request->query->has($name)) {
63+
$missingData =$this->missingDataHandler->missingData;
64+
65+
if ($missingData ===$data =$request->query->get($name) ??$missingData) {
66+
// Don't submit GET requests if the form's name does not exist
67+
// in the request
6368
return;
6469
}
65-
66-
$data =$request->query->get($name);
6770
}
6871
}else {
6972
// Mark the form with an error if the uploaded size was too large
@@ -90,6 +93,15 @@ public function handleRequest(FormInterface $form, $request = null)
9093
$params =$request->request->get($name,$default);
9194
$files =$request->files->get($name,$default);
9295
}else {
96+
$params =$this->missingDataHandler->missingData;
97+
$files =null;
98+
}
99+
100+
if ('PATCH' !==$method) {
101+
$params =$this->missingDataHandler->handle($form,$params);
102+
}
103+
104+
if ($this->missingDataHandler->missingData ===$params) {
93105
// Don't submit the form if it is not present in the request
94106
return;
95107
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Form;
13+
14+
useSymfony\Component\Form\Extension\Core\Type\CheckboxType;
15+
useSymfony\Component\Form\FormInterface;
16+
useSymfony\Component\Form\ResolvedFormTypeInterface;
17+
18+
class MissingDataHandler
19+
{
20+
publicreadonly\stdClass$missingData;
21+
22+
publicfunction__construct()
23+
{
24+
$this->missingData =new \stdClass();
25+
}
26+
27+
publicfunctionhandle(FormInterface$form,mixed$data):mixed
28+
{
29+
$processedData =$this->handleMissingData($form,$data);
30+
31+
return$processedData ===$this->missingData ?$data :$processedData;
32+
}
33+
34+
privatefunctionhandleMissingData(FormInterface$form,mixed$data):mixed
35+
{
36+
if ($form->getConfig()->getType()instanceof ResolvedFormTypeInterface &&$form->getConfig()->getType()->getInnerType()instanceof CheckboxType) {
37+
$falseValues =$form->getConfig()->getOption('false_values');
38+
39+
if ($data ===$this->missingData) {
40+
return$falseValues[0];
41+
}
42+
43+
if (\in_array($data,$falseValues)) {
44+
return$data;
45+
}
46+
}
47+
48+
if (null ===$data ||$this->missingData ===$data) {
49+
$data =$form->getConfig()->getCompound() ? [] :$data;
50+
}
51+
52+
if (\is_array($data)) {
53+
$children =$form->getConfig()->getCompound() ?$form->all() : [$form];
54+
55+
foreach ($childrenas$child) {
56+
$value =$this->handleMissingData($child,\array_key_exists($child->getName(),$data) ?$data[$child->getName()] :$this->missingData);
57+
58+
if ($this->missingData !==$value) {
59+
$data[$child->getName()] =$value;
60+
}
61+
}
62+
63+
return$data ?:$this->missingData;
64+
}
65+
66+
return$data;
67+
}
68+
}

‎src/Symfony/Component/Form/NativeRequestHandler.php

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespaceSymfony\Component\Form;
1313

1414
useSymfony\Component\Form\Exception\UnexpectedTypeException;
15+
useSymfony\Component\Form\MissingDataHandler;
1516
useSymfony\Component\Form\Util\ServerParams;
1617

1718
/**
@@ -22,6 +23,7 @@
2223
class NativeRequestHandlerimplements RequestHandlerInterface
2324
{
2425
private$serverParams;
26+
privateMissingDataHandler$missingDataHandler;
2527

2628
/**
2729
* The allowed keys of the $_FILES array.
@@ -37,6 +39,7 @@ class NativeRequestHandler implements RequestHandlerInterface
3739
publicfunction__construct(ServerParams$params =null)
3840
{
3941
$this->serverParams =$params ??newServerParams();
42+
$this->missingDataHandler =newMissingDataHandler();
4043
}
4144

4245
/**
@@ -63,13 +66,13 @@ public function handleRequest(FormInterface $form, $request = null)
6366
if ('' ===$name) {
6467
$data =$_GET;
6568
}else {
66-
// Don't submit GET requests if the form's name does not exist
67-
// in the request
68-
if (!isset($_GET[$name])) {
69+
$missingData =$this->missingDataHandler->missingData;
70+
71+
if ($missingData ===$data =$this->missingDataHandler->handle($form,$_GET[$name] ??$missingData)) {
72+
// Don't submit GET requests if the form's name does not exist
73+
// in the request
6974
return;
7075
}
71-
72-
$data =$_GET[$name];
7376
}
7477
}else {
7578
// Mark the form with an error if the uploaded size was too large
@@ -101,6 +104,15 @@ public function handleRequest(FormInterface $form, $request = null)
101104
$params =\array_key_exists($name,$_POST) ?$_POST[$name] :$default;
102105
$files =\array_key_exists($name,$fixedFiles) ?$fixedFiles[$name] :$default;
103106
}else {
107+
$params =$this->missingDataHandler->missingData;
108+
$files =null;
109+
}
110+
111+
if ('PATCH' !==$method) {
112+
$params =$this->missingDataHandler->handle($form,$params);
113+
}
114+
115+
if ($this->missingDataHandler->missingData ===$params) {
104116
// Don't submit the form if it is not present in the request
105117
return;
106118
}

‎src/Symfony/Component/Form/Tests/AbstractRequestHandlerTest.php

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
usePHPUnit\Framework\TestCase;
1515
useSymfony\Component\EventDispatcher\EventDispatcher;
1616
useSymfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
17+
useSymfony\Component\Form\Extension\Core\Type\CheckboxType;
18+
useSymfony\Component\Form\Extension\Core\Type\CollectionType;
19+
useSymfony\Component\Form\Extension\Core\Type\FormType;
1720
useSymfony\Component\Form\Form;
1821
useSymfony\Component\Form\FormBuilder;
1922
useSymfony\Component\Form\FormError;
@@ -64,6 +67,93 @@ public function getNormalizedIniPostMaxSize(): string
6467
$this->request =null;
6568
}
6669

70+
/**
71+
* @dataProvider methodExceptPatchProvider
72+
*/
73+
publicfunctiontestSubmitCheckboxInCollectionFormWithEmptyData($method)
74+
{
75+
$form =$this->factory->create(CollectionType::class, [true,false,true], [
76+
'entry_type' => CheckboxType::class,
77+
'method' =>$method,
78+
]);
79+
80+
$this->setRequestData($method, [
81+
]);
82+
83+
$this->requestHandler->handleRequest($form,$this->request);
84+
85+
$this->assertEqualsCanonicalizing([false,false,false],$form->getData());
86+
}
87+
88+
/**
89+
* @dataProvider methodExceptPatchProvider
90+
*/
91+
publicfunctiontestSubmitCheckboxInCollectionFormWithPartialData($method)
92+
{
93+
$form =$this->factory->create(CollectionType::class, [true,false,true], [
94+
'entry_type' => CheckboxType::class,
95+
'method' =>$method,
96+
]);
97+
98+
$this->setRequestData($method, [
99+
'collection' => [
100+
1 =>true,
101+
],
102+
]);
103+
104+
$this->requestHandler->handleRequest($form,$this->request);
105+
106+
$this->assertEqualsCanonicalizing([false,true,false],$form->getData());
107+
}
108+
109+
/**
110+
* @dataProvider methodExceptPatchProvider
111+
*/
112+
publicfunctiontestSubmitCheckboxFormWithEmptyData($method)
113+
{
114+
$form =$this->factory->create(FormType::class, ['subform' => ['checkbox' =>true]], [
115+
'method' =>$method,
116+
])
117+
->add('subform', FormType::class, [
118+
'compound' =>true,
119+
]);
120+
121+
$form->get('subform')
122+
->add('checkbox', CheckboxType::class);
123+
124+
$this->setRequestData($method, []);
125+
126+
$this->requestHandler->handleRequest($form,$this->request);
127+
128+
$this->assertEquals(['subform' => ['checkbox' =>false]],$form->getData());
129+
}
130+
131+
/**
132+
* @dataProvider methodExceptPatchProvider
133+
*/
134+
publicfunctiontestSubmitSimpleCheckboxFormWithEmptyData($method)
135+
{
136+
$form =$this->factory->createNamed('checkbox', CheckboxType::class,true, [
137+
'method' =>$method,
138+
]);
139+
140+
$this->setRequestData($method, []);
141+
142+
$this->requestHandler->handleRequest($form,$this->request);
143+
144+
$this->assertFalse($form->getData());
145+
}
146+
147+
publicfunctionmethodExceptPatchProvider()
148+
{
149+
return [
150+
['POST'],
151+
['PUT'],
152+
['DELETE'],
153+
['GET'],
154+
];
155+
}
156+
67157
publicfunctionmethodExceptGetProvider()
68158
{
69159
return [

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp