Zend_Validate_Db_Record существует с Doctrine 2? - PullRequest
4 голосов
/ 31 октября 2011

Я использую Doctrine 2 в приложении Zend Framework и мне требуется функциональность, аналогичная Zend_Validate_Db_RecordExists и Zend_Validate_Db_NoRecordExists.

Например, когда пользователь вводит новый элемент, мне нужно проверить, что повторяющаяся запись еще не существует. Это легко сделать с помощью Zend_Db, добавив в мои формы валидатор Db_NoRecordExists.

Я пытался реализовать предложенное решение для пользовательского валидатора , но не могу понять, как они взаимодействуют с Doctrine для извлечения сущностей (я подозреваю, что этот подход может больше не работать после Доктрины 1). х).

В разделе FAQ в руководстве по Doctrine предлагается вызывать метод includes () из клиентского кода, но это касается только коллекций, и, если возможно, я бы хотел последовательно обрабатывать все проверки моей формы изнутри моего формы моделей.

Может кто-нибудь предложить способ использования этих валидаторов Zend с DBAL Doctrine 2, настроенным в качестве соединения / ресурса базы данных?

Ответы [ 2 ]

3 голосов
/ 31 октября 2011

Это довольно просто, на самом деле.

У меня есть несколько валидаторов типа Zend_Validate, которые общаются с Doctrine ORM, поэтому у меня есть абстрактный класс, с которого они происходят.

Вот абстрактный класс:

<?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:

<?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;

  }
}

Используется в контексте Zend_Form (в котором есть метод em (), подобный абстрактному классу выше):

/**
   * 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);
}
2 голосов
/ 31 октября 2011

Проверьте классы RecordExists.php и NoRecordExists.php в моем проекте: -

https://github.com/andyfenna/AJF-IT/tree/master/library/AJFIT/Validate

Надеюсь, они вам пригодятся.

Спасибо

Andrew

...