Formulaire renvoi valeurs NULL

a marqué ce sujet comme résolu.

C’est encore moi. Je ne vais pas ouvrir un autre sujet juste pour un petit problème.

Je ne suis pas sûr de comprendre comment fonctionne exactement ceci :

1
2
3
4
5
        {% if app.flashes('success') is defined %}
            <div class="col alert alert-success mb-auto">Défini</div>
        {% else %}
            <div class="col alert alert-success mb-auto">Pas défini</div>
        {% endif %}

Quand il n’y a rien dans app.flashes(’success’), mon test renvoie vrai mais quand il y a quelque chose dedans (via un contrôleur), le test me renvoie faux. Et si je remplace le is defined par is not empty, le test me renvoie faux les deux fois.

Du coup, comment tester si un message flash existe ? J’ai également essayé avec app.flashes('success')|length > 0 mais sans succès également.

o_O

Donc ce n’est pas une instance de \Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface ? Pourtant, si c’est un tableau, comment diantre se fait-il qu’appeler get(type) ne pose pas de problème ?

Au pire, tu peux boucler sur les messages comme expliqué dans la documentation officielle. S’il n’y a pas de message d’un certain type, tu n’auras pas de message à afficher.

En même temps, je trouve ton code étrange : tu regardes s’il y a un message flash, et s’il n’y en a pas, tu en affiches un autre… Pourquoi ne pas définir l’un ou l’autre et afficher le message quel qu’il soit ?
Et si c’est une question de logique fonctionnelle, pourquoi se baser sur les messages flash ?

+0 -0

Le fait d’afficher 2 messages différents, c’est juste pour voir si ma condition fonctionne. ^^

En fait, j’aimerais juste ne pas créer la div alert s’il n’y pas de notifications. D’où mon test pour savoir si il y en a ou pas.

Concernant t’as première remarque, dans la doc, ils disent ceci, dans leur code :

// $this->addFlash() is equivalent to $request->getSession()->getFlashBag()->add()

Je note surtout que la documentation explique aussi comment afficher les messages flash par type (l’extrait de code Twig juste après celui dont tu tires la citation). Sachant que si on prend le second exemple, tu peux extraire le <div class="flash-{{ label }}"> de la boucle intérieure pour qu’il soir "entre" les deux boucles. Si tu n’as aucun message flash, il n’y aura aucun conteneur, et si tu as ne serait-ce qu’un seul d’un type, tu auras un conteneur pour lui. Et si tu en as plusieurs d’un type, tu aurais un conteneur par type. C’est pas ce que tu aimerais ?

+0 -0

Yop, c’est de nouveau moi.

Je suis toujours dans mon formulaire d’inscription et je fait face un autre problème que je n’arrive pas à comprendre.

Mon formulaire n’a pas l’air d’être soumis quand je clique sur le bouton d’inscription.

<?php
class RegisterType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('username', TextType::class, array(
                'attr' => array('placeholder' => 'Pseudo'),
                'label' => false
            ))
            ->add('password', RepeatedType::class, array(
                'type' => PasswordType::class,
                'invalid_message' => 'Les deux mots de passe doivent être identiques',
                'required' => true,
                'first_options' => array('label' => false, 'attr' => array('placeholder' => 'Mot de passe')),
                'second_options' => array('label' => false, 'attr' => array('placeholder' => 'Confimer le mot de passe'))
            ))
            ->add('email', EmailType::class, array(
                'attr' => array('placeholder' => 'Email'),
                'label' => false
            ))
            ->add('firstName', TextType::class, array(
                'attr' => array('placeholder' => 'Prénom'),
                'label' => false
            ))
            ->add('lastName', TextType::class, array(
                'attr' => array('placeholder' => 'Nom'),
                'label' => false
            ))
            ->add('phoneN1', TelType::class, array(
                'attr' => array(
                    'placeholder' => 'Téléphone fixe',
                    'maxlength' => 10
                ),
                'label' => false
            ))
            ->add('phoneN2', TelType::class, array(
                'attr' => array(
                    'placeholder' => 'Téléphone mobile',
                    'maxlength' => 10
                    ),
                'label' => false
            ))
            ->add('address', TextType::class, array(
                'attr' => array('placeholder' => 'Rue'),
                'label' => false
            ))
            ->add('birthdate', BirthdayType::class, array(
                'widget' => 'single_text'
            ))
            ->add('city', EntityType::class, array(
                'class' => City::class,
                'query_builder' => function(EntityRepository $er){
                    return $er->createQueryBuilder('listCities')
                        ->orderBy('listCities.npa', 'ASC');
                }
            ))
            ->add('cgu', CheckboxType::class, array(
                'label' => 'J\'ai lu et j\'accepte les conditions générales d\'utilisation',
                'mapped' => false
            ))
            ->add('register', SubmitType::class, array(
                'attr' => array('class' => 'btn btn-primary'),
                'label' => 'S\'inscrire'
            ))
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => User::class
        ]);
    }
