2010-03-06 10 views
13

Ich habe zwei Felder in meiner Zend Form, und ich möchte die Validierungsregel anwenden, die sicherstellt, dass der Benutzer eines der beiden Felder eingibt.Zend Form Validator: Element A oder Element B

$companyname = new Zend_Form_Element_Text('companyname'); 
    $companyname->setLabel('Company Name'); 
    $companyname->setDecorators($decors); 
    $this->addElement($companyname); 

    $companyother = new Zend_Form_Element_Text('companyother'); 
    $companyother->setLabel('Company Other'); 
    $companyother->setDecorators($decors); 
    $this->addElement($companyother); 

Wie kann ich einen Validator hinzufügen, der beide Felder betrachtet?

Antwort

12

Siehe 'Hinweis: Validierungskontext' unter page. Zend_Form übergibt den Kontext an jeden Zend_Form_Element :: isValid Aufruf als zweiten Parameter. Schreiben Sie einfach Ihren eigenen Validator, der den Kontext analysiert.

EDIT:
Okay, dachte ich I'ld an diese selbst einen Schuss nehmen. Es ist nicht getestet, noch ist es ein Mittel zu allen Zwecken, aber es wird Ihnen eine grundlegende Idee geben.

class My_Validator_OneFieldShouldBePresent extend Zend_Validator_Abstract 
{ 
    const NOT_PRESENT = 'notPresent'; 

    protected $_messageTemplates = array(
     self::NOT_PRESENT => 'Field %field% is not present' 
    ); 

    protected $_messageVariables = array(
     'field' => '_field' 
    ); 

    protected $_field; 

    protected $_listOfFields; 

    public function __construct(array $listOfFields) 
    { 
     $this->_listOfFields = $listOfFields; 
    } 

    public function isValid($value, $context = null) 
    { 
     if(!is_array($context)) 
     { 
      $this->_error(self::NOT_PRESENT); 

      return false; 
     } 

     foreach($this->_listOfFields as $field) 
     { 
      if(isset($context[ $field ])) 
      { 
       return true; 
      } 
     } 

     $this->_field = $field; 
     $this->_error(self::NOT_PRESENT); 

     return false; 
    } 
} 

Verbrauch:

$oneOfTheseFieldsShouldBePresent = array('companyname', 'companyother'); 

$companyname = new Zend_Form_Element_Text('companyname'); 
$companyname->setLabel('Company Name'); 
$companyname->setDecorators($decors); 
$companyname->addValidator(new My_Validator_OneFieldShouldBePresent($oneOfTheseFieldsShouldBePresent)); 
$this->addElement($companyname); 

$companyother = new Zend_Form_Element_Text('companyother'); 
$companyother->setLabel('Company Other'); 
$companyother->setDecorators($decors); 
$companyname->addValidator(new My_Validator_OneFieldShouldBePresent($oneOfTheseFieldsShouldBePresent)); 
$this->addElement($companyother); 
0

Ich bin nicht auf eine solche Lösung gestoßen, aber es ist perfekt so +1.

Ich würde Your_Form::isValid() erweitern, um eine manuelle Überprüfung für die Werte dieser beiden Elemente aufzunehmen.

Wenn alle Felder ihre eigenen individuellen Validatoren übergeben, gehört diese Validierung wahrscheinlich zu der Form als Ganzes und könnte daher anstelle der Felder auf die Validierung des Formulars gesetzt werden. Stimmen Sie dieser Linie zu?

0

Ich stimme @cheltztz zu, dass eine Funktion wie diese nicht existiert.

Womit ich nicht einverstanden bin, erweitert Your_Form::isValid(). Stattdessen würde ich write a custom Validator akzeptieren, die die Werte von beiden Formularelementen akzeptiert, die einen Wert haben müssen. So könnte ich es auf beliebigen Formularelementen wiederverwenden. Dies ist etwas ähnlich dem Identischen Validator.

1

Die Lösung von @fireeyedboy vorgesehen ist praktisch, aber nicht funktioniert für diese genaue Frage.

Zend_Validate_Abstract verwendet den Kontext, der nicht als Variable an isValid() übergeben werden kann. Auf diese Weise werden die leeren Felder bei der Verwendung der isValid()-Methode (egal ob die ursprüngliche oder die überschriebene) nicht übergeben und validiert (es sei denn, Sie haben setRequired(true) oder setAllowEmpty(false), die wir nicht wollen). Wenn Sie also beide Felder (companyname und companyother) leer lassen, wird keine Aktion ausgeführt. Die einzige Lösung, die mir bekannt ist, besteht darin, die Klasse Zend_Validate zu erweitern, damit leere Felder validiert werden können.

Bitte lassen Sie mich wissen, wenn Sie besser Lösung wissen, da ich mit ähnlichen Problem zu kämpfen habe.