Symfony valider un formulaire avec des champs de faux formulaires cartographiés

j'ai un formulaire avec des champs supplémentaires ajoutés avec l'option mapped à false . Mais quand j'essaie de valider mon formulaire, il ne passe pas en indiquant "cette valeur n'est pas valide" au-dessus de ces champs de formulaire. Cette option n'est pas censée contourner la validation?

Ces champs de formulaire ne sont utiles que pour remplir les autres champs et je n'ai pas besoin d'enregistrer ou même vérifier.

la seule solution que j'ai trouvée est de supprimer tous les champs supplémentaires avec js sur un bouton de soumission cliquez sur.

29
demandé sur Habeeb Perwad 2012-10-16 13:38:26

4 réponses

ce message n'est pas à jour avec Symfony 2.3

de lire les commentaires en bas

une nouvelle version arrive !

la Validation des acquis non cartographié les champs dans le Formulaire (Symfony 2.1.2)

il s'agit d'une réponse globale pour certaines questions sur le débordement des piles sur la façon actuelle de valider un champ non limité ou non cartographié dans les formulaires.

le riche écosystème Symfony 2 fait de notre cadre de choix un outil en évolution rapide.

La version Symfony 2.1 apporte beaucoup d'erreurs. Cela signifie que ce qui fonctionne avec Symfony 2.0 à 2.1.2 ne fonctionnera plus dans Symfony 2.3. Pour plus d'informations à ce sujet, lire MISE à niveau à PARTIR de Symfony 2.0 à 2.1 et de lire @deprecated commentaires dans le code Symfony.

Non consolidé fields

lors de la construction d'un formulaire, vous utilisez habituellement des entités, et votre validation peut être faite dans L'entité elle-même réservoirs à des annotations de Validation.

namespace Dj\TestBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**    
 * Dj\TestBundle\Entity\Post
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Dj\TestBundle\Entity\PostRepository")
 */
class Post
{
    // ... some code

    /**
    * @var string $title
    * @ORM\Column(name="title", type="string", length=200, nullable=false)
    * @Assert\NotBlank()
    */
    private $title;

    // .. getters and setters
}

, Mais parfois (souvent), vous devez insérer des champs de votre formulaire qui ne sont pas associées au modèle.

notre modèle exemple:

namespace Dj\TestBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Dj\TestBundle\Entity\Post
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Dj\TestBundle\Entity\PostRepository")
 */
class Post
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**ghjkl
     * @var string $title
     * @ORM\Column(name="title", type="string", length=200, nullable=false)
     * @Assert\NotBlank()
     */
    private $title;

    // ... getters and setters
}

si nous voulons ajouter un champ supplémentaire appelé myExtraField à notre formulaire nous faisons :

class PostType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('title')
                ->add('myExtraField', 'choice', array(
                        'label' => 'myExtraField option :',
                        'choices' => array(
                            1 => 'Option One',
                            2 => 'Option Wat !'
                        ),
                        'expanded' => true,
                        'mapped' => false
                   ));
    }
    // other methods
}

Note:

  • mappé remplace property_path qui sera obsolète dans Symfony 2.3
  • vous pouvez ajouter une valeur sélectionnée par défaut à myExtraField en ajoutant un 'data' = > 1 entrée dans votre tableau d'options.

exemple de code:

$builder->add('title')
    ->add('myExtraField', 'choice', array(
        'label' => 'myExtraField option :',
        'choices' => array(
            1 => 'Option One',
            2 => 'Option Wat !'
        ),
        'data' => 1, // default selected option
        'expanded' => true,
        'mapped' => false
));

si vous voulez valider le champ myExtraField vous ne pouvez pas le faire dans les annotations de L'entité Post, vous devez le faire dans votre forme.

Validation non mappé champ - Symfony 2.0 manière

la manière 2.0 était d'ajouter un validateur au Form builder ($builder - > addValidator(..)), mais cette méthode est obsolète !

