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 :

handleRequest() fausse les données envoyées


Sujet :

Symfony PHP

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 34
    Points : 18
    Points
    18
    Par défaut handleRequest() fausse les données envoyées
    Bonjour tout le monde,

    Je rencontre un problème très étrange dans un controlleur au moment de mon handleRequest($this->getRequest()).
    Pour essayer de détailler clairement et simplement :

    Un controlleur dans lequelle je construis deux forms, je handleRequest() pour mes deux formulaires, mais si le premier a été validé, alors les données récupérées sont bizarres.

    Petit exemple de scénario :

    1) Je clique sur un lien me dirigeant vers la page où mes deux formulaires sont affichés
    2) Aucune données ne sont encore affichées car rien en BDD. Mes formulaires s'affichent donc sans datas.
    3) Jajoute des données et clique pour sauvegarder, cela me redirige vers la page précédente. (en BDD les lignes sont créées)
    4) Je recommence l'étape 1. (en BDD les lignes sont toujours là)
    5) Le formulaire contient bien les données que je viens de renseigner.(en BDD les lignes sont toujours là)
    6) Je reclique sur le bouton pour sauvegarder et revenir à la page précédente.(en BDD ldeux lignes ont été supprimées)
    7) Je recommencde l'étape 1.
    8) Le formulaire s'affiche mais une seule ligne est affichée.

    A force de var_dump(), il semble que lorsque le handleRequest() s'execute, il "oublie" deux lignes de mon formulaire...

    Je tourne en rond depuis pas mal de temps sans trouver la moindre piste.

    Je vous fournis mon controlleur et mon twig. (dites moi si vous avez besoin d'autre chose :-) )

    Controlleur :
    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
     
    <?php
     
    namespace ATS\CapacityPlanBundle\Controller;
     
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Symfony\Component\HttpFoundation\Request;
    use ATS\CapacityPlanBundle\Form\Type\ResourcePickListContainerType;
    use ATS\CapacityPlanBundle\Form\Type\ServicesApplicationResourcesManagementType;
    use ATS\CapacityPlanBundle\Entity\ServicesApplication;
     
     
    class ServicesApplicationController extends Controller
    {   
        /**
         * 
         * @return render
         */
        public function viewAction($id)
        {
            $em = $this->getDoctrine()->getManager();
            $rep = $em->getRepository('ATSCapacityPlanBundle:ServicesApplication');
            $serviceApplication = $rep->find($id);
            $applicationId = $serviceApplication->getApplication()->getId();
            $projectId = $serviceApplication->getApplication()->getProject()->getId();
            $route = 'ats_capacity_plan_applicationManagement';
     
            // Get forms to display Config
            $formServAppliToDisplay = $this->createForm(new ServicesApplicationResourcesManagementType($em), $serviceApplication);
            $formResourcesPickList = $this->createForm(new ResourcePickListContainerType($em));
            // Get Original Resources --> Will be used to know if some if its has been deleted
            $originalResources = new \Doctrine\Common\Collections\ArrayCollection();
            foreach ($formServAppliToDisplay->getData()->getResources() as $resource) {
                $originalResources[]=$resource;
            }
     
            //Bind Datas 
            $formServAppliToDisplay->handleRequest($this->getRequest());
            $formResourcesPickList->handleRequest($this->getRequest());
            if($formServAppliToDisplay->isValid())// User has clicked on submit and datas are correct
            {  
                $resourcesAdded = new \Doctrine\Common\Collections\ArrayCollection();
                if (!is_null($formResourcesPickList->getData())) {
                    // We check new resources added through the resource picklist form
                    // We add it to the ServiceApplication if the picklist value is not null
                    foreach ($formResourcesPickList->getData() as $value) {
                        foreach ($value as $resource) {//loop on all services picklist
                            if (!is_null($resource['resources'])) {
                                $resourcesAdded[] = $resource['resources'];
                                $resource['resources']->addServicesApplication($formServAppliToDisplay->getData());
                                $formServAppliToDisplay->getData()->addResource($resource['resources']);
                            }
                        }
                    }
                }
     
     
                /*
                 * CHECK POURQUOI ON RENTRE DANS LA BOUCLE CI DESSOUS !!!!!!!
                 */
                foreach ($originalResources as $res) {
                    // We checked if the ServiceApplicationResources in db is still in the ServiceApplication sended through the form
                    // If no --> it has been deleted by the user
                    if (!$formServAppliToDisplay->getData()->getResources()->contains($res) && !$resourcesAdded->contains($res)){
                        $res->removeServicesApplication($serviceApplication);
                        $serviceApplication->removeResource($res);
                    }
                }
                foreach ($formServAppliToDisplay->getData()->getResources() as $value) {
                        $value->addServicesApplication($formServAppliToDisplay->getData());
                }
                try {
                    $this->updateServiceApplication($formServAppliToDisplay->getData()); // Persist infos in DB
                    //return $this->redirect($this->generateUrl($route, array('id'=>$applicationId)));
                } catch (\Exception $exc) {
                    print('An error happened inserting datas in Database ! </br></br>'.$exc->getMessage()
                            .'</br></br>Please come back to the last page and correct datas you tried to send.');
                    exit;
                }
     
     
     
            }
     
     
            $args = array(
                'projectId' => $projectId,
                'formResourcesPicklist' => $formResourcesPickList->createView(),
                'formServiceApplication' => $formServAppliToDisplay->createView(),
                'ServiceApplication' => $formServAppliToDisplay->getData(),
            );
            return $this->render('ATSCapacityPlanBundle:ServiceApplication:ServicesApplicationManagement.html.twig', $args);
        }
     
        /**
         * Function to update a serviceApplication in DB
         * @param type $project
         * @param type $id
         */
        public function updateServiceApplication($serviceApplication)
        {
            $em = $this->getDoctrine()->getManager();
            $em->persist($serviceApplication);
            $em->flush(); // Save the Project with new datas in DB
        }
    }
    TWIG :
    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
     
    {% extends "::GeneralTemplate.html.twig" %} 
     
     
    {% block menu %}
        <div id="menubar">
           <ul id="menu">
              <!-- put class="selected" in the li tag for the selected page - to highlight which page you're on -->
              <li class="selected"><a href={{ path('ats_capacity_plan_configurationview', { 'id' : projectId }) }}>Configuration</a></li>
              <li><a href={{ path('ats_capacity_plan_availability', { 'id' : projectId }) }}>Availability</a></li>
              <li><a href={{ path('ats_capacity_plan_plan', { 'id' : projectId }) }}>Plan</a></li>
              <li><a href={{ path('ats_capacity_plan_demands') }}>Demands</a></li>
              <li><a href={{ path('ats_capacity_plan_capacitytable') }}>Capacity Table</a></li>
              <li><a href={{ path('ats_capacity_plan_balance') }}>Balance</a></li>
           </ul>
        </div>
    {% endblock %}
     
     
     
    {% block body %}
    {# On charge la bibliothèque jQuery. Ici, je la prends depuis le CDN google
    mais si vous l'avez en local, changez simplement l'adresse. #}
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.10/css/jquery.dataTables.css">
    <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js"></script>
    <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/fixedcolumns/3.2.0/js/dataTables.fixedColumns.min.js"></script>
     
     
    {{ form_start(formServiceApplication) }}
     
    <div id="menu"><h2>List of Resources for {{ ServiceApplication.getApplication.getText }} - {{ ServiceApplication.getServiceName }}</h2><hr></div>
     
    <table id="resources">
        {% if formServiceApplication.resources|length > 0 %}
            {% for resource in formServiceApplication.resources %}
                {{ form_start(resource) }}
                <tr id="resource">
                    <td>{{ form_widget(resource.firstName) }} {{ form_widget(resource.lastName) }}</td>
                </tr>
                {{ form_rest(resource) }}
                {{ form_end(resource) }}
            {% endfor %}
        {% endif %}
        {% if formServiceApplication.resources|length <= 0 %}
            <tr id="resource">
                <td>No resource saved yet</td>
            </tr>
        {% endif %}
        <tr id="buttons"><td><button id="addResource" class="btn">Add Resource</button></td><td>{{ form_widget(formServiceApplication.save) }}</td></tr>   
     
     
     
    </table>
    {{ form_rest(formServiceApplication) }}   
    {{ form_end(formServiceApplication) }}
     
    {{ form_start(formResourcesPicklist) }}
    {{ form_end(formResourcesPicklist) }}
     
     
     
     
    {# Partie JavaScript : #}
     
     
    <script type="text/javascript">
      var $index = 0;
      var $count = 0;
      $(document).ready(function() {
        //var $applicationId = $(".applicationId").data("applicationid");
     
        // On récupère la table ayant pour id : assumptions
        var $containerResources = $('table#resources');
        // On ajoute un lien de suppression à la fin de chaque ligne de notre tableau d'application services
        $containerResources.find('tr#resource').each(function() {
            addDeleteLink($(this), "Please confirm deletion of that resource");
        });
     
     
        /*---------------------------------------------------------------------------------------------------*/ 
        /*------------------------------------ EXISTING RESOURCE PICKLIST  ----------------------------------*/   
        /*---------------------------------------------------------------------------------------------------*/    
     
            $('button#addResource').on('click', function(e) {
                // Get the html for adding a resource picklist
                var $newResource = $('div#ProjectResources_resources').data('prototype');
                var $newForm = '<tr><td>' + $newResource.replace(/__name__/g, 'resource' + $index) + '</td></tr>';
                var $formResource = $($newForm);
                $index++;
                addDeleteLink($formResource, "Please confirm deletion of that resource");
                // prevent the link from creating a "#" on the URL
                e.preventDefault();
                // Add a resource picklist
                $('tr#resource:first').before($formResource);
            }); 
     
        /*---------------------------------------------------------------------------------------------------*/ 
        /*-----------------------------------------  DELETION  ----------------------------------------------*/   
        /*---------------------------------------------------------------------------------------------------*/     
     
        // La fonction qui ajoute un lien de suppression à la fin d'un formulaire
        function addDeleteLink($form, $message) {
            // Construction de l'objet HTML de Suppression de formulaire
            var $removeFormA = $('<a href="#" class="btn">X</a>');
            // On l'ajoute à la fin de l'objet HTML passé à la fonction
            $form.append($removeFormA);
     
            // A chaque clic sur le bouton on enlève le formulaire associé au lien
            $removeFormA.on('click', function(e) {
                // prevent the link from creating a "#" on the URL
                e.preventDefault();
                if(confirm($message)){
                    $form.remove();// suppression du <tr><td> correspondant
                }
                // On vérifie que l'on n'a pas supprimé pas la dernière resource, auquel cas on affiche "No resource saved yet"
                $containerResources.find('tr#resource').each(function() {
                    $count++;
                });
                if($count<1){
                    $('tr#buttons').before('<tr id="resource"><td>No resource saved yet</td></tr>');
                }
                $count=0;
            });
     
        } 
     
    } );
    </script>
    {% endblock %}
    Merci d'avance de votre aide !

    Emmanuel

  2. #2
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    je n'ai pas tout analysé parceque il me faudrai du temps pour ça.

    mais en lisant rapidement, je vois que tu gères 2 formulaires, comment sait il que tu as submitter le form 1 ou 2 ?
    dans le controlleur il faut tester quel formulaire a été submitter et ensuite faire le handlerequest.


    sinon autre chose, as tu testé en faisant un dump au début du controller des paramètres/valeurs que contient la requete ?

  3. #3
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 34
    Points : 18
    Points
    18
    Par défaut
    Hello Dukoïd,

    Pour détailler un peu le contexte :

    - j'affiche effectivement deux formulaires, un qui affiche les ressources liées à un "ServiceApplication", et un autre formulaire qui est en fait un conteneur de formulaires Ressources. Ce dernier formulaire me permet l'ajout de ressources à mon "ServiceApplication" à l'aide de combobox (choiceList). Donc en fait je n'ai un bouton que pour valider le premier formulaire, mais les deux formulaires peuvent avoir des valeurs qui ont changées... Le premier car j'ai pu supprimer des ressources du formulaire présenté, et le deuxième car j'ai pu vouloir ajouter des ressources ...

    C'est donc pour cette raison que je dois récupérer le contexte des deux formulaires.

    Je n'ai pas encore dumpé les valeurs de ma requête, en quoi ça peut m'être utile ?

    Merci pour ton aide,

    Emmanuel

  4. #4
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    sache qu'en HTML, on ne peut pas techniquement submitter 2 formulaires à la fois. (aucun rapport avec Symfony)

    tu peux faire un seul formulaire des 2 formulaires ou tu peux utiliser ajax pour submiter le 1er et 2eme form

  5. #5
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 34
    Points : 18
    Points
    18
    Par défaut
    C'est qu'en fait j'ai déjà fait la même chose dansn un précédent controlleur pour lequel ça fonctionne très bien. J'ajoute des picklist dynamiquement à l'aide d'un formulaire, je peux supprimer des ressources existantes à l'aide de l'autre formulaire, et au moment de la soumission je récupère les bonnes valeurs dans les deux formulaires.

    En fait je ne comprends pas pourquoi deux resources sur trois disparaissent des données au bind des datas du handleRequest() ?

  6. #6
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 34
    Points : 18
    Points
    18
    Par défaut
    J'ai testé en commentant le handleRequest() de la deuxieme form et ça ne change rien. C'ets bien le handle Request qui ne récupère pas les bonnes datas.
    Personne n'a d'idée sur ce problème ?

  7. #7
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 34
    Points : 18
    Points
    18
    Par défaut
    Et pour info mon handle request fonctionne un peu ... :-/
    Il récupère un enregistrement à chaque fois.
    Si dans mon formulaire j'ai trois enregistrement, après le handle request il n'y en a plus qu'un, toujours le premier. Quid des suivants ?

  8. #8
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    comme je l'ai indiqué plus haut, j'aimerais bien connaitre les paramètres de la requête au début de l'action histoire d’écarter tout problème en amont.
    que tu confirmes que dans la requêtes il y a bien les 3 objets par ex, ça peut être un bon indice déjà de savoir ça , non ?

    ensuite si il t'en prends qu'un, il y a notion de plusieurs donc de collection et donc dans ton entité y'a t'il une collection pour en recevoir plusieurs ?

  9. #9
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 34
    Points : 18
    Points
    18
    Par défaut
    Bon du coup j'ai changé quelque détails dans mon controlleur et ma façon de procéder, comme suggéré par Nico_F.

    A savoir, j'ai créé une nouvelle classe qui ne me sert que pourla construcution de mon formulaire, afin de n'avoir qu'un formulaire à valider. Mon nouveau formulaire contient donc deux collections, une pour les resources liés, une qui contiendra les sous formulaires pour ajouter une resource.

    Même problème avant le getRequest() mon formulaire contient bien plusieurs resources, après celui-ci il n'en reste qu'une.

    Quels paramètres de la requète veux-tu que je récupère et comment ?

    Nico, cela peut-il venir de mon mapping ORM ?? de l'ordre dont j'ai géré le many to many de mes relations ? (le owner ne serait pas le bon ??...)

    Merci,

  10. #10
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    Hello,

    Je n'ai plus ton model en tête mais en gros ce qui serait intéressant serait de voir le contenu de ton POST avant le handleRequest().
    Un dump($request->request->all()); permettrait déjà de voir la structure et la data que tu soumets.

  11. #11
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut

Discussions similaires

  1. Récupérer les données envoyées par une tablette graphique
    Par greg08 dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 02/06/2010, 06h04
  2. Réponses: 1
    Dernier message: 07/07/2008, 12h47
  3. Contrôler les données envoyées
    Par jo the boss dans le forum Réseau
    Réponses: 1
    Dernier message: 23/05/2008, 15h24
  4. TWebBrowser : Intercepter les données envoyées
    Par Bruno13 dans le forum Delphi
    Réponses: 3
    Dernier message: 02/06/2006, 19h35

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