2

所以我做了ZF2應用,得到了一個表格,並在輸入過濾器一個輸入過濾器我有:ZF2輸入過濾學說NoObjectExists編輯對象不驗證

$this->add(
     array(
      'name'  => 'email', 
      'required' => true, 
      'validators' => array(
       array(
        'name' => 'EmailAddress' 
       ), 
       array(
        'name'  => 'DoctrineModule\Validator\NoObjectExists', 
        'options' => array(
         'object_repository' => $sm->get('doctrine.entitymanager.orm_default')->getRepository('YrmUser\Entity\User'), 
         'fields'   => 'email' 
        ), 
       ), 
      ), 
     ) 
    ); 

的偉大工程,但是當我編輯現有的對象和保存它NoObjectExists驗證器說找到一個匹配的對象,所以它不驗證。 有沒有解決這個問題的方法? 或者我應該刪除編輯表單上的驗證器,並在插入副本時捕獲異常?

UPDATE: How to use DoctrineModule\Validator\NoObjectExists in edit forms - Zend Framework 2 & Doctrine 2

是相同的問題,但答案是隻刪除在編輯驗證,這一關,當然不是一個解決辦法。因爲您在插入重複項時仍然需要捕獲拋出的異常。我可以做到這一點沒問題,但我要求的是一個解決方案,使其與NoObjectExists工作(否則是什麼使用這個驗證器,如果我必須趕上重複的異常無論如何)

更新,添加其他相關代碼我的形式和實體有比這更多的領域,但我刪除了他們保持可讀性就在這裏)

FORM:

namespace YrmUser\Form; 

use Zend\Form\Form; 
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator; 
use DoctrineORMModule\Stdlib\Hydrator\DoctrineEntity; 

use YrmUser\Entity\User; 



class UserForm extends Form 
{ 
protected $objectManager; 

/** 
* __construct description 
* 
* @param String $name form name 
* 
* @return void 
*/ 
public function __construct($name = null) 
{ 
    parent::__construct('new-user'); 
} 

public function init() 
{ 
    $this->setHydrator(
     new DoctrineHydrator($this->objectManager, 'YrmUser\Entity\User') 
    )->setObject(new User()); 

    $this->setAttribute('method', 'post'); 


    $this->add(
     array(
      'name' => 'email', 
      'attributes' => array(
       'type' => 'email', 
       'placeholder' =>'Email', 
      ), 
      'options' => array(
       'label' => 'Email', 
      ), 
     ) 
    ); 

} 
} 

FILTER:

class UserFilter extends InputFilter 
{ 
/** 
* [__construct description] 
* 
* @param ServiceLocator $sm servicelocator 
*/ 
public function __construct($sm) 
{ 


    $this->add(
     array(
      'name'  => 'email', 
      'required' => true, 
      'validators' => array(
       array(
        'name' => 'EmailAddress' 
       ), 
       array(
        'name'  => 'DoctrineModule\Validator\NoObjectExists', 
        'options' => array(
         'object_repository' => $sm->get('doctrine.entitymanager.orm_default')->getRepository('YrmUser\Entity\User'), 
         'fields'   => 'email' 
        ), 
       ), 
      ), 
     ) 
    ); 
} 
} 

控制器動作:

public function editAction() 
{ 
    $id = (int) $this->params('id', null); 
    if (null === $id) { 
     return $this->redirect()->toRoute('manage-users'); 
    } 

    $em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager'); 

    $formManager = $this->getServiceLocator()->get('FormElementManager'); 
    $form = $formManager->get('UserForm'); 

    $user = $em->find('YrmUser\Entity\User', $id); 
    $form->setInputFilter(new UserFilter($this->getServiceLocator())); 
    $form->bind($user); 

    $request = $this->getRequest(); 
    if ($request->isPost()) { 
     $form->setData($request->getPost()); 
     if ($form->isValid()) { 
      $em->persist($user); 
      $em->flush(); 
      return $this->redirect()->toRoute('manage-users'); 
     } 
    } 

    return array(
     'form' => $form, 
     'id' => $id 
    ); 
} 

實體:

class User 
{ 
/** 
* @var int 
* @ORM\Id 
* @ORM\Column(type="integer") 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
protected $id; 



/** 
* @var string 
* @ORM\Column(type="string", unique=true, length=255) 
*/ 
protected $email; 



/** 
* Get id. 
* 
* @return int 
*/ 
public function getId() 
{ 
    return $this->id; 
} 

/** 
* Set id. 
* 
* @param int $id user id 
* 
* @return void 
*/ 
public function setId($id) 
{ 
    $this->id = (int) $id; 
} 


/** 
* Get email. 
* 
* @return string 
*/ 
public function getEmail() 
{ 
    return $this->email; 
} 

/** 
* Set email. 
* 
* @param string $email user email adress 
* 
* @return void 
*/ 
public function setEmail($email) 
{ 
    $this->email = $email; 
} 
} 

在此先感謝,

YRM

+0

請發表您的控制器的編輯操作和整個表單代碼的代碼了。很難說沒有更多的代碼是什麼問題,因爲你可能會收到這個錯誤有很多原因。 –

+0

它很明顯,爲什麼我得到的「錯誤」的權利?由於電子郵件已經存在於數據庫中,因此表單不會被驗證。事情是現有的電子郵件屬於行im試圖編輯/更新。 – YRM

+0

