Zend_Validate_Db_Record With Doctrine 2? [英] Zend_Validate_Db_RecordExists with Doctrine 2?

查看:134
本文介绍了Zend_Validate_Db_Record With Doctrine 2?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



我尝试实现了定制验证器解决方案这里,但是我无法弄清楚他们如何与Doctrine进行通信来检索实体(我怀疑这种方法可能不再work post-Doctrine 1.x)。



FAQ 部分的教条手册建议调用包含()从客户端代码,但这仅涵盖集合,如果可能,我想从我的表单模型中始终处理所有的表单验证。



可以任何人都建议使用这些Zend验证器与Doctrine 2 DBAL配置为数据库连接/资源? / p>

解决方案

真的很简单。



我有几个Zend_Validate类型验证器与Doctrine ORM进行通信,所以我有一个抽象类,它们是从...下载的。



这是抽象类:

 <?php 
命名空间TimDev \Validate \Doctrine;

抽象类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 
命名空间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 =>'另一条记录已经包含%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()方法):

  / ** 
*覆盖超类方法为NoEntityExists类型验证器添加即时验证,
*依赖于知道所涉及的实体的ID。
* @param类型$ data
* @return类型
* /
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('另一个用户已经有用户名%value%',NoEntityExists :: ERROR_ENTITY_EXISTS);

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

return parent :: isValid($ data);
}


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?

解决方案

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

这篇关于Zend_Validate_Db_Record With Doctrine 2?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