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

Commitfbe76e9

Browse files
committed
[Form] Add constraints_from_* options
Apply constraints to field from an entity not mapped by the form data_class.Fix fabbot reviewFix changelog to 6.4
1 parent4813d66 commitfbe76e9

File tree

4 files changed

+181
-0
lines changed

4 files changed

+181
-0
lines changed

‎src/Symfony/Component/Form/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
CHANGELOG
22
=========
33

4+
6.4
5+
---
6+
* Add`constraints_from_entity` and`constraints_from_property` option to`FormType`
7+
48
6.3
59
---
610

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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\Extension\Validator\EventListener;
13+
14+
useSymfony\Component\EventDispatcher\EventSubscriberInterface;
15+
useSymfony\Component\Form\FormError;
16+
useSymfony\Component\Form\FormEvent;
17+
useSymfony\Component\Form\FormEvents;
18+
useSymfony\Component\Validator\ConstraintViolationInterface;
19+
useSymfony\Component\Validator\Validator\ValidatorInterface;
20+
21+
class ConstraintsFromListenerimplements EventSubscriberInterface
22+
{
23+
privateValidatorInterface$validator;
24+
25+
publicstaticfunctiongetSubscribedEvents():array
26+
{
27+
return [FormEvents::POST_SUBMIT =>'validateConstraints'];
28+
}
29+
30+
publicfunction__construct(ValidatorInterface$validator)
31+
{
32+
$this->validator =$validator;
33+
}
34+
35+
publicfunctionvalidateConstraints(FormEvent$event):void
36+
{
37+
$form =$event->getForm();
38+
39+
$entity =$form->getConfig()->getOption('constraints_from_entity');
40+
41+
if (null !==$entity) {
42+
$property =$form->getConfig()->getOption('constraints_from_property') ??$form->getName();
43+
44+
$violations =$this->validator->validatePropertyValue($entity,$property,$event->getData());
45+
/** @var ConstraintViolationInterface $violation */
46+
foreach ($violationsas$violation) {
47+
$form->addError(
48+
newFormError(
49+
$violation->getMessage(),
50+
$violation->getMessageTemplate(),
51+
$violation->getParameters(),
52+
$violation->getPlural()
53+
)
54+
);
55+
}
56+
}
57+
}
58+
}

‎src/Symfony/Component/Form/Extension/Validator/Type/FormTypeValidatorExtension.php

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

1414
useSymfony\Component\Form\Extension\Core\Type\FormType;
15+
useSymfony\Component\Form\Extension\Validator\EventListener\ConstraintsFromListener;
1516
useSymfony\Component\Form\Extension\Validator\EventListener\ValidationListener;
1617
useSymfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapper;
1718
useSymfony\Component\Form\FormBuilderInterface;
@@ -42,6 +43,7 @@ public function __construct(ValidatorInterface $validator, bool $legacyErrorMess
4243
*/
4344
publicfunctionbuildForm(FormBuilderInterface$builder,array$options)
4445
{
46+
$builder->addEventSubscriber(newConstraintsFromListener($this->validator));
4547
$builder->addEventSubscriber(newValidationListener($this->validator,$this->violationMapper));
4648
}
4749

@@ -58,13 +60,17 @@ public function configureOptions(OptionsResolver $resolver)
5860
$resolver->setDefaults([
5961
'error_mapping' => [],
6062
'constraints' => [],
63+
'constraints_from_entity' =>null,
64+
'constraints_from_property' =>null,
6165
'invalid_message' =>'This value is not valid.',
6266
'invalid_message_parameters' => [],
6367
'allow_extra_fields' =>false,
6468
'extra_fields_message' =>'This form should not contain extra fields.',
6569
]);
6670
$resolver->setAllowedTypes('constraints', [Constraint::class, Constraint::class.'[]']);
6771
$resolver->setNormalizer('constraints',$constraintsNormalizer);
72+
$resolver->setAllowedTypes('constraints_from_entity', ['string','null']);
73+
$resolver->setAllowedTypes('constraints_from_property', ['string','null']);
6874
}
6975

7076
publicstaticfunctiongetExtendedTypes():iterable

‎src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,119 @@ public function testInvalidMessage()
154154
$this->assertEquals('This value is not valid.',$form->getConfig()->getOption('invalid_message'));
155155
}
156156

