Zend Form Düzenleme ve Zend_Validate_Db_NoRecordExists

6 Cevap php

Ben yavaş yavaş benim kendi kullanımı için bazı yardımcı web sitelerini kurarak benim Zend becerileri inşa ediyorum. Ben Zend Formlar ve Form doğrulama kullanıyorum ve şimdiye kadar bir şeyler yapmanın Zend şekilde anlamak edildiğini mutlu olmuştur. Ancak ben bir düzenleme şeklinde ve benzersiz olmak zorundadır veritabanı sütun eşleyen bir alanın bağlamında Zend_Validate_Db_NoRecordExists () nasıl kullanılacağı ile biraz karıştı.

Bu basit bir tablo kullanılarak örnek için

TABLE Test
(
  ID INT AUTO_INCREMENT,
  Data INT UNIQUE
);

Ben sadece Tablo Testi için yeni bir satır ekleyerek olsaydı, ben gibi veri alanı için Zend Form elemanına bir doğrulayıcı ekleyebilirsiniz:

$data = new Zend_Form_Element_Text('Data');
$data->addValidator( new Zend_Validate_Db_NoRecordExists('Test', 'Data') )

Form doğrulama bu doğrulayıcı Veri elemanının içeriği zaten tabloda mevcut olmadığını kontrol edecektir. Böylece Testi içine insert Veri alanları UNIQUE niteleyiciyi ihlal etmeden devam edebilirsiniz.

Testi tablonun varolan satır düzenlerken Ancak durum farklı. Bu durumda doğrulayıcı eleman değeri iki birbirini dışlayan durumlar koşullardan birini karşıladığını kontrol etmek gerekiyor:

  1. The user has changed the element value, and the new value does not currently exist in the table.

  2. Kullanıcı Not eleman değerini değişti. Böylece değer does şu tabloda mevcut (ve bu Tamam).

Zend Validation Docs doğrulama işleminden kayıtları hariç amacıyla NoRecordExists () validator için bir parametre ekleme hakkında konuşun. Fikir "eşleşen satırları arıyor tabloyu doğrulamak, ancak bir alan bu özel değeri olan herhangi bir hit görmezden" olmanın. Böyle bir kullanım örneği bir tablo düzenlerken doğrulama elemanı için gerekli olan budur. 1.9 bunu yapmak için sözde kod yüzden (aslında ben 1.9 kaynak koddan bu var - güncel dokümanlar yanlış olabileceğini düşünüyorum) gibi:

