7

Db_NoRecordExistsバリデーターに「除外」オプションを使用しようとしています。これは、要素を「編集」しているときに、通常どおり「重複」エラーが返されるためです。

私が目指しているのは、コントローラーからフォーム自体に渡された値を保持するようにフォームに指示することです。

これはコントローラーです:

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)
        )
        )
    );

//... 切る ...

いくつかのアドバイス?

4

6 に答える 6

17

私も同様の問題を抱えていました。私の解決策は、バリデーターをから関数に移動することでしinitisValid

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);
}
于 2011-03-21T14:46:04.710 に答える
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);
}
于 2011-10-28T14:59:46.820 に答える
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)) {

楽しみ!

于 2014-01-31T16:12:31.010 に答える
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()を呼び出す直前に、バリデーターに何を除外するかを指示するだけです。終わり。単純。

于 2016-09-25T08:03:46.490 に答える
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;
}
于 2012-08-10T16:34:47.787 に答える
0

関数にバリデーターを作成する必要はありません。句isValidを更新するだけです。exclude

public function isValid($data)
{
    $this->getElement('name')->getValidator('Db_NoRecordExists')->setExclude('id != ' . $data['id']);
    return parent::isValid($data);
}
于 2013-01-29T18:25:50.260 に答える