namespace Dj\TestBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

// needed namespaces for 2.0 validation
use Symfony\Component\Form\CallbackValidator;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormError;

class PostType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // ... $builder->add()

        // VALIDATING NON MAPPED FIELD Symfony 2.0 way
        /** @var Symfony\Component\Form\CallbackValidator $myExtraFieldValidator **/
        $myExtraFieldValidator = new CallbackValidator(function(FormInterface $form){
          $myExtraField = $form->get('myExtraField')->getData();
            if (empty($myExtraField)) {
              $form['myExtraField']->addError(new FormError("myExtraField must not be empty"));
            }
        });
        // adding the validator to the FormBuilderInterface
        $builder->addValidator($myExtraFieldValidator);
    }
    // ... other methods
}

ceci valide actuellement le champ myExtraField, mais $ builder->addValidator mourra en Symfony 2.3 !

le code compatible Forward

comme indiqué dans mise à niveau de Symfony 2.0 à 2.1 , comme le FormValidatorInterface est déprécié, nous devons maintenant passer notre fonction de fermeture de validation d'un écouteur d'événements lié à FormEvents:: post_bind event.

c'est le code.

namespace Dj\TestBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

// needed namespaces for 2.1 validation
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormError;

class PostType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // ... $builder->add()

        // VALIDATING NON MAPPED FIELD Symfony 2.1.2 way (and forward)
        /** @var \closure $myExtraFieldValidator **/
        $myExtraFieldValidator = function(FormEvent $event){
            $form = $event->getForm();
            $myExtraField = $form->get('myExtraField')->getData();
            if (empty($myExtraField)) {
              $form['myExtraField']->addError(new FormError("myExtraField must not be empty"));
            }
        };

        // adding the validator to the FormBuilderInterface
        $builder->addEventListener(FormEvents::POST_BIND, $myExtraFieldValidator);
    }
    // ... other methods
}

cela peut certainement être amélioré avec de l'aide de gourous Sf, mais pour l'instant il valide unbounded form field d'une manière compatible forward.

l'Espérance qui permet de débloquer certains d'entre nous.

David

73
répondu David Jacquel 2017-05-23 12:10:10

comme je l'ai mentionné dans une question sur un sujet similaire , depuis Symfony 2.1, vous devez utiliser l'option 'constraints' pour ajouter une validation à vos champs non-mappés:

use Symfony\Component\Validator\Constraints\MinLength;
use Symfony\Component\Validator\Constraints\NotBlank;

$builder
    ->add('firstName', 'text', array(
        'constraints' => new MinLength(3),
    ))
    ->add('lastName', 'text', array(
        'constraints' => array(
            new NotBlank(),
            new MinLength(3),
        ),
    ))
;

J'espère que ça aidera quelqu'un comme moi qui a perdu du temps avec ça...

30
répondu Żabojad 2017-05-23 12:02:39

si vous êtes déjà en utilisant une contrainte alors vous pouvez faire ceci:

$builder
    ->add('new', 'repeated', array(
            'type' => 'password',
            'required'          => true,                    
            'invalid_message' => 'crmpicco.status.password_mismatch',
            'constraints'       => array(
                new NotBlank(),
                new Assert\Length([
                    'min'        => 2,
                    'max'        => 50,
                    'minMessage' => 'Your first name must be at least 2  characters long',
                    'maxMessage' => 'Your first name cannot be longer than 2 characters',
                ])
            )
        ))
    ->add('save', 'submit', array(
            'label' => 'password.form.fields.save',
        ))
    ;
5
répondu crmpicco 2016-05-18 03:39:27

ça marche. J'ai vérifié pour symfony 2.1. Le Code doit être comme ceci:

$builder->add('password', 'password', ['required' => false, 'mapped' => false]);

bien sûr, les biens "requis" ne sont pas requis. exemple tiré de la documentation.

0
répondu Александр Бобров 2014-02-06 03:50:46