$data = new Zend_Form_Element_Text('Data');
$data->addValidator( new Zend_Validate_Db_NoRecordExists('Test', 'Data',
                     array ('field'=>'Data', 'Value'=> $Value) );

Sorun ($ Değer) hariç edilecek değeri, örneği süre (aynı zamanda formu örneği edildiği zaman) onaylayıcısına bağlı olmasıdır. Form bir kayıt düzenlerken Ama, bu değer formu başlangıçta verilerle doldurulur iken $ veri alanının içeriğine bağlı gerekiyor - IE başlangıçta Test tablo satırdan okunan veri değeri. Ancak tipik Zend desen bir form örneği ve istenen element değere dahil bağlanma değerini önleyen iki ayrı aşamada doldurulur.

I () doğrulayıcı oluştuğu (ve bu ortak Zend denetleyici model olduğuna dikkat edin) NoRecordExists için $ Değer bağlanmasını istiyoruz Aşağıdaki Zend pseudo kod işaretleri:

$form = new Form() 
if (is Post) {
    $formData = GetPostData()
    if ($form->isValid($formData)) {
        Update Table with $formData
        Redirect out of here
    } else {
        $form->populate($formData)
    }
} else {
    $RowData = Get Data from Table
    $form->populate($RowData)     <=== This is where I want ('value' => $Value) bound
}

Ben alt-sınıf Zend_Form olabilir ve populate (NoRecordExists (başlangıç ​​formu nüfus) doğrulayıcı bir tek atımlık ekleme yapmak) yöntemi geçersiz, ama bu benim için büyük bir kesmek gibi görünüyor. Yani diğer insanların ne düşündüğünü bilmek istedim ve zaten bu sorunu çözer yazılı bir desen var mı?

Edit 2009-02-04

Ben bu sorunun sadece iyi çözüm özel bir doğrulayıcı yazmak ve Zend sürümü hakkında unutmak olduğunu düşünüyordum. Tablo ve kolon isimleri verilen Ben teklik sınamak için bazı SQL üretebilir ve böyle bir böyle bir kimliği ile satırı hariç ki benim formu, gizli bir alan olarak kayıt kimliği vardır. Tabii ki bu ben Model gizlemek gerekiyordu dB tabakasına formu bağlama nasıl olacağı konusunda beni düşünme başladı!

6 Cevap

Ezici yanıtı inceledikten sonra ben bir özel doğrulama ile gidiyorum karar verdik

Bu böyle yapılır:

  1. Ben FORMU, bu doğrulayıcı (örneğin, e-posta alanı) ekleyin:

 

$email->addValidator('Db_NoRecordExists', true, array('table' => 'user', 'field' => 'email'));
  1. Benim için işe yaramadı sonra o yana bu özel hata mesajı eklemek etmeyin, örneğin:

 

$email->getValidator('Db_NoRecordExists')->setMessage('This email is already registered.');

 

  1. Lütfen Controller bu ekleyin:

 

/* Don't check for Db_NoRecordExists if editing the same field */

    $form->getElement('email')
             ->addValidator('Db_NoRecordExists',
                                 false,
                                 array('table' => 'user',
                                       'field' => 'email',
                                       'exclude' => array ('field' => 'id', 'value' => $this->request->get('id'))));

And after this you do verifications, e.g.:

    if ($this->getRequest()->isPost())
            {
                if($form->isValid($this->getRequest()->getPost()))
                {

    ....

İşte bu!

Bu da çalışır:

$this->addElement('text', 'email', array(
        'label'      => 'Your email address:',
        'required'   => true,
        'filters'    => array('StringTrim'),
        'validators' => array(
            'EmailAddress',
             array('Db_NoRecordExists', true, array(
                    'table' => 'guestbook', 
                    'field' => 'email',
                    'messages' => array(
                        'recordFound' => 'Email already taken'
                    )
                )
            )
        )
    ));
private $_id;

public function setId($id=null)
{
    $this->_id=$id;    
}

public function init()
{
    .....
    if(isset($this->_id)){
        $email->addValidator('Db_NoRecordExists', false, array('table' => 'user', 'field' => 'email','exclude' => array ('field' => 'id', 'value' => $this->_id) )); 
        $email->getValidator('Db_NoRecordExists')->setMessage('This email is already registered.');      
    }

Şimdi u kullanabilirsiniz:

$form = new Form_Test(array('id'=>$id));

Siz sadece arama $form->getElement('input')->removeValidator('Zend_Validator_Db_NoRecordExists'); yerine dışlamayı temin olabilir.

Ben sadece email address teklik için bu örneği denedim ve aşağıda maddeleri ile mükemmel çalışır:

1] In my form:

// Add an email element
    $this->addElement('text', 'email', array(
        'label'      => 'Email :',
        'required'   => true,
        'filters'    => array('StringTrim'),
        'validators' => array(
            'EmailAddress',
        )
    ));

İşte unique email address çalışması için eklenmesi gereken özel bir şey var:

    $email = new Zend_Form_Element_Text('email');
    $email->addValidator('Db_NoRecordExists', true, array('table' => 'guestbook', 'field' => 'email'));

2] In my controller:

$form->getElement('email')
     ->addValidator('Db_NoRecordExists',
                         false,
                         array('table' => 'guestbook',
                               'field' => 'email',
                               'exclude' => array ('field' => 'id', 'value' => $request->get('id'))));

if ($this->getRequest()->isPost()) {
        if ($form->isValid($request->getPost())) {

Size insanlara yardımcı olur umarım!

Teşekkürler