8000 Compose validation · Issue #35226 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
Compose validation #35226
Closed
Closed
@JumpIfBelow

Description

@JumpIfBelow

Description
Creates a new composite constraint to validate a composition of constraints. The minumum and maximum validated should be set optionnaly.

Example
For example, there are two use case that could be easily answered with such a composition.

  1. When properties are exclusive to each other
/**
 * @Assert\Compose(
 *   constraints={
 *     @Assert\Expression("value.bar !== null"),
 *     @Assert\Expression("value.baz !== null"),
 *   },
 *   min=1,
 *   max=1,
 *   minMessage="One of $bar or $baz should be set.",
 *   maxMessage="Only one of $bar or $baz should be set.",
 * )
 */
class Foo {
  public $bar;
  public $baz;
}
  1. Password security rules
    Often there are security rules to enforce for a new password. Those are limited set, and not all of the rules are mandatory for a valid password. For example, we could have the rules with the following statement:
  • at least 8 characters long
  • at least 3 of those:
    • contains 1 lower case character
    • contains 1 upper case character
    • contains 1 digit
    • contains 1 special character

It is an issue to enforce that a password is complex enough in the current state. Allowing to compose constraints enables simpler code:

class User {
  /**
   * @Assert\Length(min=8)
   * @Assert\Compose(
   *   constraints={
   *     @Assert\Regex("/[a-z]/"),
   *     @Assert\Regex("/[A-Z]/"),
   *     @Assert\Regex("/\d/"),
   *     @Assert\Regex("/[,;:.!?]/"),
   *   },
   *   min=3,
   *   minMessage="The password must contains at least one of those 3 character: ...",
   * )
   */
  public string $password;
}

Basic code
To me, a Compose annotation could look like this:

/**
 * @Annotation
 * @Target({"CLASS", "PROPERTY", "METHOD", "ANNOTATION"})
 */
class Compose extends Composite
{
    /**
     * @var string $minMessage
     */
    public string $minMessage = 'compose.min';

    /**
     * @var string $maxMessage
     */
    public string $maxMessage = 'compose.max';

    /**
     * @var Constraint[] $constraints
     */
    public array $constraints = [];

    /**
     * @var int $min
     */
    public int $min = 0;

    /**
     * @var int|null $max
     */
    public ?int $max = null;

    public function getDefaultOption()
    {
        return $this->getCompositeOption();
    }

    public function getTargets()
    {
        return [
            static::CLASS_CONSTRAINT,
            static::PROPERTY_CONSTRAINT,
        ];
    }

    protected function getCompositeOption()
    {
        return 'constraints';
    }
}

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

      0