?>
<?php
   public function register(Request $request, UserPasswordEncoderInterface $encoder, \Swift_Mailer $mailer)
    {
        $user = new User();
        $form = $this->createForm(RegisterType::class);

        dump($form);
        dump($request);
        dump($user);
        exit();

        //Gestion des données renvoyées
        $form->handleRequest($request);

        if($form->isSubmitted() && $form->isValid())
        {
            
           /** Blablabla **/
        }

        return $this->render('utils/registration.html.twig', array(
            'registerForm' => $form->createView(),
        ));
    }
?>

Au moment du dump, j’ai bien les valeurs de mon formulaire dans $request, dataClass correspond à App\Entity\User dans $form mais bizarrement, le paramètre submitted est à false.

Et c’est ça qui me paraît bizarre : comment je peux avoir les valeurs du formulaire si celui-ci n’a pas été soumis ? :o

Et si j’enlève le exit() qui est juste après les dump, j’ai droit à l’erreur suivante :

Expected argument of type "integer or null", "string" given.

+0 -0

Attention à ne pas confondre la Request et le Form. C’est normal que tu retrouves tes valeurs dans ta Request ; n’importe quel formulaire passe ses valeurs dans un POST ou un GET.

Concernant ton erreur, il nous en faudrait plus, parce que là on ne peut pas vraiment savoir d’où cela vient. Même si je suppose que l’erreur est liée au champ cgu. À moins qu’elle ne soit liée à un attribut hors formulaire.

Edit : Pense à lier ton $user à ton formulaire :

<?php
$user = new User();
$form = $this->createForm(RegisterType::class, $user);
+0 -0

Mais alors, comment t’expliques le fait que l’attribut method de ma Request soit un POST et qu’elles contiennent bien les valeurs renvoyées par le formulaire mais qu’en même temps, dans mon Form, l’attribut submitted soit à false alors que j’ai cliqué sur le bouton d’inscription ?

Pour l’erreur, elle vient au moment du $form->handleRequest($request); car si je fait un exit juste après cette ligne, l’erreur s’affiche et l’exit n’est pas pris en compte.

Et concernant ton dernier point, j’ai cru lire que cela n’était pas nécessaire car j’indiquais explicitement qu’il s’agit de la classe User dans l’option setDefaults dans la fonction resolver.

EDIT : Voilà l’affichage des dump au moment de l’erreur. J’ai même fait un dup

