Bonjour,

J'aurais vraiment besoin d'un coup de pouce parce que je suis coincée depuis un moment maintenant..

Grâce à ajax j'envoies mes données que mon controller reçoit bien. Je fais un for pour que toutes les données s'affichent correctement.

Après avoir fait ça, je tente desespérment d'insérer en base de données mais je n'y arrive pas. J'essaie en premier lieu de savoir si la table est vide avec un select et ensuite de faire un if (si la bdd est vide alors insérer en base sinon mettre à jour les données).

Je suspecte de mettre le query builder dans le repository de l'entité.

Merci d'avance pour votre aide !

ajax :

$(document).ready(function() {
    saveGrid = function () {
        delete serializedFull;
        serializedData = grid.save();
        serializedData = JSON.stringify(serializedData,null, ' ')
        console.log(serializedData);
        $.ajax({
           type:"post",
           url:"index.php/recherche/ajax",
           data: {"data" : serializedData},
            success: function(save){
               alert(save);
            }
        });
  #[Route('/recherche/ajax', name: '_recherche_ajax', methods: "POST")]
    public function saveGrid(Request $request): Response
    {
        $check = "sa";
        $var = json_decode($request->get("data"), true);

        foreach ($var as $key) {

            //récupère les valeurs et les assignent a des variables
            //chaque boucle correspond a une grid
            $valueX = $key["x"];
            $valueY = $key["y"];
            $valueW = $key["w"];
            $valueID = $key["id"];
            $valueH = $key["h"];

            //vérifie si le grid existais déjà
            //requete en BDD

//            $em = $this->container->get("doctrine.orm.default_entity_manager");
//
//            $em = $this->getDoctrine()->getManager();
//// Où aussi
//            $em = $this->get('doctrine.orm.entity_manager');
//
//            $entityManager = $this->getDoctrine()->getManager();

//            $userRepo = $entityManager->getRepository(GFEnv::class);
//
//            $queryBuilder = $entityManager->createQueryBuilder();

//            $queryBuilder->select('alias')
//                ->from(GFEnv::class, 'alias')
//                ->where('alias.id = :id')
//                ->setParameter('id', $valueID);

//            $query = $queryBuilder->getQuery()->getOneOrNullResult();
//           if($query == null){
//               return new Response("la base est vise");
//           } else{
//               return new Response ("la base a une entrée");
//           }
//            var_dump($query);

            //if

                //si oui update
            //else

                //si non insert
        }

ou avec repository :

  /**
     * @throws ORMException
     * @throws OptimisticLockException
     */
    public function select($value)
    {
        $entityManager = $this->getDoctrine()->getManager();
        $queryBuilder = $entityManager->createQueryBuilder();

        $queryBuilder->select('alias')
            ->from(GFEnv::class, 'alias')
            ->where('alias.id = :id')
            ->setParameter('id', $value);

        return $queryBuilder->getResult();

//        $query = $queryBuilder->getQuery()->getOneOrNullResult();
//        if ($query == null) {
//            return new Response("la base est vise");
//        } else {
//            return new Response ("la base a une entrée");
//        }
    }

Je ne connais pas la best practice

7 réponses


gillesr
Réponse acceptée

Tu n'as pas besoin du getDoctrine.
Pour utiliser l'EntityManager, il faut l'injecter comme je t'ai montré plus haut et l'utiliser directement en faisant $this->em->find()
donc il faut supprimer la méthode que tu as ajoutée dans le repository.

Dans ton controleur, il y 2 cas :
cas n1 : ton entité existe => tu la récupères avec un find
cas n2: ton entité n'existe pas => tu la crées

c'est ce que j'ai fait avec :


 $gf = ($id) ? $this->em->find(GFEnv::class, $id) : new GFEnv();

Qui est une écriture raccourcie pour :


 if($id) {
     $gf = $this->em->find(GFEnv::class, $id);
 } else {
     $gf = new GFEnv();
 }

La façon dont je récupère l'id ici est un exemple, il faut surement l'adapter à la façon dont tu passes les arguments à ton controleur.

A ce stade, tu as une entité $gf qu'il faut mettre à jour avec les données que tu as récupérées avec ton $request->get("data") avant de la persister en base.

Bonjour,

Tu n'as pas besoin d'ajouter une méthode dans le repository pour récupérer un enregistrement.
Le principe est relativement simple :

  • si ton entité n'existe pas, tu la crées
  • sinon tu la mets à jour

Pour faire ça, tu injecte l'EntityManagerInterface de doctrine dans le constructeur (de ton controleur)


public function __construct(private EntityManagerInterface $em){}

Ensuite, dans ta méthode saveGrid, tu l'utilises pour récupérer l'entité dont l'id est passé en paramètre (si il existe) :


#[Route('/recherche/ajax', name: '_recherche_ajax', methods: "POST")]
    public function saveGrid(Request $request): Response
    {
        // s'il y a un id passé en paramètre on récupère l'enregistrement, sinon on crée une nouvelle entité
        $id = $request->get('id);
        $gf = ($id) ? $this->em->find(GFEnv::class, $id) : new GFEnv();

        // tes traitements
        ...

        $this->em->persist($gf);
        $this->em->flush();
        return ...
    }

Ici, j'ai injhecté l'EntityManagerInterface dans le constructeur, mais tu peux l'injecter directement dans la méthode si tu ne l'utilise pas ailleurs.

Mipmo
Auteur

Merci beaucoup pour ta réponse Gillesr,

J'ai ajouté les lignes que tu as proposé et malheuresement j'ai une erreur 500 post dans ma console.

Je vais essayer de regarder plus en détails.

Mipmo
Auteur

Du coup je n'y arrive toujours pas, j'ai tenté plusieurs choses mais la finalité reste la même : erreur 500.

J'ai essayé de créer $entityManager = $this->getDoctrine()->getManager(); Mais jai une erreur qui me dit "Method 'getDoctrine' not found in DefautController".

En commantant plusieurs lignes du code je remarque également un problème au niveau du persist... J'arrive à court d'idées. Si vous avez des suggestions ou autre n'hésitez pas ça m'aiderait beaucoup ! Merci d'avance !

Et que dit l'erreur 500 ? quel est le message d'erreur ?

Mipmo
Auteur

J'ai cette erreur dans la console :

POST http://Adresse_IP/intranet/public/index.php/recherche/ajax 500 (Internal Server Error)
send @ jquery-3.4.1.min.js:2
ajax @ jquery-3.4.1.min.js:2
saveGrid @ main.js:65
onclick @ VM7787 index.php:65

Après, au niveau du getDoctrine, même avec les use il me dit que la méthode n'est pas définie, une idée ? :/

Mipmo
Auteur

Bonjour,

Merci Gillesr, du coup j'ai réussi à bien faire la requête, pour le moment je suis en train de gérer l'update et le insert, merci beaucoup en tout cas ^^