2

I'm currently working on performing some custom validation to an entity using constraints (also custom ones) and the validator component. I want to get the specified constraints to an Entity by group to apply the correct constraints group.

I saw this old question for Symfony 2 and seems it doesn't work in Symfony 4.

The entity User.php:

class User
{
    private $id;
    private $email;
    private $origin;

   ...
}

The configured constraints in a validation.yaml file:

App\Domain\User:
  properties:
    origin:
      - NotBlank: { groups: [user_create] }
      - NotNull: { groups: [user_update] }

The validation process:

// Get the component by injection and gets valid metadata
// Also gets the validation groups user_* for origin field
$metadata = $this->validator->getMetadataFor(User::class);

// This returns an empty array
$constraints = $metadata->findConstraints('user_create');

// This also returns an empty array
$constraints = $metadata->findConstraints('Default');

// Empty violations because constraints are empty
$violations = $this->validator->validate($leadRequest, $constraints, 'user_create');

Dump of $metadata:

ClassMetadata^ {#1551
  +name: "App\Domain\User"
  +defaultGroup: "User"
  +members: array:11 [
    "origin" => array:1 [
      0 => PropertyMetadata^ {#2472
        +class: "App\Domain\User"
        +name: "origin"
        +property: "origin"
        -reflMember: array:1 [
          "App\Domain\User" => ReflectionProperty {#2223
            +name: "origin"
            +class: "App\Domain\User"
            modifiers: "private"
          }
        ]
        +constraints: array:4 [
          0 => NotBlank^ {#5590
            +message: "This value should not be blank."
            +allowNull: false
            +normalizer: null
            +payload: null
            +"groups": array:1 [
              0 => "user_create"
            ]
          }
          1 => NotNull^ {#5567
            +message: "This value should not be null."
            +payload: null
            +"groups": array:1 [
              0 => "user_update"
            ]
          }

...

There is not any documentation about this feature so maybe this method is no longer valid or I'm doing something wrong.

Thank you for your help.

10
  • Maybe cache clear ? where is your validation.yaml file ? Commented Jul 25, 2019 at 10:35
  • 1
    Why don't you simply call $this->validator->validate($leadRequest, null, 'user_create');? I mean, if you need to perform a validation against a particular "group", just use it. The $constraints field could be useful only if you need a "sub-set" of constraint under the same "group" Commented Jul 25, 2019 at 10:37
  • @VincentDecaux The cache clear trick doesn't make any changes and the validation file is in config/validator/validation.yaml as said in the validator docs. Commented Jul 25, 2019 at 10:39
  • Is your User.php in the right namespace? And did you enable the validation as shown in symfony.com/doc/current/validation.html#configuration Commented Jul 25, 2019 at 10:41
  • @DonCallisto That method works correctly but I need to perform some operations with the same constraints, that's why I need to get them. Commented Jul 25, 2019 at 10:42

1 Answer 1

1

I think you must define what property you want to get constraint for.

This code works :

dd($metadata->properties['origin']->getConstraints());

But :

dd($metadata->getConstraints());

will return an empty array as well.

You can build your own group array :

$groups = [];
foreach ($metadata->properties as $property) {
    $constraints = $property->getConstraints();

    foreach ($constraints as $constraint) {
        foreach ($constraint->groups as $group) {
            $groups[$group] []= $constraint;
        }
    }
}
dd($groups);
Sign up to request clarification or add additional context in comments.

3 Comments

It works but then I should iterate over all properties and the main issue is not solved because I want to get the constraints by a specific group. Maybe I should create my own method but it seems to be already implemented in the GenericMetadata class. That's why it doesn't have much sense to me
You can build your own function so, iterating through all properties, then all constraints to find every constraint you want. See my update
Thank you. Definitively is working, it seems is a valid temporal solution. But it keeps bothering me that the findConstraints method should work but it doesn't. One issue of this solution is that in some custom constraints the $this->context->getObject() method returns null but I think is valid since the the constraints are manually built, using $this->context->getRoot() gives me the User object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.