問題很明顯是什麼導致它不是。這可能是控制器操作中的一個問題,或者它可能是形式水化器來命名幾個問題。只是想排除一些東西快速搜救雖然和似乎這個問題是一個可能dupilcate這個問題http://stackoverflow.com/questions/16808574/how-to-use-doctrinemodule-validator-noobjectexists-in-edit -forms-的Zend-framewor –

回答

4

最近我對我的項目同樣的問題,我花了很多時間尋找一個解決方案,我終於在Github上找到了這個模塊LosBase

它使用兩個海關驗證器延伸DoctrineModule\Validator\NoObjectExistsNoEntityExistsAdd行動和NoOtherEntityExistsEdit行動。

所以我用這個appraoch來解決我的問題。這是迄今爲止我所做的解決方案:

NoOtherEntityExists驗證:

use Zend\Validator\Exception\InvalidArgumentException; 
use DoctrineModule\Validator\NoObjectExists; 

class NoOtherEntityExists extends NoObjectExists 
{ 
    private $id; //id of the entity to edit 
    private $id_getter; //getter of the id 
    private $additionalFields = null; //other fields 
    public function __construct(array $options) 
    { 
     parent::__construct($options); 
     if (isset($options['additionalFields'])) { 
      $this->additionalFields = $options['additionalFields']; 
     } 
     $this->id = $options['id']; 
     $this->id_getter = $options['id_getter']; 
    } 
    public function isValid($value, $context = null) 
    { 
     if (null != $this->additionalFields && is_array($context)) { 
      $value = (array) $value; 
      foreach ($this->additionalFields as $field) { 
       $value[] = $context[$field]; 
      } 
     } 
     $value = $this->cleanSearchValue($value); 
     $match = $this->objectRepository->findOneBy($value); 

     if (is_object($match) && $match->{$this->id_getter}() != $this->id) { 
      if (is_array($value)) { 
       $str = ''; 
       foreach ($value as $campo) { 
        if ($str != '') { 
         $str .= ', '; 
        } 
        $str .= $campo; 
       } 
       $value = $str; 
      } 
      $this->error(self::ERROR_OBJECT_FOUND, $value); 
      return false; 
     } 
     return true; 
    } 
} 

NoEntityExists驗證:

use Zend\Validator\Exception\InvalidArgumentException; 
use DoctrineModule\Validator\NoObjectExists; 

class NoEntityExists extends NoObjectExists 
{ 
    private $additionalFields = null; 
    public function __construct(array $options) 
    { 
     parent::__construct($options); 
     if (isset($options['additionalFields'])) { 
      $this->additionalFields = $options['additionalFields']; 
     } 
    } 
    public function isValid($value, $context = null) 
    { 
     if (null != $this->additionalFields && is_array($context)) { 
      $value = (array) $value; 
      foreach ($this->additionalFields as $field) { 
       $value[] = $context[$field]; 
      } 
     } 
     $value = $this->cleanSearchValue($value); 
     $match = $this->objectRepository->findOneBy($value); 
     if (is_object($match)) { 
      if (is_array($value)) { 
       $str = ''; 
       foreach ($value as $campo) { 
        if ($str != '') { 
         $str .= ', '; 
        } 
        $str .= $campo; 
       } 
       $value = $str; 
      } 
      $this->error(self::ERROR_OBJECT_FOUND, $value); 
      return false; 
     } 
     return true; 
    } 
} 

使用此驗證器與輸入過濾器:

In m ÿ定製input filters,我添加兩種方法:一種對追加NoEntityExists驗證器,和其他要追加NoOtherEntityExists驗證:

/** 
* Appends doctrine's NoObjectExists Validator for Add FORM . 
* 
* @param \Doctrine\ORM\EntityRepository $repository 
* @return \Zend\InputFilter\InputFilter 
*/ 
public function appendAddValidator(EntityRepository $repository) 
{ 
    $this->add($this->getFactory()->createInput(array(
      'name' => 'libellesite', //unique field name 
      'validators' => array(
        array(
          'name' => 'Netman\Form\NoEntityExists',//use namespace 
          'options' => array(
            'object_repository' => $repository, 
            'fields' => 'libellesite', 
            'messages' => array(
            'objectFound' => 'custom message here' 
            ), 
          ), 
        ), 
      ) 
    ))); 
    return $this; 
} 

/** 
* Appends doctrine's NoObjectExists Validator for EDIT FORM. 
* 
* @param \Doctrine\ORM\EntityRepository $repository 
* @return \Zend\InputFilter\InputFilter 
*/ 
public function appendEditValidator(EntityRepository $repository, $id) 
{ 
    $this->add($this->getFactory()->createInput(array(
      'name' => 'libellesite', 
      'validators' => array(
        array(
          'name' => 'Netman\Form\NoOtherEntityExists', 
          'options' => array(
            'object_repository' => $repository, 
            'fields' => 'libellesite', 
            'id'=>$id, // 
            'id_getter'=>'getCodesite',//getter for ID 
            'messages' => array(
            'objectFound' => 'custom message here' 
            ), 
          ), 
        ), 
      ) 
    ))); 
    return $this; 
} 

控制器:

addAction

$repository = $em->getRepository('Entity\Name'); 
$form->setInputFilter($filter->appendAddValidator($repository)); 

editAction

$id = $this->params('id', null); 
$repository = $em->getRepository('Entity\Name'); 
$form->setInputFilter($filter->appendEditValidator($repository,$id)); 

希望這會幫助別人!