2014-02-19 17 views
7

In meiner Anwendung Symfony 2 (2.4.2) gibt es einen Formulartyp, der aus 3 Feldern besteht.Ein Feld sollte nicht leer sein, wenn einige Felder in Symfony Form leer sind

Ich möchte die Validierung wie folgt aussehen: Wenn field A und field B leer sind, sollte field C nicht leer sein. Dies bedeutet, dass mindestens ein Feld einige Daten erhalten sollte.

Derzeit überprüfe ich die empfangenen Daten in der Steuerung. Gibt es einen empfohlenen Weg, dies zu tun?

+0

Pikachu: DDDDDD – Qwertie

Antwort

12

Es gibt sogar einfachere Lösungen als das Schreiben eines benutzerdefinierten Validators. Die einfachste von allen ist wohl der Ausdruck Einschränkung:

class MyEntity 
{ 
    private $fieldA; 

    private $fieldB; 

    /** 
    * @Assert\Expression(
    *  expression="this.fieldA != '' || this.fieldB != '' || value != ''", 
    *  message="Either field A or field B or field C must be set" 
    *) 
    */ 
    private $fieldC; 
} 

Sie können auch eine Validierungsmethode Ihre Klasse hinzufügen und mit der Callback-Einschränkung mit Anmerkungen versehen:

/** 
* @Assert\Callback 
*/ 
public function validateFields(ExecutionContextInterface $context) 
{ 
    if ('' === $this->fieldA && '' === $this->fieldB && '' === $this->fieldC) { 
     $context->addViolation('At least one of the fields must be filled'); 
    } 
} 

Das Verfahren wird bei der Validierung ausgeführt werden der Klasse.

+1

Ich denke, diese Antwort ist besser und einfacher. – pikachu0

3

Dies ist wahrscheinlich ein Anwendungsfall für eine Custom Validation Constraint. Ich habe es selbst nicht benutzt, aber im Grunde erstellen Sie eine Constraint und eine Validator. Sie geben dann Ihre Constraint in Ihrer config/validation.yml an.

Your\Bundle\Entity\YourEntity: 
    constraints: 
     - Your\BundleValidator\Constraints\YourConstraint: ~ 

Die eigentliche Validierung wird von Ihrem Validator getan. Sie können Symfony erzählen die ganze Einheit auf Ihre validate Methode zu übergeben mit mehreren Feldern zuzugreifen:

public function getTargets() 
{ 
    return self::CLASS_CONSTRAINT; 
} 

Und Ihre validate:

public function validate($entity, Constraint $constraint) 
{ 
    // Do whatever validation you need 
    // You can specify an error message inside your Constraint 
    if (/* $entity->getFieldA(), ->getFieldB(), ->getFieldC() ... */) { 
     $this->context->addViolationAt(
      'foo', 
      $constraint->message, 
      array(), 
      null 
     ); 
    } 
} 
+0

Funktioniert wie ein Charme! Vielen Dank! – pikachu0

0

Sie können dies tun, mit Group Sequence Providers, zum Beispiel:

use Symfony\Component\Validator\GroupSequenceProviderInterface; 

/** 
* @Assert\GroupSequenceProvider 
*/ 
class MyObject implements GroupSequenceProviderInterface 
{ 
    /** 
    * @Assert\NotBlank(groups={"OptionA"}) 
    */ 
    private $fieldA; 

    /** 
    * @Assert\NotBlank(groups={"OptionA"}) 
    */ 
    private $fieldB; 

    /** 
    * @Assert\NotBlank(groups={"OptionB"}) 
    */ 
    private $fieldC; 

    public function getGroupSequence() 
    { 
     $groups = array('MyObject'); 

     if ($this->fieldA == null && $this->fieldB == null) { 
      $groups[] = 'OptionB'; 
     } else { 
      $groups[] = 'OptionA'; 
     } 

     return $groups; 
    } 
} 

Nicht getestet, aber ich denke, es würde funktionieren

Verwandte Themen