2015-02-21 2 views
2

Я пытаюсь получить валидатор UniqueEntity от Symfony, работающий для моих объектов Doctrine. Symfony валидатор уже подключен и работает, UniqueEntity от Symfony \ Bridge, однако, является более сложной задачей, показывая эту ошибку:Использование Symfony UniqueEntity с Doctrine

PHP Fatal error: Class 'doctrine.orm.validator.unique' not found in /app/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactory.php on line 46 

Похоже, если ValidatorFactory запрашивает валидатор UniqueEntity из контейнера Symfony, которого у меня нет, потому что я не использую полный стек symfony.

Моя сущность выглядит следующим образом:

<?php 
namespace App\Model; 

use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Validator\Constraints as Assert; 
use Symfony\Bridge\Doctrine\Validator\Constraints as AssertDoctrine; 

/** 
* User 
* 
* @ORM\Table(name="users", uniqueConstraints={@ORM\UniqueConstraint(name="id_UNIQUE", columns={"id"}), @ORM\UniqueConstraint(name="username_UNIQUE", columns={"username"})}) 
* @ORM\Entity(repositoryClass="App\Repository\UserRepository") 
* @AssertDoctrine\UniqueEntity("username") 
*/ 
class User extends AbstractEntity 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    protected $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="username", type="string", length=45, unique=true, nullable=false) 
    * @Assert\Length(min=3, max=45) 
    */ 
    protected $username; 

    /** ... */ 
} 

где AbstractEntity является отображенная суперкласса, включая Trait, который обеспечивает функциональные возможности проверки для всех объектов:

<?php 
namespace App\Model\Traits; 

use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Validator\Validation; 
use App\Utility\Exception\ConstraintViolationException; 

/** 
* A trait enabling validation of Doctrine entities to ensure invalid entities 
* don't reach the persistence layer. 
*/ 
trait ValidatorAwareTrait 
{ 
    public function validate() 
    { 
     $validator = Validation::createValidatorBuilder() 
      ->enableAnnotationMapping() 
      ->getValidator(); 

     $violations = $validator->validate($this); 

     // Count is used as this is not an array but a ConstraintViolationList 
     if (count($violations) !== 0) { 
      $message = $violations[0]->getPropertyPath() . ': ' . $violations[0]->getMessage(); 
      throw new ConstraintViolationException($message); 
     } 
     return true; 
    } 
} 

ответ

0

Во-первых, вы должны проверить, если проверка включена в ваш config.yml:

framework: 
    validation:  { enable_annotations: true } 

Далее, убедитесь, что вы про смотри необходимый атрибут поля в вашей уникальной аннотацию:

@AssertDoctrine\UniqueEntity(fields={"username"}) 

Наконец, если предыдущие шаги еще терпят неудачу, вы можете предоставить свой собственный сервис уникальный валидатора (см original service for reference) в аннотации, как например:

@AssertDoctrine\UniqueEntity(fields={"username"}, 
service="use.my.unique.validator.service") 

Вы можете даже предоставить диспетчер объектов через em -option в этой аннотации.

3

Ref:

  1. DoctrineBridge\Validator\Constraints\UniqueEntity
  2. Symfony\Component\Validator\Constraint

У меня был такой же вопрос несколько месяцев назад.

Короткий ответ: вы не сможете использовать ValidatorEntity Validator без использования какого-либо типа DI, который перечисляет службу «doctrine.orm.validator.unique» и переводит его в Symfony \ Bridge \ Doctrine \ Validator \ Ограничения \ UniqueEntityValidator.

Длинный ответ: сообщение об ошибке, которое вы видите, является результатом того, что DoctrineBridge \ Validator \ Constraints \ UniqueEntity повторно использует Symfony \ Component \ Validator \ Constraint :: validatedBy(). Фактически, если вы просмотрите комментарий выше DoctrineBridge \ Validator \ Constraints \ UniqueEntity :: validatedBy(), вы увидите, что он указывает, что «валидатор должен быть определен как служба с этим именем», что приводит к тому, что этот валидатор как ожидается, будет использоваться с компонентом Symfony DependencyInjection.

Что не сразу видно, что имя службы, которое отображается в сообщении об ошибке фактически определено в Doctrine \ DoctrineBundle \ Resources \ Config \ Orm.xml

Извиняюсь за непредоставление ссылку файлы orm.xml и dbal.xml. Моя репутация в настоящее время не позволяет.

0
$validator = Validation::createValidatorBuilder() 
     ->setConstraintValidatorFactory($this->validatorFactory) 
     ->enableAnnotationMapping() 
     ->getValidator(); 

    $violations = $validator->validate($user); 

    if (count($violations) !== 0) { 
     $message = $violations[0]->getPropertyPath() . ': ' . $violations[0]->getMessage(); 
     throw new \Exception($message); 
    } 

    $this->entityManager->persist($user); 
    $this->entityManager->flush(); 

Где $ this-> validatorFactory это сервис @ validator.validator_factory '

+2

Могли бы вы предоставить некоторые детали? Ваш ответ - в основном код – jhhoff02

Смежные вопросы