所以我得到了一个ZF2应用程序,在InputFilter中有一个Form和一个InputFilter,我有:
$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验证器说找到匹配的对象,因此它不会验证.有这个问题的解决方案吗?或者我应该删除编辑表单上的验证器并在插入重复时捕获异常?
更新: 如何在编辑表单中使用DoctrineModule\Validator\NoObjectExists - Zend Framework 2和Doctrine 2
是同样的问题,但答案是在编辑时删除验证器,这个过程不是一个解决方案.因为你仍然必须捕获插入副本时抛出的异常.我可以做到这一点没有问题,但我要求的是一个解决方案,使它与NoObjectExists一起使用(否则,如果我必须捕获重复项的异常,那么是否使用此验证器)
更新,添加其他相关代码(我的表单和实体有更多的字段,但我删除它们,以保持在这里可读)
形成:
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', ), ) ); } }
过滤:
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
我最近在我的项目中遇到了同样的问题,我花了很多时间寻找解决方案,我终于找到了这个模块LosBase.
它使用两个海关验证其延长DoctrineModule\Validator\NoObjectExists
:NoEntityExists
对Add
行动和NoOtherEntityExists
为Edit
行动.
所以我用这个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; } }
将此验证器与inputFilter一起使用:
在我的自定义中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));