DoctrineModule\Validator\NoObjectExists
在用于编辑的 Zend 表单中使用验证器的最有效方法是什么?因为当我使用相同的表单来保存编辑的值时,这会验证对象的存在和标志表单是无效的。
问问题
4889 次
3 回答
6
几周前,我在自定义过滤器中使用辅助方法解决了同样的问题。我不确定这是否是正确的方法,但它有效。
- 编写一个自定义输入过滤器扩展
Zend\InputFilter\InputFilter
. - 在过滤器方法中添加您的通用过滤器和验证
init()
器。 - 在输入过滤器中编写一个辅助方法,将教义的存在验证器附加到当前验证器链,如下所示。
- 创建新对象时将存在验证器添加到您的过滤器实例,编辑时使用通用过滤器实例。
所以,
<?php
/**
* Baz filter
*/
class BazFilter extends Zend\InputFilter\InputFilter
{
/**
* This method will be triggered automatically when you retrive baz filter via inputfiltermanager.
*/
public function init()
{
// Define your input names, types, validators and filters as arrays
$this->add(array(
'name' => 'code',
'required' => true,
'validators' => array(),
'filters' => array()
));
$this->add( array(...) );
$this->add( array(...) );
// ...
}
/**
* Appends doctrine's noobjectexists validator to validator chain only when required.
*
* @access public
* @param \Doctrine\ORM\EntityRepository $repository
* @return \Zend\InputFilter\InputFilter
*/
public function appendExistenceValidator(\Doctrine\ORM\EntityRepository $repository)
{
$validatorSignature = array(
'name' => 'code',
'validators' => array(
array(
'name' => 'DoctrineModule\Validator\NoObjectExists',
'options' => array(
'object_repository' => $repository,
'fields' => 'code',
'messages' => array( NoObjectExists::ERROR_OBJECT_FOUND => "This object with code already exists in database." )
)
)
)
);
$validator = $this->getFactory()->createInput( $validatorSignature );
$this->add($validator);
return $this;
}
}
最后,在编辑时将此输入过滤器附加到您的表单中:
// $form = your form instance
// $filter = Bazfilter instance
$form->setData($postData)->setInputFilter( $filter );
if( $form->isValid() === false ) {
// ...
}
创建时:
// $filter = bazfilter instance
$repository = $entityManager->getRepository('Your\Entity\Name');
$filter->appendExistenceValidator( $repository ); // <-- Notice this line
$form->setData($postData)->setInputFilter( $filter );
if( $form->isValid() === false ) {
// ...
}
于 2013-05-29T11:13:55.040 回答
1
您不能以简单的方式使用 NoObjectExists,而应使用 UniqueObject:
于 2014-01-16T17:50:17.110 回答
0
我尝试在表单中使用 DoctrineModule\Validator\NoObjectExists ,它会阻止保持唯一字段不变的更新。正如@Tadej 提到的 - 使用 UniqueObject。这是一个示例表格:
class ExampleForm extends Form implements InputFilterProviderInterface
{
/**
* @var EntityManager
*/
private $entityManager;
/**
* @var Repository
*/
private $repository;
/**
* ExampleForm constructor.
*
* @param EntityManager $entityManager
* @param Repository $repository
*/
public function __construct(EntityManager $entityManager, Repository $repository)
{
$this->entityManager = $entityManager;
$this->repository = $repository;
$this->add(
[
'type' => Text::class,
'name' => 'name',
'options' => [
'label' => _('Name *')
],
'attributes' => [
'class' => 'form-control',
],
]
);
}
/**
* @return array
*/
public function getInputFilterSpecification()
{
return [
'name' => [
'required' => true,
'filters' => [
],
'validators' => [
[
'name' => UniqueObject::class,
'options' => [
'object_manager' => $this->entityManager,
'object_repository' => $this->repository,
'fields' => ['name'],
'use_context' => true,
'messages' => [
UniqueObject::ERROR_OBJECT_NOT_UNIQUE => "Name '%value%' is already in use",
]
]
]
]
],
];
}
}
注意“use_context”选项的使用——如果字段不是主键,则必须使用它。“消息”是可选的。
于 2016-11-09T10:19:01.993 回答