Partage
  • Partager sur Facebook
  • Partager sur Twitter

[S3] Création d'une barre de recherche simple

Sujet résolu
    28 décembre 2016 à 10:55:21

    Bonjour,

    je cherche à créer une barre de recherche pour un projet permettant d'afficher des séries en fonction de leur nom ou de leur synopsis. Il faut donc une condition OR dans le WHERE que je n'arrive pas à reproduire... Le travail est tout simple en PHP, mais je bloque en Smfony 3. Autre conditions, il n'est pas nécessaire de taper tout les mots du nom ou synopsis de la série pour la trouver. Avec thrones n devrait trouver 'game of thrones' et avec chemistry on trouve 'breaking bad', mais la c'est aussi compliqué. Comment faire en sorte que ce soit reconnu comme ceci dans la requête ?

    Voila la fonction que j'ai faite jusqu'ici:

    /**
     * @Route("/search", name="search")
     * @Template()
     */
    public function searchAction()
    {
        $em = $this->get('doctrine')->getManager();
        $repo = $em->getRepository('AppBundle:TVShow');
        $data = 'A high school chemistry teacher diagnosed with inoperable lung cancer turns to manufacturing and selling methamphetamine in order to secure his family\'s future.';
        $shows = $repo->findBy(
            array(
                'name' => array('game of thrones', 'dexter', 'breaking bad'),
                'synopsis' => array($data)
            )
        );
        
        //erreur dans la reconnaissance de createQueryBuilder
        /*$shows = $this->createQueryBuilder('s')
            ->where('s.name LIKE ?', '%'.$data.'%')
            ->orWhere('s.synopsis LIKE ?', '%'.$data.'%')
        ;*/
    
        return $this->render('AppBundle:Default:shows.html.twig', array(
                'shows' => $shows
        ));
    }

    Merci de votre aide ;)

    -
    Edité par Radiax18 28 décembre 2016 à 11:05:35

    • Partager sur Facebook
    • Partager sur Twitter

    </radiax>

      28 décembre 2016 à 10:59:56

      Bonjour,

      orWhere() n'existe pas^^ :) il faut faire un OR dans ton SQL directement : 

      ->where('s.name LIKE ? OR s.synopsis LIKE ?', array('%'.$data.'%','%'.$data.'%'))


      et donc tu vas pas pouvoir passé par le findBy mais plutot par une requete que tu créer toi meme :) 

      -
      Edité par Hsuissia 28 décembre 2016 à 11:00:51

      • Partager sur Facebook
      • Partager sur Twitter
      Voir une araignée c'est rien ... Le pire c'est quand tu ne la vois plus !
        28 décembre 2016 à 11:08:13

        J'ai modifié la requête par ceci

        $shows = $this->createQueryBuilder('s')
            ->where('s.name LIKE :data OR s.synopsis LIKE :data')
            ->setParameter('data', $data)
        ;

        Malheureusement j'ai toujours une erreur lors de l'exécution de la recherche

        Attempted to call an undefined method named "createQueryBuilder" of class "AppBundle\Controller\DefaultController".



        • Partager sur Facebook
        • Partager sur Twitter

        </radiax>

          28 décembre 2016 à 11:22:16

          Si tu fais ceci dans ton controller, $this c'est ton controller, il n'as pas la méthode createQueryBuilder.

          C'est le repository qui s'est faire ça :) 

          Donc soit tu passe par une fonction de ton repository, soit tu l'utilise en appel dans ton controller :

          $repo = $this->getDoctrine()->getRepository("AppBundle:TVShow");
          $shows = $repo->createQueryBuilder('s')
              ->where('s.name LIKE :data OR s.synopsis LIKE :data')
              ->setParameter('data', $data)
          ;



          • Partager sur Facebook
          • Partager sur Twitter
          Voir une araignée c'est rien ... Le pire c'est quand tu ne la vois plus !
            28 décembre 2016 à 11:38:15

            Merci, je n'ai plus d'erreurs désormais. Malheureusement aucun résultat ne s'affiche...
            • Partager sur Facebook
            • Partager sur Twitter

            </radiax>

              28 décembre 2016 à 18:03:22

              Bha après regarde dans le profiler la requete qui est executé et regarde si tu as des resultats pour

              • Partager sur Facebook
              • Partager sur Twitter
              Voir une araignée c'est rien ... Le pire c'est quand tu ne la vois plus !
                15 janvier 2017 à 20:41:34

                comment faire pour récupérer le données d'un formulaire (formulaire sur la page twig et non par controller), séparer les mots pour chaque espace, et utiliser ces mots pour les comparer aux données présents dans la base ? Sachant que chaque mot peut n'être qu'une partie du résumé ou du titre d'une série.
                • Partager sur Facebook
                • Partager sur Twitter

                </radiax>

                  16 janvier 2017 à 10:10:30

                  Récupérer le formulaire twig, il faut : 

                  • Que l'action du formulaire envoi vers une action de ton controller:  <form action="{{path('nom_route'}}" method="POST">
                  • Dans le dis controller, tu regardes l'evenement du POST sur la variable request :
                    public function monAction(Request $request) {
                      if ($request->getMethod() == "POST")
                      
                  • Tu récupère les données avec ce même request, via les name de tes inputs dans ton twig :
                    // Soit tout récupérer dans un tableau : 
                    
                    $datas = $request->request->all(); // Array avec $datas['name_input'];
                    
                    // Soit une par une : 
                    $search = $request->request->get('name_input');
                    
                  • Ensuite tu parses cette variable par espace et tu l'envoi en requete :) 

                  Voila, c'est deja un bon début

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Voir une araignée c'est rien ... Le pire c'est quand tu ne la vois plus !
                    16 janvier 2017 à 11:47:26

                    J'y suis presque, ta solution est géniale !

                    /**
                     * @Route("/search", name="search")
                     * @Template()
                     */
                    public function searchAction(Request $request)
                    {
                        if ($request->getMethod() == "POST") {
                            $search = $request->request->get('search');
                    
                            $em = $this->getDoctrine()->getManager();
                            $query_shows = $em->createQueryBuilder();
                            $query_shows
                                ->select('s')
                                ->from('AppBundle:TVShow', 's')
                                ->where('s.name LIKE :data OR s.synopsis LIKE :data')
                                ->setParameter('data', '%'.$search.'%');
                    
                            $shows = $query_shows->getQuery()->getResult();
                        }
                    
                        return $this->render('AppBundle:Default:shows.html.twig', array(
                            'shows' => $shows
                        ));
                    }

                    Me reste plus qu'à empêcher d'afficher des résultats si je ne marque rien dans la barre, et à parser le code en ajoutant une petite boucle pour les 'LIKE' de la requête et ça devrait fonctionner. Quelque chose dans ce style:

                    $query_shows
                        ->select('s')
                        ->from('AppBundle:TVShow', 's');
                    
                    for(data in datas){
                        $query_shows
                            ->where('s.name LIKE :data OR s.synopsis LIKE :data')
                           ->setParameter('data', '%'.data.'%');
                    }

                    Encore une fois merci pour ton aide ;)


                    -
                    Edité par Radiax18 16 janvier 2017 à 21:11:35

                    • Partager sur Facebook
                    • Partager sur Twitter

                    </radiax>

                      18 janvier 2017 à 12:09:40

                      J'ai trouvé comment parser une chaîne sur les fichiers twig avec la méthode split mais c'est difficile de trouver pour le controller...

                      Quelqu'un sait comment faire ?

                      • Partager sur Facebook
                      • Partager sur Twitter

                      </radiax>

                        20 janvier 2017 à 10:58:11

                        Parser : explode() ou str_split() ou preg_split(), je te laisse regarder la doc dessus.
                        • Partager sur Facebook
                        • Partager sur Twitter
                        Voir une araignée c'est rien ... Le pire c'est quand tu ne la vois plus !
                          20 janvier 2017 à 12:20:25

                          str_split() est intéressante quoi que ne correspondant pas à mon besoin. Preg_split() et explode() semble pourvoir fonctionner et comme je n'ai pas besoin des options de preg_split-), je vais opter pour explode() que j'ai déjà eu l'occasion d'utiliser. Je ne pensais pas que ces fonctions PHP fonctionnaient dans le controller de Symfony 3.

                          Merci énormément pour ton aide, je pourrais tester ça ce soir en rentrant ;)

                          • Partager sur Facebook
                          • Partager sur Twitter

                          </radiax>

                            20 janvier 2017 à 13:30:56

                            Controller de symfony, c'est du PHP, tu peux utiliser toute fonction de PHP sans exception :) tu peux faire du mysqli() PDO(), DateTime, random() str_length... Après, utiliser du pdo alors qu'il y a doctrine c'est un peu bête mais pour le reste pas de limite, c'est du PHP Pur
                            • Partager sur Facebook
                            • Partager sur Twitter
                            Voir une araignée c'est rien ... Le pire c'est quand tu ne la vois plus !
                              21 janvier 2017 à 20:13:15

                              J'ai fait ça mais seul le denier résultat est pris en compte
                              Par exemple si je met "breaking throne", il renvoie "game of thrones"

                              $datas = explode(" ", $search);
                              
                                          $em = $this->getDoctrine()->getManager();
                                          $query_shows = $em->createQueryBuilder();
                                          $query_shows
                                              ->select('s')
                                              ->from('AppBundle:TVShow', 's');
                                          foreach ($datas as $data) {
                                              $query_shows
                                                  ->where('s.name LIKE :data OR s.synopsis LIKE :data')
                                                  ->setParameter('data', '%'.$data.'%');
                                          }



                              • Partager sur Facebook
                              • Partager sur Twitter

                              </radiax>

                              [S3] Création d'une barre de recherche simple

                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                              • Editeur
                              • Markdown