我正在尝试为Db_NoRecordExists验证器使用“exclude”选项,因为当我“编辑”该元素时,它总是像往常一样将我返回“重复”错误。
我的目标是告诉表单从Controller中保留传递给表单本身的值......
这是控制器:
public function editAction()
{
$id = $this->getRequest()->getParam('id');
$pagesMapper = new Application_Model_PagesMapper();
$form = new Application_Form_PageEdit();
$form->populate($pagesMapper->fetchId($id, true));
if ($this->getRequest()->isPost()) {
if ($form->isValid($this->getRequest()->getPost())) {
//... cut ...
}
}
$this->view->form = $form;
}
这是表格:
class Application_Form_PageEdit extends Zend_Form
{
public function init()
{
$commonFilters = array('StringTrim');
$commonValidators = array('NotEmpty');
$this->setMethod('post')->setAction('/admin-page/edit');
$id = new Zend_Form_Element_Hidden('id');
$pid = new Zend_Form_Element_Hidden('pid');
$keyname = new Zend_Form_Element_Text('keyname');
$keyname->setLabel('Keyname')
->setRequired(true)
->addFilters($commonFilters)
->addFilter('StringToLower')
->addFilter('Word_SeparatorToDash')
->addValidator('Db_NoRecordExists', false, array(
'table' => 'pages',
'field' => 'keyname',
'exclude' => array(
'field' => 'id',
'value' => $this->getValue('id)
)
)
);
// ...切...
一些建议?
答案 0 :(得分:17)
我有类似的问题。我的解决方案是将验证器从init
移动到isValid
函数。
public function isValid($data)
{
$this->getElement('keyname')
->addValidator(
'Db_NoRecordExists',
false,
array(
'table' => 'pages',
'field' => 'keyname',
'exclude' => array(
'field' => 'id',
'value' => $this->getValue('id')
)
)
);
return parent::isValid($data);
}
答案 1 :(得分:2)
对我来说,只有这个解决方案才能完美运行:
public function isValid($data)
{
$clause = $this->_dbAdapter->quoteInto('id = ?', $this->getValue('id'));
$this->getElement('keyname')
->addValidator('Db_NoRecordExists', false, array(
'adapter' => $this->_dbAdapter,
'table' => 'employee_name',
'field' => 'name',
'exclude' => $clause
)
);
return parent::isValid($data);
}
答案 2 :(得分:1)
我做了什么,在控制器中的验证逻辑之前,我添加以下代码来检查当前用户数据的字段。如果匹配,我只是从元素中删除验证器:
if(($this->getRequest()->isPost()) && $request->getParam('email')==$this->user->getEmail()) {
$form_preferences->getElement('email')->removeValidator('Db_NoRecordExists');
}
此时它将传递isValid逻辑没问题。
if(($this->getRequest()->isPost()) && $form_preferences->isValid($_POST)) {
享受!
答案 3 :(得分:1)
我不喜欢覆盖 isValid()功能的解决方案。这只是感觉我们不理解 Db_NoRecordExists 验证器如何工作。您只需在调用 isValid()之前向验证程序提供要排除的记录的实际ID。验证器甚至提供了一个访问器来设置这个值本身! Zend指令真的没有任何帮助,所以人们正在努力解决这个问题并不奇怪。
这是一种更优雅且以工作流为导向的方式来设置排除而不破坏,扩展或覆盖表单:
// $post is assumed to have our posted form variables //
// $form is assumed to be our form that is already setup with validators. //
$form->getElement('username')->
getValidator('Db_NoRecordExists')->
setExclude([
'field' => 'user_id',
'value' => $post['user_id'],
]);
if ( $form->isValid( $post ) ) {
// do valid stuff
// ...
}
else {
// do invalid stuff
// ...
}
排除实际上是我们的字段和值的数组。我们只是在调用 isValid()之前告诉验证者要排除什么。完成。简单。
答案 4 :(得分:0)
对表单进行此更改:
class Application_Form_PageEdit extends Zend_Form
{
public function getExcludeFromQuery($elementName)
{
$element = $this->getElement($elementName);
if ($element)
{
return $element->getValidator('Db_NoRecordExists')->getExclude();
} else
{
return NULL;
}
}
public function setExcludeFromQuery($elementName, $excludeFromQuery)
{
$element = $this->getElement($elementName);
if ($element)
{
$element->getValidator('Db_NoRecordExists')->setExclude($excludeFromQuery);
}
return $this;
}
public function init()
{
$commonFilters = array('StringTrim');
$commonValidators = array('NotEmpty');
$this->setMethod('post')->setAction('/admin-page/edit');
$id = new Zend_Form_Element_Hidden('id');
$pid = new Zend_Form_Element_Hidden('pid');
$keyname = new Zend_Form_Element_Text('keyname');
$keyname->setLabel('Keyname')
->setRequired(true)
->addFilters($commonFilters)
->addFilter('StringToLower')
->addFilter('Word_SeparatorToDash')
->addValidator('Db_NoRecordExists', false, array(
'table' => 'pages',
'field' => 'keyname',
'exclude' => array(
'field' => 'id',
'value' => $this->getValue('id)
)
)
);
编辑动作:
public function editAction()
{
$duplicateElementName = 'whatever';
$duplicateElementValue = 'value from db';
$id = $this->getRequest()->getParam('id');
$pagesMapper = new Application_Model_PagesMapper();
$form = new Application_Form_PageEdit();
$form->populate($pagesMapper->fetchId($id, true));
$form->setExcludeFromQuery($duplicateElementName, $duplicateElementValue);
if ($this->getRequest()->isPost()) {
if ($form->isValid($this->getRequest()->getPost())) {
//... cut ...
}
}
$this->view->form = $form;
}
答案 5 :(得分:0)
无需在isValid
函数中构建验证器,只需更新exclude
子句:
public function isValid($data)
{
$this->getElement('name')->getValidator('Db_NoRecordExists')->setExclude('id != ' . $data['id']);
return parent::isValid($data);
}