我有一个用于“添加”和“编辑”表单的字段集。
字段集实现InputFilterProviderInterface
以提供其验证。
在验证添加操作时,我需要检查数据库中不存在具有相同值的数据库记录,因此我使用NoRecordExists
验证器。
到目前为止一切都很好。但是,当我在编辑表单中使用相同的字段集时,验证将失败,因为显然已经有一条具有特定值的记录,它是正在编辑的记录。
所以我转向验证器的exclude
选项,NoRecordExists
并使用我正在编辑的记录的“id”(这是我的主键字段)排除记录。
所以我快到了,唯一我无法解决的是如何获得我想在创建输入过滤器时排除的“id”值getInputFilterSpecification
。
这是我的字段集代码。如果有人能告诉我如何从内部访问表单(或绑定对象)的其他属性,getInputFilterSpecification
我将非常感激。
也许我需要以不同的方式实现我的 imputfilter 来做到这一点?甚至实现自定义验证器?但是对于看起来非常常规的用例来说,自定义验证器肯定会过大...
提前谢谢了。:wq
<?php
namespace Kickoff\Form\Competition;
use Kickoff\Form\AbstractFieldset,
Kickoff\Model\Entities\Competition,
DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator,
Zend\InputFilter\InputFilterProviderInterface;
class CompetitionFieldset extends AbstractFieldset implements InputFilterProviderInterface
{
public function init()
{
$this->setName('Competition')
->setHydrator(new DoctrineHydrator($this->getObjectManager(),'Kickoff\Model\Entities\Competition'))
->setObject(new Competition())
->setLabel('Competition')
->setAttribute('class','form-collection');
$this->add(array(
'type' => 'Zend\Form\Element\Hidden',
'name' => 'id',
));
$this->add(array(
'name' => 'name',
'options' => array(
'label' => 'Competition name',
'admin_inline' => true,
),
));
$this->add(array(
'name' => 'long_name',
'options' => array(
'label' => 'Competition long name',
'admin_inline' => true,
),
'attributes' => array(
'class' => 'input-xxlarge',
),
));
$this->add(array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'leagues',
'options' => array(
'label' => 'Leagues',
'count' => 0,
'should_create_template' => true,
'allow_add' => true,
'target_element' => array(
'type' => 'LeagueFieldset',
),
),
));
}
/**
* Implement InputFilterProviderInterface
*/
public function getInputFilterSpecification()
{
return array(
'name' => array(
'filters' => array(
array('name' => 'Zend\Filter\StringTrim'),
),
'validators' => array(
'notempty' => array(
'name' => 'NotEmpty',
'break_chain_on_failure' => true,
'options' => array(
'messages' => array('isEmpty' => 'Competition name is required.',),
),
),
'length' => array(
'name' => 'StringLength',
'options' => array(
'max' => '64',
'messages' => array(
'stringLengthTooLong' => 'Competition name must be no more than 64 characters.',
),
),
),
'unique' => array(
'name' => 'Db\NoRecordExists',
'options' => array(
'table' => 'competition',
'field' => 'name',
'adapter' => $this->serviceManager->getServiceLocator()->get('db'),
'exclude' => array(
'field' => 'id',
'value' => '',
),
'messages' => array(
'recordFound' => 'A competition already exists with this name',
),
),
),
),
),
'long_name' => array(
'filters' => array(
array('name' => 'Zend\Filter\StringTrim'),
),
'validators' => array(
'length' => array(
'name' => 'StringLength',
'options' => array(
'max' => '128',
'messages' => array(
'stringLengthTooLong' => 'Competition long name must be no more than 128 characters.',
),
),
),
),
),
);
}
}
编辑:将我的“编辑”控制器操作添加到这篇文章中:
public function editCompetitionAction()
{
$id = $this->params()->fromRoute('competition_id');
$repository = $this->getEntityManager()->getRepository('Kickoff\Model\Entities\Competition');
$competition = $repository->find($id);
if (null == $competition) {
$this->getResponse()->setStatusCode(404);
return;
}
$formManager = $this->serviceLocator->get('FormElementManager');
$form = $formManager->get('Kickoff\Form\Competition\CompetitionForm');
$form->bind($competition);
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
$this->logger->debug("Validator is ".print_r($form->getValidator(),1));
if ($form->isValid()) {
$this->getEntityManager()->persist($competition);
$this->getEntityManager()->flush();
}
}
return array(
'form' => $form,
);
}