zend-framework - Zend_Validate_Db_RecordExists 与 Doctrine 2?

标签 zend-framework zend-form doctrine-orm zend-db zend-validate

我在 Zend Framework 应用程序中使用 Doctrine 2,并且需要类似于 Zend_Validate_Db_RecordExists 和 Zend_Validate_Db_NoRecordExists 的功能。

例如,当用户输入一个新项目时,我需要验证不存在重复的条目。通过在我的表单上添加 Db_NoRecordExists 验证器,使用 Zend_Db 很容易实现这一点。

我尝试实现提议的自定义验证器解决方案 here ,但我无法弄清楚他们如何与 Doctrine 通信以检索实体(我怀疑这种方法可能不再适用于后 Doctrine 1.x)。

FAQ Doctrine 手册的部分建议从客户端代码调用 contains() ,但这仅涵盖集合,如果可能的话,我希望从我的表单模型中一致地处理我的所有表单验证。

任何人都可以提出一种方法来使用这些 Zend 验证器并将 Doctrine 2 DBAL 配置为数据库连接/资源吗?

最佳答案

这很简单,真的。

我有一些 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);
}

关于zend-framework - Zend_Validate_Db_RecordExists 与 Doctrine 2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7951453/

相关文章:

php - 从对象中选择随机项目

php - 在zend中使用单一表单插入两个表的数据

zend-framework - 如何以zend形式设置元素

php - Zend <dt> <dd> 装饰器 : what do I lose by removing them

zend-framework - 每个月的第一天

javascript - 如何为所有 AJAX 链接编写一个 jquery 函数

php - 编辑表单时填充 zend 多选框

Symfony2。使用数据 fixture 填充多对多连接表

php - Zerofill 与 Doctrine2

php - 在 Doctrine 2 中使用类表继承时 : how can one write a Native SQL Query that will return results from a child class?