bug #30062 [Form] do not overwrite the constraint being evaluated (xabbuh)

This PR was merged into the 3.4 branch.

Discussion
----------

[Form] do not overwrite the constraint being evaluated

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #27362
| License       | MIT
| Doc PR        |

Commits
-------

345a6329dd do not overwrite the constraint being evaluated
This commit is contained in:
Nicolas Grekas 2019-02-07 09:55:37 +01:00
commit 6fa8d07902
2 changed files with 32 additions and 7 deletions

View File

@ -26,10 +26,10 @@ class FormValidator extends ConstraintValidator
/**
* {@inheritdoc}
*/
public function validate($form, Constraint $constraint)
public function validate($form, Constraint $formConstraint)
{
if (!$constraint instanceof Form) {
throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Form');
if (!$formConstraint instanceof Form) {
throw new UnexpectedTypeException($formConstraint, __NAMESPACE__.'\Form');
}
if (!$form instanceof FormInterface) {
@ -62,8 +62,8 @@ class FormValidator extends ConstraintValidator
// Otherwise validate a constraint only once for the first
// matching group
foreach ($groups as $group) {
if (\in_array($group, $constraint->groups)) {
$validator->atPath('data')->validate($form->getData(), $constraint, $group);
if (\in_array($group, $formConstraint->groups)) {
$validator->atPath('data')->validate($form->getData(), $formConstraint, $group);
if (\count($this->context->getViolations()) > 0) {
break;
}
@ -113,7 +113,7 @@ class FormValidator extends ConstraintValidator
? (string) $form->getViewData()
: \gettype($form->getViewData());
$this->context->setConstraint($constraint);
$this->context->setConstraint($formConstraint);
$this->context->buildViolation($config->getOption('invalid_message'))
->setParameters(array_replace(['{{ value }}' => $clientDataAsString], $config->getOption('invalid_message_parameters')))
->setInvalidValue($form->getViewData())
@ -125,7 +125,7 @@ class FormValidator extends ConstraintValidator
// Mark the form with an error if it contains extra fields
if (!$config->getOption('allow_extra_fields') && \count($form->getExtraData()) > 0) {
$this->context->setConstraint($constraint);
$this->context->setConstraint($formConstraint);
$this->context->buildViolation($config->getOption('extra_fields_message'))
->setParameter('{{ extra_fields }}', '"'.implode('", "', array_keys($form->getExtraData())).'"')
->setInvalidValue($form->getExtraData())

View File

@ -13,16 +13,20 @@ namespace Symfony\Component\Form\Tests\Extension\Validator\Constraints;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
use Symfony\Component\Form\Extension\Validator\Constraints\Form;
use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\SubmitButtonBuilder;
use Symfony\Component\Translation\IdentityTranslator;
use Symfony\Component\Validator\Constraints\GroupSequence;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\NotNull;
use Symfony\Component\Validator\Constraints\Valid;
use Symfony\Component\Validator\Context\ExecutionContext;
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
use Symfony\Component\Validator\Validation;
/**
* @author Bernhard Schussek <bschussek@gmail.com>
@ -649,6 +653,27 @@ class FormValidatorTest extends ConstraintValidatorTestCase
return ['group1', 'group2'];
}
public function testCauseForNotAllowedExtraFieldsIsTheFormConstraint()
{
$form = $this
->getBuilder('form', null, ['constraints' => [new NotBlank(['groups' => ['foo']])]])
->setCompound(true)
->setDataMapper(new PropertyPathMapper())
->getForm();
$form->submit([
'extra_data' => 'foo',
]);
$context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator());
$constraint = new Form();
$this->validator->initialize($context);
$this->validator->validate($form, $constraint);
$this->assertCount(1, $context->getViolations());
$this->assertSame($constraint, $context->getViolations()->get(0)->getConstraint());
}
private function getMockExecutionContext()
{
$context = $this->getMockBuilder('Symfony\Component\Validator\Context\ExecutionContextInterface')->getMock();