IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Problème de formulaire


Sujet :

Symfony PHP

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 207
    Par défaut Problème de formulaire
    Bonjour.

    Sur la home de mon site je possède une liste d'articles.
    Quand je clique sur un des articles je fais donc appel à mon executeShow qui affiche les détails de l'article avec en dessous un formulaire de commentaires.

    Je fais ceci dans mon action
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $this->comment_form = new CommentForm();
    Dans la template showSucess.php (qui contient donc les détails d'un post -> $post) j'affiche donc en bas de mon article un partial qui m'affiche mon formulaire de commentaires.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <?php include_partial('form_comment', array('form' => $comment_form)) ?>
    L'action de mon formulaire fait appel à l'action ci dessous.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public function executeCreatecomment(sfWebRequest $request)
      {
        $this->forward404Unless($request->isMethod(sfRequest::POST));
     
        $this->comment_form = new CommentForm();
     
        $this->processForm($request, $this->comment_form);
     
       // que mettre ici ???
      }
    Comment faire pour lors de la soumissions (on oublie de remplir un champs obligatoire par exemple) pouvoir revenir sur ma page show avec le formulaire qui affiche mon formulaire avec la liste des erreurs?

    Si dans executeCreatecomment à la fin je fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    getPartial('form_comment', array('form' => $this->comment_form))
    du coup je vois bien le formulaire qui affiche les erreurs mais je perd les détails du post car seul le partial s'affiche, du coup je tourne en rond et je sais pas comment gérer le formulaire + sa validation et laisser afficher les details de mon post au dessus.

    SI vous avez des astuces je suis preneur.

    Merci

  2. #2
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Tous le code de vérification est inclus dans le form, le code de sauvegarde aussi.

    A ta place, je créerais une action dans mon module article, action du genre executeAddComment, qui fait la vérification et prépare les données comme le template show article.

    Et si tu dois ré-afficher, tu bascules sur le template show.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 207
    Par défaut
    Citation Envoyé par mimi68 Voir le message
    Tous le code de vérification est inclus dans le form, le code de sauvegarde aussi.

    A ta place, je créerais une action dans mon module article, action du genre executeAddComment, qui fait la vérification et prépare les données comme le template show article.

    Et si tu dois ré-afficher, tu bascules sur le template show.
    Je vois pas ce que ca pourrait changer en fait.

    Quand je vais etre sur ma page show j'aurais en bas un formulaire d'ajout de commentaires qui aura comme action
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <form action="<?php echo url_for('post/addcomment') ?>" method="post">
    Si je rebascule sur le template show, tu veux dire que je dois faire ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $this->setTemplate('show')
    mais ca va refaire la meme chose, quand je vais aller sur mon template show, les erreurs de mon formulaire ne seront pas visibles non?

  4. #4
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Si parce que tu as binder ton form avec les données récupérées. Donc les erreurs seront générées.

    Et comme tu auras récupérés les données de l'article, toute la page pourra être visible.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 207
    Par défaut
    Citation Envoyé par mimi68 Voir le message
    Si parce que tu as binder ton form avec les données récupérées. Donc les erreurs seront générées.

    Et comme tu auras récupérés les données de l'article, toute la page pourra être visible.
    Ton executeAddComment ne serait pas équivalent à mon executeCreatecomment?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    public function executeCreatecomment(sfWebRequest $request)
      {
        $this->forward404Unless($request->isMethod(sfRequest::POST));
     
        $this->comment_form = new CommentForm();
     
        $this->processForm($request, $this->comment_form);
     
        //$this->setTemplate('show');
      }
     
    protected function processForm(sfWebRequest $request, sfForm $form)
      {
        if ($request->isMethod('post'))
         {
     
            $form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
            if ($form->isValid())
            {
              $commentaire = $form->save();
              $this->redirect($this->generateUrl('post_show_detail', $commentaire));
            }
     
         }
      }
    Je vois pas la différence en fait avec ce que tu me dis.

    Tu pourrais mieux expliciter (genre deux trois lignes de code par ci par la, car au final j'ai l'impression qu'on fait la même chose), j'ai vraiment du mal à voir ce que tu insinues

    Merci à toi.

  6. #6
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    A peu de chose près, sauf erreur de ma part (je me méfie à cet heure ci) tu ne récupère pas les données permettant d'afficher l'article.

    Bon, c'est une supposition, je ne sais pas ce que cache le template "post_show_detailSuccess" mais je ne vois pas où tu récupères les données nécessaire à l'affichage de l'article.

    Si je suis vraiment trop à côté, demains je ferais un truc plus précis.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 207
    Par défaut
    Dans mon executeShow, je récupère mon objet post grâce au routing que j'ai mis en place.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public function executeShow(sfWebRequest $request)
    {
       $this->post = $this->getRoute()->getObject();
    }
    Et oui en effet comme tu le dis dans ma méthode executeCreatecomment(sfWebRequest $request) ou je soumet mon formulaire il me manque une astuce me permettant de récupérer mon objet post et ainsi je pense je pourrais de nouveau afficher mon article avec en dessous le formulaire qui affiche les erreurs etc.

  8. #8
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Une possibilité serait que dans ton formulaire tu initialises un champ caché avec l'id du post en question.

    Mais cela me semble un peu lourd.

    L'autre solution serait de stockée l'Id du post dans l'objet user, mais en cas de double fenêtre sur deux posts, ça va être la merde.


    Une idée un peu folle mais qui pourrait marcher sous symfony. Jamais testé par moi.

    Le form attend une URL de retour de la forme www.monsite.ici/module/action.php.

    Avec les routes de symfony et le système de récupération des données on pourrait avoir une URL du genre : www.monsite.ici/affPost/idPost/addComment.php et récupérer des informations de type get dans une URL envoyée en post... Mais c'est un peu dingue comme idée et il faudrait monter un prototype.

    Après, cela devrait marcher avec tous les explorateurs, vu que le travail de ouf est fait sur le serveur. Mais cela va-t-il marcher sur le serveur ? The question.

    Une fois que tu as l'Id du post, plus de problème pour récupérer les données. Et peut-être même qu'avec ce système tu peux les récupérées par "$this->getRoute()->getObject()" Mais là, symfony serait ... magique !!!

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 207
    Par défaut
    Bon bon bon, ce qui m'énerve un peux avec ce symfony c'est que pour faire des trucs tout simple on galère pas mal.

    Je vais encore forcer et forcer pour trouver une solution, et en plus vu la communauté symfony pour trouver de l'aide c'est la galère!!!

    Merci à toi sinon d'avoir contribué.

  10. #10
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Pas de problèmes.

    Le problème avec symfony, c'est qu'il faut penser "développement avec symfony" et non pas "développement en PHP".

    Une fois que tu es arrivé à faire abstraction des habitudes PHP et que tu penses symfony, c'est beaucoup plus simple.

    La seul difficulté dans ton formulaire est de retourner l'Id du post. Le reste est très simple.

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 85
    Par défaut
    Citation Envoyé par mimi68 Voir le message
    Une possibilité serait que dans ton formulaire tu initialises un champ caché avec l'id du post en question.

    Mais cela me semble un peu lourd.
    En quoi cette solution vous parrait lourde ? Elle me semble plutôt bien indiqué.

  12. #12
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Citation Envoyé par AoSiX Voir le message
    En quoi cette solution vous parrait lourde ? Elle me semble plutôt bien indiqué.
    Lorsque le formulaire inclus va être régénéré, les champs masqués ne le sont pas. Il faut donc gérer manuellement la ré-alimentation du champ à chaque ré-affichage pour s'assurer que le champ caché aura toujours l'Id du post.

    Mais effectivement, ce n'est pas plus lourd que le fait de passer par le lien.

  13. #13
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Bon, j'ai un peu joué ce soir, ce truc de get et post mélangé me turlupinait un peu.

    Et bien, cela marche, et cela marche même très bien.

    J'ai monté un mini projet de blog.

    Le schéma
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
     
    post:
      actAs:
        sluggable:
          unique:         true
          fields:         [ titre ]
          canUpdate:      true
        timestampable:
      columns:
        user_id:   integer(4)
        titre:            string(100)
        presentation:     string(250)
        texte:            string(1000)
      relations:
        user:
          class:          sfGuardUser
          local:          user_id
          foreign:        id
          foreignAlias:   posts
          onDelete:       CASCADE
     
    comment:
      actAs:
        timestampable:
      columns:
        post_id:          integer
        comment:          string(250)
        nom:              string(75)
        email:            string(100)
      relations:
        post:
          local:          post_id
          foreign:        id
          foreignAlias:   comments
          onDelete:       CASCADE
    Minimum mais va nous servir pour l'exemple. J'ai rajouté du sfGuard, plus par habitude que par nécessité. Le slug aussi n'est pas paramétré.

    Un petit coup de fixture pour travailler
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
    sfGuardUser:
      user1:
        username:               user one
        password:               user1
        groups:                 [ postG ]
     
    sfGuardGroup:
      postG:
        name:                   Post editor
        permissions:            [ postP, commentP ]
     
    sfGuardPermission:
      postP:
        name:                   post
      commentP:
        name:                   comment
     
    post:
      pst1:
        user:                   user1
        titre:                  Message Un
        presentation:           La présentation du message 1
        texte:                  Le texte de la présentation du message 1
      pst2:
        user:                   user1
        titre:                  Message Deux
        presentation:           La présentation du message 2
        texte:                  Le texte de la présentation du message 2
     
    comment:
      cmt11:
        post:                   pst1
        comment:                commentaire 1
        nom:                    Le nom de Un
        email:                  nom.un@mail.srv
      cmt12:
        post:                   pst1
        comment:                commentaire 2
        nom:                    Le nom de Deux
        email:                  nom.deux@mail.srv
      cmt21:
        post:                   pst2
        comment:                commentaire 1
        nom:                    Le nom de Un
        email:                  nom.un@mail.srv
    Construire la base et les objets.

    Sur l'application, on va créer un module
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    symfony doctrine:generate-module --with-show --with-doctrine-route --non-verbose-templates frontend post post
    Et dans le fichier routing.yml, on rajoute la route pour notre module
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    post:
      class: sfDoctrineRouteCollection
      options:
        model: Post
        module: post
    Il va nous permettre d'afficher la liste des post et avec show d'en afficher un.

    On modifie le action.class.php pour récupérer les commentaires (on pourrait facilement les récupérer dans le template). On va en profiter pour initialiser notre formulaire de création de commentaire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class postActions extends sfActions
    {
        ...
     
        public function executeShow(sfWebRequest $request)
        {
            $this->post = $this->getRoute()->getObject();
            $this->comments = $this->post->getComments();
            $this->commentAddForm = new commentAddForm();
        }
     
        ...
    Le form est un peu particulier puisque je l'ai dérivé juste pour pouvoir avoir des contrôles particulier pour la création

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class commentAddForm extends BasecommentForm
    {
      public function configure()
      {
          $this->useFields(array( 'nom', 'email', 'comment'));
     
          $this->setValidator('nom', new sfValidatorString(array('max_length' => 75, 'required' => true)));
      }
    }
    Il y a des tas de validations qui pourraient être faîtes ici, j'ai juste rendu le nom obligatoire pour pouvoir générer une erreur.

    Le template show maintenant, je n'ai pas fait de partiel, mais rien ne s'y oppose.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
    <table>
      <tbody>
        <tr>
          <th>Id:</th>
          <td><?php echo $post->getId() ?></td>
        </tr>
          ...
      </tbody>
    </table>
     
    <hr />
    <table>
        <tbody>
            <?php foreach ($comments as $comment) : ?>
                <tr>
                    <th>Comment</th>
                    <td><?php echo $comment->getComment() ?></td>
                </tr>
                <tr>
                    <th>Nom</th>
                    <td><?php echo $comment->getNom() ?></td>
                </tr>
                <tr>
                    <th>eMail</th>
                    <td><?php echo $comment->getEmail() ?></td>
                </tr>
            <?php endforeach ?>
        </tbody>
    </table>
     
    <hr />
    <form action="<?php echo url_for('@postAddComment?id=' . $post->getId()) ?>">
        <h2>Ajouter un commentaire</h2>
        <table>
            <?php echo $commentAddForm ?>
            <tr>
                <td colspan="2"><input type="submit" value="add" /></td>
            </tr>
        </table>
    </form>
    <hr />
     
    <a href="<?php echo url_for('post/edit?id='.$post->getId()) ?>">Edit</a>
    &nbsp;
    <a href="<?php echo url_for('post/index') ?>">List</a>
    On y a rajouté la liste des commentaires dans un foreach, simple.

    On y a aussi rajouté le formulaire de saisie une url de retour un peu particulière. Au préalable dans le routing.yml, on y a rajouté une route avant la précédente, en tête de fichier pour renvoyer notre action de création.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    postAddComment:
      url: /post/:id/AddComment
      param:
        module: post
        action: addComment
    A noter l'inclusion de l'ID du post en cours de modification dans l'URL.

    Et dans notre formulaire, le lien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     url_for('@postAddComment?id=' . $post->getId())
    On lui indique la route à utiliser "@postAddComment" avec le paramètre Id pour générer l'URL.

    Reste à récupérer notre demande d'insertion toujours dans le module post
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    class postActions extends sfActions
    {
        public function executeAddComment(sfWebRequest $request)
        {
            $this->post = Doctrine_Query::create()
                    ->from('post p')
                    ->select('*')
                    ->where('p.id = ?', $request->getParameter('id'))
                    ->fetchOne();
            $comment = new comment();
            $comment->setPost($this->post);
            $this->commentAddForm = new commentAddForm($comment);
            $this->commentAddForm->bind($request->getParameter($this->commentAddForm->getName()));
            if ($this->commentAddForm->isValid())
            {
                $this->commentAddForm->save();
     
                $this->redirect('post_show', $post);
            }
            $this->comments = $this->post->getComments();
            $this->setTemplate('show');
        }
    On commence par initialiser l'objet $post à partir de l'id récupéré dans la requète "$request->getParameter('id')".

    On initialise un form pour comment et on l'initialise avec un objet du modèle comment, un objet vierge où l'on met juste le lien avec le post en cours.

    On lie notre form avec les données récupérer, on vérifie s'il est valide.

    Valide ! On sauvegarde le form et on redirige sur le post, ce qui affichera le commentaire dans la liste

    Pas Valide ! on initialise la liste des commentaire et on redirige sur le template show.


    C'est fonctionnel. Il reste des tas de choses à faire pour en faire un blog, mais le sujet était l'ajout de commentaires dans le formulaire d'affichage du post avec la gestion des contrôle.

    On pourrait aussi initialiser le form "comment" avec un objet vierge initialisé et lié avec le post en cours dans l'action executeShow et récupéré l'id du post à partir de là. Une autre option a creuser.

    Je joint un zip avec l'application de test.
    Fichiers attachés Fichiers attachés

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 207
    Par défaut
    Un gros merci mimi68 pour ce post très complet.
    Je le bookmark et je le lirai avec attention dès demain je pense.

    Je viendrai y faire des remarques ou poser des questions au cas ou.

    Merci

    EDIT : nickel

Discussions similaires

  1. [IIS - TOMCAT][Struts] Problème de formulaire
    Par tscoops dans le forum Tomcat et TomEE
    Réponses: 2
    Dernier message: 01/02/2005, 14h04
  2. Réponses: 7
    Dernier message: 19/10/2004, 16h12
  3. [STRUTS] problème de formulaire
    Par ultimax dans le forum Struts 1
    Réponses: 5
    Dernier message: 09/07/2004, 15h55
  4. [Struts] Problème de formulaire(s) ...
    Par djoukit dans le forum Struts 1
    Réponses: 8
    Dernier message: 10/03/2004, 23h48
  5. Réponses: 12
    Dernier message: 24/09/2003, 15h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo