@soho350

Как создать собственный валидатор в symfony?

Как в symfony создать собственный валидатор? Я вроде читаю https://symfony.com/doc/4.4/validation/custom_cons... но чё то понять не могу. Мне нужен что бы валидация происходила через анотацию по типу такого.
/**
   * @Assert\NotBlank(message="Поле не должно быть пустым *")
   */
    private $name;

Допустим написать простой валидатор если private $name равняется 1 то вывести сообщение (message="Не должно равняться 1 *") . Думаю свой валидатор смысла кидать сюда нету.
  • Вопрос задан
  • 322 просмотра
Решения вопроса 1
Maksclub
@Maksclub
maksfedorov.ru
Я вроде читаю https://symfony.com/doc/4.4/validation/custom_cons... но чё то понять не могу.

/**
* @Annotation
*/
class ContainsAlphanumeric extends Constraint
{
public function validate($value, Constraint $constraint) {}
}


Небольшая путаница произошла по спешке: аннотация (констрейнт) — это одно, валидатор — другое, они связаны, но это две разные вещи одной системы.

Constraint — по сути выражение/аннотация, по которой будет срабатывать валидатор. Она принимает в себя некие параметры и содержит логику к чему применяться — к классу или филду класса.

Создаем свой констрейнт:
В нашем констрейнте мы планируем, что мы сможем передать некий дополнительный параметр размер, а если не передадим, то его значение будет 55 (ну так хотим). Причем это будет относиться не к кполю, которое валидируем, а именно к констрейнту, То есть то, что он отдаст валидатору. Ну например возраст или некий пинг,да что угодно, в общем ориентируясь на который валидатор применит некую логику.
/**
 * @Annotation
 */
final class AnyConstraint
{
    /**
     * @Required
     * @var int
     */
    public $size = 55;

    /**
     * Вот тут мы укажем некий валидатор, тот класс, который и будет валидировать наше значение
     * Дял удобства он будет называться также + слово Validator, в нашем случае AnyConstraintValidator
     */
    public function validatedBy()
    {
        return \get_class($this).'Validator';
    }
}


Создаем собственно валидатор
на который выше в методе validatedBy() мы уже указали

class AnyConstraintValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint): void
    {
        // Тут логика, при которой или все пройдет до return - все отлично
        // Или вообще исключение вывалится (если пришло чего-то не то)
        // Или (для чего и используется валидатор) создастся violation

        // например число в объекте больше того, которое мы указали в size (по дефолту если не указали: 55)
        if($value > $constraint->size) {
            $this->context->buildViolation('Тут пинг пришел вообще большой  —  такой нельзя, брат')
                ->setParameter('{{ string }}', $value)
                ->addViolation();
        }
    }
}


Используем:
class AnyEntity
{
    /**

     * Если значение больше 55  — то не пройдет валидацию
     * @AnyConstraint(120)
     */
    protected $name;
}


Помимо всего у констрейнта можно указать к чему применять — к методу, классу или к переменной класса
  • Через аннотацию у класса констрейнта: @Target({"PROPERTY", "METHOD", "ANNOTATION"})
  • Через метод переопределенный метод getTarget()
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы