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

 PHP Discussion :

blocage lors de la validation du formulaire


Sujet :

PHP

  1. #1
    Membre actif Avatar de elvan49
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2006
    Messages
    274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2006
    Messages : 274
    Points : 204
    Points
    204
    Par défaut blocage lors de la validation du formulaire
    Bonjour,
    J'expose mon souci.
    Contexte : je suis le tuto Jobeet et je me suis permis de dériver...

    J'ai créé un module supplémentaire me permettant de créer des pages administrables : info
    j'ai voulu insérer un formulaire dans l'une de ses pages. Pour cela j'ai procédé ainsi :
    - création d'un model JobeetContactForm hérité directement de sfForm
    - création d'un partial _form_email dans le module info
    - création d'une méthode executeSend() dans action.class.php controllant l'envoi des données formulaire et faisant appel à une autre méthode sendForm()
    Quand je fais un envoi je suis bien retourné vers le bon template, il y a bel et bien une validation des champs qui s'applique mais je perd toutes les valeurs entrées et le _csrf_token ! Et donc à partir de là mon formulaire est bloqué car toujour invalide.
    Je vous fournis ici les codes des divers méthodes et templates :
    Ah oui, petite précision il y a une inclusion d'un second partial dans le premier mais ça ne devrait pas influer...

    lib/form/doctrine/JobeetContactForm.class.php
    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
    class JobeetContactForm extends sfForm
    {
      public function configure()
      {
     
          $this->widgetSchema['nom'] = new sfWidgetFormInput();
          $this->widgetSchema['email'] = new sfWidgetFormInput();
          $this->widgetSchema['type'] = new sfWidgetFormChoice(array(
              'choices' => Doctrine::getTable('JobeetInfo')->getTypes(),
              'multiple' => false,
              'expanded' => false,
              'label' => 'Profession'
          ));
          $this->widgetSchema['sujet'] = new sfWidgetFormChoice(array(
              'choices' => Doctrine::getTable('JobeetInfo')->getDemandes(),
              'multiple' => false,
              'expanded' => false
          ));
          $this->widgetSchema['message'] = new sfWidgetFormTextarea();
          // validators
          $this->validatorSchema['nom'] = new sfValidatorString(array(
              'min_length' => 3,
              'required' => true
          ));
          $this->validatorSchema['email'] = new sfValidatorEmail(array(
              'required' => true
          ));
          $this->validatorSchema['message'] = new sfValidatorString(array(
              'min_length' => 3,
              'max_length' => 600,
              'required' => true
          ));
          // erreur
          $this->errorSchema = new sfValidatorErrorSchema($this->validatorSchema);
      }
    }
    apps/frontend/modules/info/actions/actions.class.php [extrait]
    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
    public function executeShow(sfWebRequest $request)
      {
        $this->forward404Unless($this->jobeet_info = Doctrine_Core::getTable('JobeetInfo')->find(array($request->getParameter('id'))));
     
        $this->form_email = new JobeetContactForm();
      }
    ...
    public function executeSend(sfWebRequest $request){
          $this->forward404Unless($request->isMethod(sfRequest::POST) || $request->isMethod(sfRequest::PUT));
          $this->forward404Unless($this->jobeet_info = Doctrine_Core::getTable('JobeetInfo')->find(2));
     
          $this->form_email = new JobeetContactForm();
          $this->sendForm($request, $this->form_email);
          $this->setTemplate("show");
      }
    ...
    protected function sendForm(sfWebRequest $request, sfForm $form_email){
          //$form_email->bind($request->getParameter("devis"));
          $form_email->bind($request->getParameter($form_email->getName()));
     
              if($form_email->isValid()){
                  $sujet = $request->getParameter("sujet");
                  $message = "<h3>$sujet</h3>
                    <p>nom : ".$request->getParameter('nom')."<br />
                    email : ".$request->getParameter('email')."<br />
                    Société de type : ".$request->getParameter('type')."<br />
                    </p><p>-- Message --</p>".$request->getParameter('message');
                  $email = Swift_Message::newInstance($sujet)
                          ->setFrom($request->getParameter('email'))
                          ->setTo("contact@bibi.com")
                          ->setBody($message,"text/html");
                  $this->getMailer()->send($email);
                  $this->redirect('info/4');
              }
      }
    Et maintenant les templates...
    apps/frontend/modules/info/templates/showSuccess.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <?php if($jobeet_info->getId() == 2): ?>
            <?php include_partial("info/form_email", array('form_email' =>  $form_email, "jobeet_info" => $jobeet_info)); ?>
        <?php endif; ?>
    l'appel conditionnel sert à n'afficher le formulaire que lorsque l'action show reçoit l'id=2 qui est la page de contact.
    apps/frontend/modules/info/templates/_form_email.php
    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
    <?php use_stylesheets_for_form($form_email) ?>
    <?php use_javascripts_for_form($form_email) ?>
     
    <?php include_partial("fck", array("textarea_id" => "message", "gt" => "info"));?>
     
    <h3>Laissez-nous un message... </h3>
    <dfn>Merci de renseigner ce formulaire afin de répondre au mieux à votre demande.</dfn>
    <form name="devis" id="devis" action="<?php echo url_for('info/send?id=2') ?>" method="post" <?php $form_email->isMultipart() and print 'enctype="multipart/form-data" '; ?>>
                <table>
                    <tfoot>
                      <tr>
                        <td colspan="2"><center>
                            <span class="art-button-wrapper">
                                <span class="l"></span>
                                <span class="r"></span>
                                <input type="submit" value="Send" class="art-button"/>
                            </span>
                    </center>
                        </td>
                      </tr>
                    </tfoot>
                    <tbody>
                      <?php echo $form_email; ?>
                    </tbody>
                </table>
            </form>
    Je ne comprends pas, il faudrait sans doute que je passe un objet en argument au formulaire pour qu'il retrouve ses données mais le _csrf_token ??? Bref je sèche.
    Peut-êtr m'y suis-je mal pris depuis le départ ?Quelqu'un a-t-il une piste ? Je précise que si le formulaire est valide tout se passe bien et je suis bien renvoyé vers la bonne page. Si je rajoute un else en fin de méthode sendForm() avec un redirect vers une page d'échec j'affiche la bonne page aussi mais ce que je veux c'est revenir au formulaire invalide et permettre de le corriger !
    "n'imprimez ces messages que si nécessaire... Préservez notre planète"

  2. #2
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     $this->form_email = new JobeetContactForm();
    te crée un formulaire vierge.

    Si tu veux initialiser le formulaire avec des valeurs, soit tu passes un objet initialisé dans le constructeur, soit tu fais un bind($request). Or tu fais ton bind() et le isValid() dans ta méthode sendForm() qui a pris en entrée... une copie de ton formulaire initial. Le $this->form de ton action demeure donc placidement inchangé.

  3. #3
    Membre actif Avatar de elvan49
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2006
    Messages
    274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2006
    Messages : 274
    Points : 204
    Points
    204
    Par défaut
    C'est pourtant ainsi que procède la méthode processForm auto-générée lors de la création du module...
    Je comprends bien que je dois lui passer un objet mais je ne sais pas comment l'instancier ou s'il l'est déjà où le récupérer. On le voit bien dans executeUpdate que le formulaire est instancié avec l'objet du module.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $this->forward404Unless($jobeet_info = Doctrine_Core::getTable('JobeetInfo')->find(array($request->getParameter('id'))), sprintf('Object jobeet_info does not exist (%s).', $request->getParameter('id')));
    Mon problème je pense c'est que l'objet dont j'ai besoin n'est pas celui du module mais celui du formulaire.
    "n'imprimez ces messages que si nécessaire... Préservez notre planète"

  4. #4
    Membre actif Avatar de elvan49
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2006
    Messages
    274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2006
    Messages : 274
    Points : 204
    Points
    204
    Par défaut
    Si je complète et corrige la méthode executeSend par les lignes suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $form_email = $this->jobeet_info->bind($request);
    $this->form_email = new JobeetContactForm($form_email);
    Je retrouve mon erreur de _csrf_token mais sous une autre forme
    symfony m'affiche sa page d'erreur 500
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Unknown record property / related component "_csrf_token" on "JobeetInfo"
    "n'imprimez ces messages que si nécessaire... Préservez notre planète"

  5. #5
    Membre actif Avatar de elvan49
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2006
    Messages
    274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2006
    Messages : 274
    Points : 204
    Points
    204
    Par défaut
    J'ai ajouté ça dans actions.class.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $form_values = array(
              "sujet"=>$request->getPostParameter("sujet"), 
              "type"=>$request->getPostParameter('type'),
              "message"=>$request->getPostParameter('message'),
              "nom"=>$request->getPostParameter('nom'),
              "email"=>$request->getPostParameter('email'),
              "_csrf_token"=>$request->getPostParameter("_csrf_token","75cae42c7b46f41275a0b1ab14655028"));
    $this->form_email = new JobeetContactForm($form_values);
    afin de passer les données en tableau associatif au formulaire. mais ça ne change rien, le formulaire est tujours invalide et je ne récupère pas ces fichues valeurs.
    "n'imprimez ces messages que si nécessaire... Préservez notre planète"

  6. #6
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut
    Quelle différence fais-tu entre "l'objet du module" et "l'objet du formulaire" ? Pourquoi ne pas initialiser normalement ton formulaire ? Pourquoi faire un bind sur une autre instance du formulaire ? Pourquoi faire le bind avant l'initialisation ? Bref, je ne comprends rien à ce que tu fais et j'ai un peu l'impression que tu patouilles dans le code au hasard sans trop comprendre non plus.

    En tout cas, pour les traitements classiques, la procédure de base qui fonctionne sans problèmes est :
    1 - récupérer "l'objet du module" qui se trouve dans la route de la requête et qui est en principe le même que "l'objet du formulaire"
    2 - initialiser un formulaire avec cet objet
    3 - faire ses traitements (affichage, redirection, validation, etc).

    Exemple venant d'un formulaire autogénéré par symfony :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
      public function executeUpdate(sfWebRequest $request)
      {
        $this->category = $this->getRoute()->getObject(); // 1
        $this->form = $this->configuration->getForm($this->category); // 2
        $this->processForm($request, $this->form); // 3
     
        $this->setTemplate('edit');
      }

  7. #7
    Membre actif Avatar de elvan49
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2006
    Messages
    274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2006
    Messages : 274
    Points : 204
    Points
    204
    Par défaut
    Pourquoi ?
    Parce que cette procédure simlple que tu me décris, je l'ai essayée...
    Et qu'elle me renvoie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Fatal error: Call to undefined method sfRoute::getObject() in  /var/www/jobeet/apps/frontend/modules/info/actions/actions.class.php on  line 71
    Alors oui, du coup j'ai aussi l'impression de patouiller et de ne rien comprendre... Je vais rester sur cette voie plutôt que de m'éparpiller (ce en quoi tu as raison Herode) et essayer de comprendre pourquoi la méthode n'est pas trouvée.
    "n'imprimez ces messages que si nécessaire... Préservez notre planète"

  8. #8
    Membre actif Avatar de elvan49
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2006
    Messages
    274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2006
    Messages : 274
    Points : 204
    Points
    204
    Par défaut
    OK c'est un problème de route... je cherche. J'espère que ce n'est pas le fait d'avoir créer une autre class form pour le cnontact...
    "n'imprimez ces messages que si nécessaire... Préservez notre planète"

  9. #9
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut
    Selon la classe de route instanciée, la méthode getObject() existe ou pas. Si tu veux associer un objet à une route, il faut que ta route soit du type sfObjectRoute ou un de ses descendantes (sfDoctrineRoute, souvent). Et que le routing.yml soit paramétré en conséquence, of course.

  10. #10
    Membre actif Avatar de elvan49
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2006
    Messages
    274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2006
    Messages : 274
    Points : 204
    Points
    204
    Par défaut
    of course. J'étais bien parti dans ce sens.
    Voici mon routing.yml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    info_send:
      url:  /info/send
      class: sfDoctrineRoute
      options:  {model: JobeetInfo, type: object}
      param:  {module: info, action: send}
      requirements:
        sf_method: [post]
    mais désormais le problème est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Unknown record property / related component "_csrf_token" on "JobeetInfo"
    "n'imprimez ces messages que si nécessaire... Préservez notre planète"

  11. #11
    Membre actif Avatar de elvan49
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2006
    Messages
    274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2006
    Messages : 274
    Points : 204
    Points
    204
    Par défaut
    On avance, maintenant l'erreur est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    500 | Internal Server Error | sfValidatorErrorSchema
    _csrf_token [Required.]
    Est-ce que quelqu'un peut m'orienter sur l'interprétation à tirer de ça :
    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
    options:
         path_info_key: PATH_INFO
         path_info_array: SERVER
         http_port: null
         https_port: null
         default_format: null
         logging: '1'
         relative_url_root: null
         formats: { txt: text/plain, js: [application/javascript, application/x-javascript, text/javascript], css: text/css, json: [application/json, application/x-json], xml: [text/xml, application/xml, application/x-xml], rdf: application/rdf+xml, atom: application/atom+xml }
         no_script_name: false
    parameterHolder:
        action: send
        contact: { nom: '', email: '', type: Artisan, sujet: Renseignement, message: '', id: '2', _csrf_token: e664275f6b73fc9a98a456f78f272ff2 }
        id: '2'
        module: info
    attributeHolder:
        sf_route: 'sfDoctrineRoute Object()'
    Pourquoi mon formulaire indique une erreur de _csrf_token alors que dans la requête il a visiblement l'info ?
    "n'imprimez ces messages que si nécessaire... Préservez notre planète"

  12. #12
    Membre actif Avatar de elvan49
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2006
    Messages
    274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2006
    Messages : 274
    Points : 204
    Points
    204
    Par défaut Je dépose les armes
    Je renonce pour le moment.
    Je vais avancer dans le tuto, il faut arréter de mettre la charrue avant les boeufs !

    Mais, bon, snif !
    "n'imprimez ces messages que si nécessaire... Préservez notre planète"

Discussions similaires

  1. Réponses: 5
    Dernier message: 25/06/2012, 12h15
  2. [1.x] Conserver input file lors d'une validation de formulaire
    Par insane1 dans le forum Symfony
    Réponses: 2
    Dernier message: 23/08/2010, 12h49
  3. Help pour ouverture d'un popup lors de la validation d'un formulaire
    Par vrossi59 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 28/07/2006, 19h57
  4. Réponses: 3
    Dernier message: 16/05/2006, 09h23
  5. Ouvrir une popup lors de la validation d'un formulaire
    Par pod1978 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 23/11/2005, 15h47

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