2010-12-09 7 views
1

Ich habe ein SymfonyForm, das 1: n embedForm (s) hat. Das Hauptformular und die embedForm-Klasse haben ihre eigene PreValidation, die eine bedingte Validierung implementiert. Ein Teil der EmbedForm Klasse sieht wie folgt aus:PreValidation in Symfony 1.4 für embedForm mit sfValidatorCallback

private function configurePreValidators() { 
    $validator = new sfValidatorCallback(array('callback'=> array($this, 'preValidation'))); 
    $this->getValidatorSchema()->setPreValidator(new sfValidatorOr(array($validator))); 
} 

public function preValidation(sfValidatorCallback $validator, array $values){ 
... 
    $this->getValidator(self::SOME_FIELD)->setOption('required', false); 
... 
} 
public function configure() { 
    ... 
    $this->configurePreValidators(); 
    parent::configure(); 
} 

Die Prävalidierung der Hauptform ähnlich ist.

Wenn ich das Formular abschicke, funktioniert die Vorvalidierung des Hauptformulars einwandfrei.

Im embedForm des „SOME_FIELD“ erhält, einen erforderlichen Validierung-Fehler, obwohl ich es explizit setOption Satz (‚erforderlich‘, false) im Prävalidierung des embedForm.

Gibt es etwas, was ich berücksichtigen muss, wenn ich die Vorvalidierung in einer EmbedForm verwende? Was ist mit mergePreValidator? Irgendwelche Hinweise dazu?

Vielen Dank im Voraus!

Antwort

3

Das Problem hier ist nicht, dass Ihre Pre-und Post-Validatoren nicht feuern - sie sind (oder zumindest sollten sie sein). Das Problem besteht darin, dass der Validierer, den Sie ändern, preValidate nicht der ist, auf den im Validiererschema der obersten Ebene verwiesen wird, d. H. Das Validatorschema für das Formular der obersten Ebene.

Eine Lösung: anstatt den Validator in preValidate zu ändern, einfach die Validierung durchführt:

public function preValidation(sfValidatorCallback $validator, array $values) 
{ 
    if (!$this->getValidator(self::SOME_FIELD)->isEmpty($values[self::SOME_FIELD]) 
    { 
    throw new sfValidatorErrorSchema(self::SOME_FIELD => new sfValdiatorError($validator, 'msg')); 
    } 
} 

Hinweis Diese Lösung hat eine gewisse Gefahr: , wenn Sie den Validator für SOME_FIELD innerhalb des Top-Level-Formulars ändern Es wird in diesem Vorprüfer nicht geändert und umgekehrt.

Werfen wir einen Blick auf warum. In sfForm :: embedForm:

Symfony nistet einfach die Validatoren. Deshalb werden Pre und Post immer noch angerufen. Warum ändert sich die Referenz? sfValidatorSchema :: offsetSet:

public function offsetSet($name, $validator) 
{ 
    ...  
    $this->fields[$name] = clone $validator; 
} 

Also, wenn ein Formular eingebettet ist, wird das Validator Schema geklont. Daher haben Änderungen an den Validatoren innerhalb eines eingebetteten Formulars keinen Einfluss auf das Validiererschema der obersten Ebene.

+0

Vielen Dank für Ihre Erklärungen ... – hasentopf

+0

Das wird nicht in meiner Formklasse Top-Level helfen? foreach ($ this-> getEmbeddedForm ('my_embeded_forms')) -> getEmbeddedForms() als $ form_id => $ form) { $ this-> mergePreValidator ($ form-> getValidatorSchema()); } ??? – hasentopf

+0

Nein, sfForm :: embedForm führt die Schemas bereits in den Code ein, den ich oben eingefügt habe. Die preValidators FEHLEN, sie ändern einfach die falsche Validator-Instanz. –