2011-10-31 5 views
4

젠드 프레임 워크 애플리케이션에서 Doctrine 2를 사용하고 있으며 Zend_Validate_Db_RecordExists 및 Zend_Validate_Db_NoRecordExists와 비슷한 기능이 필요합니다.Doctrine 2에 Zend_Validate_Db_RecordExists가 있습니까?

예를 들어 사용자가 새 항목을 입력하면 중복 항목이 아직 존재하지 않는지 확인해야합니다. 이것은 내 양식에 Db_NoRecordExists 검사기를 추가하여 Zend_Db로 쉽게 수행 할 수 있습니다.

here 제안 된 사용자 정의 유효성 검사 솔루션을 구현하려했지만 Doctrine과 통신하여 엔티티를 검색하는 방법을 알 수 없습니다.이 방법은 더 이상 Doctrine 1.x 이후에는 작동하지 않습니다.

Doctrine 매뉴얼의 FAQ 섹션은 클라이언트 코드에서 contains()를 호출하는 것을 제안하지만 컬렉션에만 적용되며 가능한 경우 가능한 모든 양식 유효성 검사를 양식 모델에서 일관되게 처리하고 싶습니다.

누구나 Doctrine 2 DBAL을 데이터베이스 연결/리소스로 구성하여 이러한 Zend 검사기를 사용하는 방법을 제안 할 수 있습니까? 내 프로젝트에서 RecordExists.php 및 NoRecordExists.php 클래스 밖으로

+0

지금까지 두 응답자 덕분입니다. 두 코드 모두 공부하기 - 저는 여전히 ZF에서 플러그인/사용자 정의 클래스를 사용하는 것에 익숙합니다. 일단 내가 뭔가를 얻을 대답을 선택합니다. – cantera

답변

3

정말 아주 간단합니다.

Doctrine ORM과 대화하는 몇 가지 Zend_Validate 유형 검사기가 있으므로이 클래스는 하위 클래스에서 파생 된 추상 클래스를 가지고 있습니다.

여기 추상 클래스입니다 : 여기

<?php 
namespace TimDev\Validate\Doctrine; 

abstract class AbstractValidator extends \Zend_Validate_Abstract{ 
    /** 
    * @var Doctrine\ORM\EntityManager 
    */ 
    private $_em; 


    public function __construct(\Doctrine\ORM\EntityManager $em){ 
    $this->_em = $em; 
    } 

    public function em(){ 
    return $this->_em; 
    } 
} 

의 내 NoEntityExists 검사기 : (위의 추상 클래스와 같은 전각() 메소드가)를 Zend_Form의 맥락에서 사용

<?php 
namespace TimDev\Validate\Doctrine; 

class NoEntityExists extends AbstractValidator{ 

    private $_ec = null; 
    private $_property = null; 
    private $_exclude = null; 

    const ERROR_ENTITY_EXISTS = 1; 

    protected $_messageTemplates = array(
    self::ERROR_ENTITY_EXISTS => 'Another record already contains %value%' 
); 

    public function __construct($opts){ 
    $this->_ec = $opts['class']; 
    $this->_property = $opts['property']; 
    $this->_exclude = $opts['exclude']; 
    parent::__construct($opts['entityManager']); 

    } 

    public function getQuery(){ 
    $qb = $this->em()->createQueryBuilder(); 
    $qb->select('o') 
      ->from($this->_ec,'o') 
      ->where('o.' . $this->_property .'=:value'); 

    if ($this->_exclude !== null){ 
     if (is_array($this->_exclude)){ 

     foreach($this->_exclude as $k=>$ex){      
      $qb->andWhere('o.' . $ex['property'] .' != :value'.$k); 
      $qb->setParameter('value'.$k,$ex['value'] ? $ex['value'] : ''); 
     } 
     } 
    } 
    $query = $qb->getQuery(); 
    return $query; 
    } 
    public function isValid($value){ 
    $valid = true; 

    $this->_setValue($value); 

    $query = $this->getQuery(); 
    $query->setParameter("value", $value); 

    $result = $query->execute(); 

    if (count($result)){ 
     $valid = false; 
     $this->_error(self::ERROR_ENTITY_EXISTS); 
    } 
    return $valid; 

    } 
} 

:

/** 
    * Overrides superclass method to add just-in-time validation for NoEntityExists-type validators that 
    * rely on knowing the id of the entity in question. 
    * @param type $data 
    * @return type 
    */ 
    public function isValid($data) { 
    $unameUnique = new NoEntityExists(
        array('entityManager' => $this->em(), 
         'class' => 'PMS\Entity\User', 
         'property' => 'username', 
         'exclude' => array(
          array('property' => 'id', 'value' => $this->getValue('id')) 
         ) 
        ) 
    ); 
    $unameUnique->setMessage('Another user already has username "%value%"', NoEntityExists::ERROR_ENTITY_EXISTS); 

    $this->getElement('username')->addValidator($unameUnique); 

    return parent::isValid($data); 
} 
+0

두 응답자 모두에게 감사드립니다. 유효성 확인 요구 사항에 사용하기 위해 변형 된 timdev 코드를 사용했습니다. – cantera