Я вроде читаю 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()