如何获取带有唯一约束的错误消息

How to get an error message with a unique constraint

我有一个表格,其中为产品添加了参考号。我已将此字段设为唯一,因为不会有重复的参考编号。

我遇到的问题是,当我添加一个已经附加到另一个产品的参考号时,我 运行 进入异常 Integrity constraint violation: 1062 Duplicate entry for key 'reference'。相反,我希望表单向用户显示一条消息,通知他们引用已在使用中。

编辑:我创建了一个自定义验证器来检查给定的引用是否已经存在,但是我收到以下错误:

Type error: Too few arguments to function Backend\Modules\Glasses\Domain\Glasses\Validator\Constraints\DuplicateReferenceValidator::__construct(), 0 passed in /var/www/html/vendor/symfony/symfony/src/Symfony/Component/Validator/ContainerConstraintValidatorFactory.php on line 52 and exactly 1 expected

我似乎无法在 DuplicateReferenceValidator

中获取我的 GlassesRepository

数据传输对象:

<?php

namespace Backend\Modules\Glasses\Domain\Glasses;

use Backend\Modules\Glasses\Domain\Brand\Brand;
use Backend\Modules\MediaLibrary\Domain\MediaGroup\MediaGroup;
use Common\Doctrine\Entity\Meta;
use Symfony\Component\Validator\Constraints as Assert;
use Backend\Modules\Glasses\Domain\Glasses\Validator\Constraints as CustomAssert;

class GlassesDataTransferObject
{

/*** Other fields ***/

    /**
     * @var string
     *
     * @Assert\NotBlank(message="err.FieldIsRequired")
     * @CustomAssert\DuplicateReference
     */
    public $reference;

/*** Other fields ***/

DuplicateReference.php

<?php


namespace Backend\Modules\Glasses\Domain\Glasses\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
 * @Annotation
 */
class DuplicateReference extends Constraint
{
    public $message = '"{{ reference }}" already exists.';
}

DuplicateReferenceValidator.php

<?php


namespace Backend\Modules\Glasses\Domain\Glasses\Validator\Constraints;

use Backend\Modules\Glasses\Domain\Glasses\GlassesRepository;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;

class DuplicateReferenceValidator extends ConstraintValidator
{
    private $repository;

    /**
     * DuplicateUserValidator constructor.
     */
    public function __construct(GlassesRepository $repository)
    {
        $this->repository = $repository;
    }

    public function validate($value, Constraint $constraint)
    {
        if (!$constraint instanceof DuplicateReference) {
            throw new UnexpectedTypeException($constraint, DuplicateReference::class);
        }

        // custom constraints should ignore null and empty values to allow
        // other constraints (NotBlank, NotNull, etc.) take care of that
        if (null === $value || '' === $value) {
            return;
        }

        if (!is_string($value)) {
            // throw this exception if your validator cannot handle the passed type so that it can be marked as invalid
            throw new UnexpectedTypeException($value, 'string');
        }

        $qb = $this->repository->createQueryBuilder('g');

        $qb->select('g.reference')
            ->where('g.reference = :reference')
            ->setParameter('reference', $value);

        $match = $qb->getQuery()->execute();

        if ($match) {
            $this->context->buildViolation($constraint->message)
                ->setParameter('{{ reference }}', $value)
                ->addViolation();
        }
    }
}

我自己想出来了。

我需要将实体管理器添加到我的 services.yml 文件中,以便能够在验证程序中访问它。

Backend\Modules\Glasses\Domain\Glasses\Validator\Constraints\DuplicateReferenceValidator:
        attributes:
            - "@doctrine.orm.entity_manager"