it-swarm.dev

Symfony convalida il modulo con campi falso modulo mappati

Ho un modulo con campi aggiuntivi aggiunti con l'opzione mapped a false. Ma quando provo a convalidare il mio modulo, non passerà indicando "questo valore non è valido" sopra questi campi specifici del modulo. Questa opzione non dovrebbe bypassare la convalida? 

Questi campi modulo sono utili solo per popolare altri campi e non è necessario salvarli o controllarli. 

L'unica soluzione che ho trovato è quella di rimuovere tutti i campi aggiuntivi con js su un pulsante di invio fare clic. 

31
kzrdt

Questo post non è aggiornato con Symfony 2.3

leggi i commenti qui sotto

Una nuova versione sta arrivando!

Convalida dei campi non mappati in Form (Symfony 2.1.2)

Questa è una risposta globale per alcune domande StackOverflow sul modo corrente di convalidare campi non associati o non mappati nei moduli.

Il ricco ecosistema di Symfony 2 rende il nostro framework di scelta uno strumento in rapida evoluzione.
La versione 2.1 di Symfony porta molte deprecazioni. Ciò significa che ciò che funziona con Symfony 2.0 a 2.1.2 non funzionerà più in Symfony 2.3 . Per maggiori informazioni a riguardo, leggi AGGIORNA DA Symfony 2.0 a 2.1 e leggi i commenti @deprecated nel codice Symfony.

Campi non associati

Quando si crea un modulo, di solito si utilizzano le Entità e la convalida può essere effettuata nei serbatoi dell'entità stessa alle annotazioni di convalida.

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
}

Ma a volte (spesso) è necessario inserire alcuni campi nel modulo che non sono mappati al modello.

Il nostro esempio di modello è come questo:

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
}

Se vogliamo aggiungere un campo extra chiamato myExtraField al nostro modulo, facciamo:

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
}

Nota :

  • mapped sostituisce property_path che sarà deprecato in Symfony 2.3
  • puoi aggiungere un valore selezionato predefinito a myExtraField aggiungendo una 'data' => 1 voce nell'array delle opzioni.

Codice di esempio: 

$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
));

Se si desidera validare il campo myExtraField non è possibile farlo nelle annotazioni di post entità, è necessario farlo nel modulo.

Validazione campo non mappato - il modo Symfony 2.0

Il modo 2.0 era di aggiungere un validatore al generatore di moduli ($ builder-> addValidator (..)), ma questo metodo è deprecato!

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
}

Questo sta attualmente validando il campo myExtraField, BUT $ builder-> addValidator morirà in Symfony 2.3!

Il codice compatibile Forward

Come indicato in AGGIORNAMENTO DA Symfony 2.0 a 2.1 , poiché FormValidatorInterface è deprecato, ora dobbiamo passare la nostra funzione di chiusura di validazione a un listener di eventi associato all'evento FormEvents :: POST_BIND.

Questo è il codice.

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
}

Questo può certamente essere migliorato con alcuni aiuti Sf, ma per ora convalida il campo modulo non associato in un modo compatibile in avanti.

Spero che aiuti a liberare alcuni di noi.

David

74
David Jacquel

Come ho menzionato in una domanda su un argomento simile , sin da Symfony 2.1, dovresti usare l'opzione 'constraints' per aggiungere la validazione ai tuoi campi non mappati:

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),
        ),
    ))
;

Spero che possa aiutare qualcuno come me che ha perso del tempo su questo ...

30
Żabojad

Se sei già usando un vincolo allora puoi farlo:

$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
crmpicco

Le sue opere. Controllato per symfony 2.1 . Il codice dovrebbe essere così:

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

Ovviamente la proprietà 'richiesta' non è richiesta. Esempio dalla documentazione.