157+
publicfunctiontestConstraintsFromEntityValid()
158+
{
159+
// Maps firstName field to Author::firstName -> Length(3) constraint
160+
$form =$this->createFormForConstraintsFrom();
161+
162+
$form->submit(['firstName' =>'foo']);
163+
164+
$errors =$form->getErrors(true);
165+
166+
$this->assertCount(0,$errors);
167+
}
168+
169+
publicfunctiontestConstraintsFromEntityEmpty()
170+
{
171+
// Maps firstName field to Author::firstName -> Length(3) constraint
172+
$form =$this->createFormForConstraintsFrom();
173+
174+
$form->submit(['firstName' =>'']);
175+
176+
$errors =$form->getErrors(true);
177+
178+
$this->assertCount(1,$errors);
179+
}
180+
181+
publicfunctiontestConstraintsFromEntityInvalid()
182+
{
183+
// Maps firstName field to Author::firstName -> Length(3) constraint
184+
$form =$this->createFormForConstraintsFrom();
185+
186+
$form->submit(['firstName' =>'foobar']);
187+
188+
$errors =$form->getErrors(true);
189+
190+
$this->assertCount(1,$errors);
191+
}
192+
193+
publicfunctiontestConstraintsFromEntityCustomPropertyValid()
194+
{
195+
// Maps firstName field to Author::lastName -> Length(min: 5) constraint
196+
$form =$this->createFormForConstraintsFrom('lastName');
197+
198+
$form->submit(['firstName' =>'foobar']);
199+
200+
$errors =$form->getErrors(true);
201+
202+
$this->assertCount(0,$errors);
203+
}
204+
205+
publicfunctiontestConstraintsFromEntityCustomPropertyEmpty()
206+
{
207+
// Maps firstName field to Author::lastName -> Length(min: 5) constraint
208+
$form =$this->createFormForConstraintsFrom('lastName');
209+
210+
$form->submit(['firstName' =>'']);
211+
212+
$errors =$form->getErrors(true);
213+
214+
$this->assertCount(1,$errors);
215+
}
216+
217+
publicfunctiontestConstraintsFromEntityCustomPropertyInvalid()
218+
{
219+
// Maps firstName field to Author::lastName -> Length(min: 5) constraint
220+
$form =$this->createFormForConstraintsFrom('lastName');
221+
222+
$form->submit(['firstName' =>'foo']);
223+
224+
$errors =$form->getErrors(true);
225+
226+
$this->assertCount(1,$errors);
227+
}
228+
229+
protectedfunctioncreateFormForConstraintsFrom(string$propertyName =null)
230+
{
231+
$formMetadata =newClassMetadata(Form::class);
232+
$authorMetadata = (newClassMetadata(Author::class))
233+
->addPropertyConstraint('firstName',newLength(3))
234+
->addPropertyConstraint('lastName',newLength(min:5))
235+
;
236+
$metadataFactory =$this->createMock(MetadataFactoryInterface::class);
237+
$metadataFactory->expects($this->any())
238+
->method('getMetadataFor')
239+
->willReturnCallback(staticfunction ($classOrObject)use ($formMetadata,$authorMetadata) {
240+
if (Author::class ===$classOrObject ||$classOrObjectinstanceof Author) {
241+
return$authorMetadata;
242+
}
243+
244+
if (Form::class ===$classOrObject ||$classOrObjectinstanceof Form) {
245+
return$formMetadata;
246+
}
247+
248+
returnnewClassMetadata(\is_string($classOrObject) ?$classOrObject :$classOrObject::class);
249+
})
250+
;
251+
252+
$validator = Validation::createValidatorBuilder()
253+
->setMetadataFactory($metadataFactory)
254+
->getValidator()
255+
;
256+
257+
$form = Forms::createFormFactoryBuilder()
258+
->addExtension(newValidatorExtension($validator))
259+
->getFormFactory()
260+
->create(FormTypeTest::TESTED_TYPE)
261+
->add('firstName', TextTypeTest::TESTED_TYPE, [
262+
'constraints_from_entity' => Author::class,
263+
'constraints_from_property' =>$propertyName ??null,
264+
])
265+
;
266+
267+
return$form;
268+
}
269+
157270
protectedfunctioncreateForm(array$options = [])
158271
{
159272
return$this->factory->create(FormTypeTest::TESTED_TYPE,null,$options);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp