Comment autoriser les valeurs vides dans les validateurs symfony2

Je voudrais appliquer des validateurs sur les propriétés d'un objet uniquement lorsque la valeur n'est pas vide, c'est-à-dire.

Maintenant comportement symfony standard:

class Entity
{
    /**
     * @ORMColumn(type="string", nullable=true)
     * @AssertEmail()
     */
    protected $email;
    (...)
}

Cet objet ne passera pas la validation si un email est null, ou une chaîne vide, existe-t-il un moyen de dire au validateur d'affirmer comme valide, une valeur vide et de valider uniquement si le champ contient des données?

PS je sais que je peux écrire un validateur de rappel, mais écrire un rappel pour chaque champ juste pour avoir la fonctionnalité "allowEmpty" n'est pas si agréable.

24
demandé sur canni 2011-09-22 21:52:44

6 réponses

, Vous devez définir explicitement 'required' => false votre FormBuilder classe pour tous les champs facultatifs. Voici un paragraphe décrivant options de type de champ .


Modifier. obtenir pas mal de downvotes. Par défaut tous les validateurs traiter null valeurs valides, , sauf NotNull et NotEmpty. Aucun des deux n'a été utilisé dans la question. La question est implicitement de savoir comment désactiver l'attribut required côté client activé par défaut.

25
répondu gilden 2018-02-26 10:20:45

Définir l'option required n'est pas la solution:

Notez également que la définition de l'option requise sur true n'entraînera pas la validation côté serveur à appliquer. En d'autres termes, si un utilisateur soumet une valeur vide pour le champ (avec un ancien navigateur ou un service web, par exemple), elle sera acceptée comme valeur valide sauf si vous utilisez la validation NotBlank ou NotNull de Symfony contrainte.

Http://symfony.com/doc/current/book/forms.html#field-type-options

Pour mes validateurs personnalisés, j'ajoute un

if (null == $value) {
    return true;
}

À la méthode isValid(). Cependant, je ne suis pas sûr de ce qui serait le meilleur moyen pour les classes de validateur standard.

19
répondu David de Boer 2012-02-27 08:53:07

Si je comprends bien, vous voulez une validation côté serveur uniquement si la valeur est entrée. Je suis exactement dans le même scénario. Je veux valider une URL uniquement si l'URL est fournie. La meilleure façon que je suis tombé sur était d'écrire ma propre classe de validation personnalisée. Vous pouvez écrire une classe de validation personnalisée Générique.

J'ai suivi ce lien https://symfony-docs-chs.readthedocs.org/en/2.0/cookbook/validation/custom_constraint.html sauf pour quelques changements à cause de la dernière version de symfony. Voici l'implémentation

Acme \ BundleNameBundle\Validator\Constraints \ Cstmurl

namespace Acme\BundleNameBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Url;

/**
 * @Annotation
 */
class CstmUrl extends Url
{
    public $message = 'The URL "%string%" is not valid';
}

Acme \ BundleNameBundle\Validator\Constraints \ Cstmurlvalidator

namespace Acme\BundleNameBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Url;
use Symfony\Component\Validator\Constraints\UrlValidator;

class CstmUrlValidator extends UrlValidator
{
    public function validate($value, Constraint $constraint)
    {
        if(!$value || empty($value))
            return true;

        parent::validate($value, $constraint);
    }
}

Validtion.yml

Acme\BundleNameBundle\Entity\Student:
    Url:
        - Acme\BundleNameBundle\Validator\Constraints\CstmUrl: ~

À L'intérieur du contrôleur, il suffit de lier la contrainte que vous feriez normalement

'constraints'=> new CstmUrl(array("message"=>"Invalid url provided"))

Je suis sûr qu'il peut y avoir d'autres meilleures façons de le faire, mais pour l'instant, je pense que cela fait bien le travail.

3
répondu Ahad Ali 2015-03-16 04:23:35

Juste au cas où quelqu'un d'autre rencontrerait cette même question. Je préfère le résoudre personnellement en ajoutant l'attribut suivant dans mon modèle de brindille:

{{ form_row(form.<field>, {'required': false}) }}
2
répondu Anton Babushkin 2013-09-30 04:00:35

Voici l'astuce que j'ai trouvée en fait:

Https://github.com/symfony/symfony/issues/5906

Vous devez écrire un transformateur de données qui ne fait rien, puis l'ajouter à votre champ. Après cela, juste appelle la méthode submit () avec le deuxième paramètre à false.

Notez que C'est ok avec Symfony 2.3.

1
répondu choomz 2013-07-24 08:22:59

Le type de champ deviner gère cela. http://symfony.com/doc/current/book/forms.html#field-type-guessing

Cela dépend de votre déclaration de formulaire: "le" devinant " est activé lorsque vous omettez le deuxième argument de la méthode add () (ou si vous lui passez null). Si vous passez un tableau d'options comme troisième argument (fait pour dueDate ci-dessus), ces options sont appliquées au champ deviné."

0
répondu David 2014-03-18 16:45:47