Skip to content

[Form][Validator] Embedded entities are validated with the wrong validation groups #30094

Closed
@keichinger

Description

@keichinger

Symfony version(s) affected: At least 4.2.2 - 4.2.3

Description
Given the following data structure (noise like getter/setters, id properties, and some Doctrine annotations have been stripped in this paste):

class EntityA
{
    /**
     * @var string|null
     *
     * @Assert\NotBlank()
     */
    private $name;

    /**
     * @var EntityB|null
     *
     * Enable validation for nested entities
     * @Assert\Valid()
     */
    private $entityB;

    /**
     * @Assert\Callback()
     *
     * @param ExecutionContextInterface $executionContext
     */
    public function validateSomethingImportant (ExecutionContextInterface $executionContext) : void
    {
        // Called with the *CORRECT* validation groups
    }
}


class EntityB
{
    /**
     * @var string|null
     *
     * @Assert\NotBlank()
     */
    private $fieldA;

    /**
     * @var string|null
     *
     * @Assert\NotBlank(groups={"required_field_b"})
     */
    private $fieldB;

    /**
     * @Assert\Callback()
     *
     * @param ExecutionContextInterface $executionContext
     */
    public function validateRequiredFields (ExecutionContextInterface $executionContext) : void
    {
        // Called with the *WRONG* validation groups
    }
}

We end up with some unexpected behaviour inside the EntityB::validateRequiredFields method, which is called before EntityBForm's validation_groups are resolved. I wasn't expecting the callback validation to be run before the Form has determined which validation groups are important, which led in my case to some unexpected behaviour and could introduce bugs.

I was digging through some test codes which were testing for the correct validation groups, but not for an integration that makes sure they're called in the correct order, with the correct groups.

Am I missing something here or is this a bug?

How to reproduce
Reproducer: https://github.com/keichinger/symfony-validation-repro

Steps:

  1. After installing the project as usual (git clone, composer install, local webserver configs if necessary, etc.)
  2. Copy the .env to a .env.local and update the DB credentials
  3. Run php bin/console doctrine:schema:update --dump-sql --force, as I didn't create a migration
  4. Open the site in your browser, under / an unstyled form (class EntityAForm) is rendered
  5. Fill in arbitrary values and hit the submit button
  6. Inspect the debug code, which has been added to the validation_groups callback inside the forms and the @Assert/Callback validation callbacks inside the entities

It should look like this:
image

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions