-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Open
Description
Symfony version(s) affected
7.3
Description
I don't know if this is a bug or an expected behavior, but when a Compound
constraint containing a Composite
constraint is applied while specifying a validation group, this throws an exception:
The group(s) "Default" passed to the constraint "Symfony\Component\Validator\Constraints\Sequentially" should also be passed to its containing constraint "App\Validator\PasswordRequirement".
I was testing #60212, using yceruto/formflow-bundle, which rely on validation groups to validate steps.
How to reproduce
<?php
declare(strict_types=1);
namespace App\Validator;
use Symfony\Component\PasswordHasher\PasswordHasherInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Constraints\Compound;
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD)]
final class PasswordRequirement extends Compound
{
/**
* @param array<string, mixed> $options
*/
protected function getConstraints(array $options): array
{
return [
new Assert\Sequentially(
constraints: [
new Assert\NotBlank(),
new Assert\Type('string'),
new Assert\Length(min: 12),
new Assert\NotCompromisedPassword(),
new Assert\PasswordStrength(minScore: 4),
],
),
];
}
}
<?php
namespace App\Form\Data;
use App\Validator\EmailRequirement;
use App\Validator\PasswordRequirement;
class CredentialsDto
{
public function __construct(
#[EmailRequirement]
public ?string $email = null,
#[PasswordRequirement(groups: ['password'])]
public ?string $password = null,
) {
}
}
<?php
declare(strict_types=1);
namespace App\Form\Type;
use App\Form\Data\CredentialsDto;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class CredentialsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('email', EmailType::class)
->add('password', RepeatedType::class, [
'type' => PasswordType::class,
'first_options' => [
'label' => 'Password',
],
'second_options' => [
'label' => 'Confirm Password',
],
])
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => CredentialsDto::class,
'validation_groups' => ['Default', 'password'],
]);
}
}
Possible Solution
No response
Additional Context
If the Default
group is added to the list, the constraint is executed correctly:
#[PasswordRequirement(groups: [ 'Default', 'password'])] // this work
public ?string $password = null,