Skip to content
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

Valid Constraints multiple groups apply only on one #27257

Closed
gregoirepaqueron opened this issue May 14, 2018 · 5 comments
Closed

Valid Constraints multiple groups apply only on one #27257

gregoirepaqueron opened this issue May 14, 2018 · 5 comments

Comments

@gregoirepaqueron
Copy link

Symfony version(s) affected: 3.4.8

I have a parent Entity with many childrens Entities. I have 2 groups of validations Default and final.
The goal is to use only the group Default through a non-restrictive form, in order to valid the integrity of datum sent, then on the last page, display all the errors message more restrictive, with combining the 2 groups.
When i'm trying to validate on the 2 groups, i'm adding the 2 groups to Valid() constraint, but only 1 is applied.

Exemple :

Mandate.php

    /**
     * @var Customer[]|Collection
     * @Assert\Count(min="1", groups={"final"})
     * @Assert\Valid(groups={"Default", "final"})
     * @ORM\OneToMany(targetEntity="Customer", mappedBy="mandate", cascade={"persist", "remove"})
     */
    protected $customers;

Customer.php

    /**
     * @var string
     * @Assert\Length(max=80)
     * @Assert\Email()
     * @Assert\NotBlank(groups={"final"})
     * @ORM\Column(type="string", nullable=true)
     */
    protected $email;

    /**
     * @var string
     * @Assert\Length(max=40)
     * @Assert\NotBlank(groups={"final"})
     * @ORM\Column(type="string", nullable=true)
     */
    protected $firstName;

CustomerController.php

    /**
     * @param ValidatorInterface $validator
     * @param Mandate $mandate
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function summaryAction(ValidatorInterface $validator, Mandate $mandate)
    {
        $errors = $validator->validate($mandate, null, ['Default', 'final']);
        ...
    }

I forced in database that $firstName = null and $email = "notvalidemail"
In the $errors list, i will find only that the email is incorrect, but not that the firstname should be not null.
So, only the group Default is applied.

@HeahDude
Copy link
Contributor

Hello @gregoirepaqueron, thank you for reporting this issue.
AFAICS It could be a bug, in the meantime using:

/**
     * @var Customer[]|Collection
     * @Assert\Count(min="1", groups={"final"})
     * @Assert\Valid(groups={"Customer", "final"})
     * @ORM\OneToMany(targetEntity="Customer", mappedBy="mandate", cascade={"persist", "remove"})
     */
    protected $customers;

may fix your issue.

@HeahDude
Copy link
Contributor

Of course you need to add the Customer group to the validate method too, so passing three groups: ['Default', 'Customer', 'final'].

The reason is that Valid is a composite constraint and the default group of Customer is not a subset of the default group aliasing Mandate in your case.

I don't know if we really want to support the case though, maybe we could better document it.

ping @xabbuh

@xabbuh
Copy link
Member

xabbuh commented May 14, 2018

Without diving into this very much it seems to me that this issue is caused by the same cache mechanism that also causes #17675 and #26205.

@HeahDude
Copy link
Contributor

HeahDude commented Aug 4, 2018

No the problem comes from the Valid constraint using groups on the doctrine collection not on the entities it contains because the collection does not have constraints, nor groups.
To use groups on a collection, you should either use All or Collection constraints but they cannot contain Valid.
If you want to use Valid to validate nested entities in a "model" collection just define validation groups in the nested class or its properties and they will be used as they always have been.
To use groups with Valid it must be a nested entity, not an entity nested in a class you do not configure (i.e a doctrine collection), so in a doctrine entity context either a OneToOne or a ManyToOne property.

@xabbuh
Copy link
Member

xabbuh commented Sep 24, 2018

Indeed, I missed the point that the $customers is a collection object. I agree with @HeahDude that we should rather improve the documentation for this. Thus, I am closing here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants