Zend_Validate_Db_RecordExists with Doctrine 2?

China☆狼群 提交于 2019-12-12 09:42:35

问题


I'm using Doctrine 2 in a Zend Framework application and require functionality similar to Zend_Validate_Db_RecordExists and Zend_Validate_Db_NoRecordExists.

For example, when a user enters a new item, I need to validate that a duplicate entry doesn't already exist. This is easy to accomplish with Zend_Db by adding the Db_NoRecordExists validator on my forms.

I tried implementing the custom-validator solution proposed here, but I can't figure out how they are communicating with Doctrine to retrieve entities (I suspect this approach may no longer work post-Doctrine 1.x).

The FAQ section of the Doctrine manual suggests calling contains() from the client code, but this only covers collections, and if possible I'd like to handle all of my form validation consistently from within my form models.

Can anyone suggest a way to use these Zend validators with Doctrine 2 DBAL configured as the database connection/resource?


回答1:


It's quite straightforward, really.

I have a few Zend_Validate-type validators that talk to Doctrine ORM, so I have an abstract class that they descend from.

Here's the abstract class:

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

Here's my NoEntityExists validator:

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

  }
}

Used in the context of a Zend_Form (which has an em() method like the abstract class above):

/**
   * 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:


Check out the RecordExists.php and NoRecordExists.php classes in my project:-

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

I hope these are some use to you.

Thanks

Andrew



来源:https://stackoverflow.com/questions/7951453/zend-validate-db-recordexists-with-doctrine-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!