Form {#6610 ▼
  -config: FormBuilder {#6611 ▶}
  -parent: null
  -children: OrderedHashMap {#6620 ▶}
  -errors: []
  -submitted: false
  -clickedButton: null
  -modelData: null
  -normData: null
  -viewData: null
  -extraData: []
  -transformationFailure: null
  -defaultDataSet: true
  -lockSetData: false
}
Request {#207 ▼
  +attributes: ParameterBag {#230 ▶}
  +request: ParameterBag {#228 ▼
    #parameters: array:1 [▼
      "register" => array:13 [▼
        "username" => "Test"
        "password" => array:2 [▶]
        "lastName" => "tqeqwe"
        "firstName" => "weqer"
        "birthdate" => "1992-12-15"
        "email" => "test@test.com"
        "phoneN1" => "1892347238"
        "phoneN2" => "2314872384"
        "address" => "Test 14"
        "city" => "3"
        "cgu" => "1"
        "register" => ""
        "_token" => "2Zah0QzET6STV8Iku03fr2614YPVw-TIgCxMHfPbwFM"
      ]
    ]
  }
  +query: ParameterBag {#229 ▶}
  +server: ServerBag {#272 ▶}
  +files: FileBag {#252 ▶}
  +cookies: ParameterBag {#231 ▶}
  +headers: HeaderBag {#294 ▶}
  #content: null
  #languages: null
  #charsets: null
  #encodings: null
  #acceptableContentTypes: null
  #pathInfo: "/inscription"
  #requestUri: "/inscription"
  #baseUrl: ""
  #basePath: null
  #method: "POST"
  #format: null
  #session: Session {#2014 ▶}
  #locale: null
  #defaultLocale: "fr"
  -isHostValid: true
  -isForwardedValid: true
  basePath: ""
  format: "html"
}
User {#3449 ▼
  -id: null
  -username: null
  -password: null
  -email: null
  -firstName: null
  -lastName: null
  -phoneN1: null
  -phoneN2: null
  -address: null
  -birthdate: null
  -lastLogin: null
  -picture: null
  -hash: null
  -isActive: null
  -city: null
  -postulations: ArrayCollection {#3517 ▶}
  -jobOffers: ArrayCollection {#3518 ▶}
  -documents: ArrayCollection {#3519 ▶}
}
SubmitButton {#6766 ▼
  -clicked: false
  -parent: Form {#6610 ▶}
  -config: SubmitButtonBuilder {#6767 ▶}
  -submitted: false
}
+0 -0

Il y a plusieurs façons de soumettre un formulaire :

  • activer un élément type="submit" ou type="image" ;
  • appuyer sur ENTER depuis un <input> (selon le navigateur, j’imagine) ;
  • utiliser du JavaScript document.getElementsById(monForm).submit.

Je ne sais pas exactement comment Symfony fait pour déterminer si un formulaire a été soumis, mais s’il se base sur le fait qu’un bouton submit ait été activé, je ne crois pas que les deux dernières méthodes activent effectivement le bouton (et comment ça se passe pour les formulaires dont le bouton a été placé dans le HTML, comme c’est conseillé ?).
D’autre part, il me semble que c’est la méthode handleRequest() qui change la valeur du paramètre submitted, selon des critères que je ne suis pas allé regarder au moment de publier ce message.

Par rapport à cette histoire de résolution : le fait de spécifier quel type d’objet est sous-jacent à une classe ne fait que renseigner au composant de formulaire quelle sera la structure des données qu’il recevra pour pré-remplir le formulaire et par ricochet celle qu’il faudra utiliser pour organiser les valeurs soumises, récupérable soit dans l’objet passé comme second argument de createForm(), soit avec $form->getData().

+0 -0

La méthode handleRequest prend les données envoyées seulement si cela provient de la méthode POST. En gros, si la page a été appelée via GET, pour Symfony, cela veut dire qu’il faut afficher le formulaire mais si elle a été appelé via POST, alors là, il faut gérer la soumission du formulaire (d’après ce que j’ai compris).


Finalement, j’ai trouvé l’erreur. En fait, cela venait du type de mes champs correspondant au téléphone. J’avais mis un type TelType mais Symfony renvoie au format text alors que dans ma BDD, j’utilise un type integer.

+0 -0

J’ai changé le type de la propriété. Cela me permet de gérer la longueur maximale du champ pour l’affichage (ce que ne permet pas un champ de type entier)


Par contre, il se passe toujours un truc bizarre.

Je reçois l’email, tout va bien et quand je clique sur le lien d’activation dans l’email (typiquement, via GMAIL), j’arrive bien sur la page d’activation mais soudainement, mon site "se bloque" si bien quand je recharge avec F5, il ne se charge plus et l’icône d’actualisation tourne indéfiniment.

Je suis obligé

  1. Arrêter le serveur
  2. Le redémarrer : là, il me dit qu’il écoute sur le port 8001
  3. L’arrêter à nouveau
  4. Je le redémarre une nouvelle fois et là, il écoute bien sur le port 8000 et tout fonctionne à nouveau.

o_O ? Il y a une manipulation particulière à faire avec les emails ? Ou c’est lié l’environnement de production ?

J’ai eu des soucis de ce genre avec Internet Explorer et Opera avec Presto, une histoire de nombre de connexions ouvertes d’une certaine manière qu’apparemment seuls ces deux navigateurs utilisent. Je ne me souviens plus exactement de ce qu’il faut changer dans les paramètres d’Apache pour pallier cela… Je vais tenter de retrouver.


La méthode handleRequest prend les données envoyées seulement si cela provient de la méthode POST. En gros, si la page a été appelée via GET, pour Symfony, cela veut dire qu’il faut afficher le formulaire mais si elle a été appelé via POST, alors là, il faut gérer la soumission du formulaire (d’après ce que j’ai compris).

Charvalos

Je pense que ça dépend aussi de la méthode spécifiée pour le formulaire, il doit y avoir quelque chose qui peut gérer les envois en GET quand le formulaire est prévu pour utiliser cette méthode.

+0 -0

J’ai eu des soucis de ce genre avec Internet Explorer et Opera avec Presto, une histoire de nombre de connexions ouvertes d’une certaine manière qu’apparemment seuls ces deux navigateurs utilisent. Je ne me souviens plus exactement de ce qu’il faut changer dans les paramètres d’Apache pour pallier cela… Je vais tenter de retrouver.

Je vais chercher aussi de mon côté. Au passage, j’utilise Chrome.

Bizarre. J’ai rajouté dans mon fichier http.conf et effectivement, cela a boosté la vitesse de mon serveur XAMPP mais j’ai toujours ce problème dès que je clique sur le lien contenu dans le mail.

Je n’y comprends rien. C’est comme si le fait de cliquer sur le lien bloquait le port.

Et pour rajouter de la bizarrerie, quand je fais php bin/console server:status, j’ai le droit à

[WARNING] No web server is listening.

Est-ce que cela viendrait du fait que j’utilise le Web Server intégré à Symfony ?

EDIT : Bon, cela a l’air de fonctionné. Peut-être que cela venait du fait que je faisais un exit et que cela mettait le bordel après.

Encore une question que je n’arrive pas à trouver : comment mettre à jour des données telles que la dernière date de connexion si l’authentification est réussie ?

+0 -0

Je me méfiais de ce que j’avais loupé une mise à jour du dernier message  ^^

Est-ce que cela viendrait du fait que j’utilise le Web Server intégré à Symfony ?

Charvalos

Ah oui, j’oublie toujours cette possibilité. Du coup, manipuler Apache alors que tu ne le sers pas est inutile, effectivement.

Encore une question que je n’arrive pas à trouver : comment mettre à jour des données telles que la dernière date de connexion si l’authentification est réussie ?

Charvalos

Je suppose qu’il y a un événement noyau lors d’une authentification réussie, tu devrais ainsi pouvoir ajouter un service qui écoute cet événement et met à jour ladite date.

+0 -0

Effectivement, pour ajouter la dernière date de connexion, il suffit de suivre ceci.

Par contre, pour en revenir à mon formulaire, il y a encore une chose qui ne fonctionne pas comme je l’aimerais.

J’ai mes 2 champs de téléphones (dont est un obligatoire) de type TelType. Comme indiqué dans la doc, cela retourne un string et dans ma BDD, les deux champs sont donc de types VARCHAR.

Le problème est que si j’entre du texte, par exemple, 123tz213, Symfony va gueuler avec l’erreur suivante :

Expected argument of type "integer", "string" given.

Du coup, j’ai regardé les validations disponibles et j’ai mis ceci :

<?
    /**
     * @ORM\Column(type="string", length=10)
     * @Assert\NotBlank(message="Veuillez entrer un numéro de téléphone correct")
     * @Assert\Type(type="numeric", message="Veuillez entrer un numéro de téléphone correct")
     */
    private $phoneN1;

    /**
     * @ORM\Column(type="string", nullable=true, length=10)
     * @Assert\Type(type="numeric", message="Veuillez entrer un numéro de téléphone correct")
     */
    private $phoneN2;
?>

Et d’après la doc PHP, is_numeric vérifie qu’une chaine de caractère est de type numérique.

Ce que je ne comprends pas, c’est qu’au lieu d’afficher le message d’erreur "Veuillez entrez ….", Symfony me gueule dessus. C’est comme si mon assertion n’était pas pris en compte.

+0 -0

Attention, is_numeric vérifie que la chaîne passée en paramètre contient un nombre valide sous forme de chaîne. Donc s’il y a des lettres qui n’entrent pas dans l’hexadécimal, et au moindre espace ou la moindre virgule, la fonction retourne false, sauf erreur.

Je ne comprends pas non-plus l’erreur que te génère Symfony. C’est à quelle étape exactement qu’elle survient ? A l’appel de setPhoneN1() ?

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte