use Symfony\Component\Validator\Constraints as Assert;
use App\Validator as AcmeAssert;
new Assert\Collection([
'product_id' => [
new Assert\NotBlank(),
new Assert\Type('integer'),
new AcmeAssert\TableRecordExists(Product::class)
],
new AcmeAssert\TableRecordExists(OrderProduct::class, [
'id' => $this->getRouteParam('orderProductId')
]);
<?php
namespace App\Validator;
use Symfony\Component\Validator\Constraint;
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
class TableRecordExists extends Constraint
{
public string $message = 'The value "{{ value }}" is not valid.';
public string $table = '';
public ?string $id = null;
public function __construct(string $table, $options = null, array $groups = null, $payload = null)
{
$options['table'] = $table;
parent::__construct($options, $groups, $payload);
}
public function getDefaultOption(): string
{
return 'table';
}
public function getRequiredOptions(): array
{
return ['table'];
}
}
<?php
namespace App\Validator;
use Doctrine\ORM\EntityNotFoundException;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
class TableRecordExistsValidator extends ConstraintValidator
{
private ManagerRegistry $managerRegistry;
public function __construct(ManagerRegistry $managerRegistry)
{
$this->managerRegistry = $managerRegistry;
}
public function validate($value, Constraint $constraint)
{
if (!$constraint instanceof TableRecordExists) {
throw new UnexpectedTypeException($constraint, TableRecordExists::class);
}
if (null === $value || '' === $value) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $value)
->addViolation();
} else {
if (is_null($this->managerRegistry->getRepository($constraint->table)->findOneBy([
'id' => $value ?? $constraint->id
]))) {
throw (new EntityNotFoundException())::fromClassNameAndIdentifier($constraint->table, [$value]);
}
}
}
}