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 :

Récupérer les valeurs de 3 tables liées [4.x]


Sujet :

Symfony PHP

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Technicien GC
    Inscrit en
    Juillet 2017
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien GC
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Juillet 2017
    Messages : 23
    Points : 32
    Points
    32
    Par défaut Récupérer les valeurs de 3 tables liées
    Bonjour, voici mon problème actuel sur un projet de création d'un forum via Symfony 4.2.

    Comme vous pouvez le voir sur l'image ci-dessous, je réussi à afficher le nom de la category (Fantasy) et tous les topics dans la liste en dessous sous forme d'un tableau afin d'avoir le titre, le nom de l'auteur du topic, la différence de la date etc..
    Nom : 15554676763662_Capture.PNG
Affichages : 2198
Taille : 26,6 Ko

    Voici le code qui me permet cet affichage :
    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
    // App\Controller\CategoriesController.php
     
    public function show($id): Response
        {
            $category = $this->getDoctrine()
                ->getRepository(Categories::class)
                ->find($id);
     
            $topics = $category->getTopics();
     
            return $this->render('pages/showCategory.html.twig', [
                'category' => $category,
                'topics' => $topics,
            ]);
        }
    Code Twig : 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
    {% extends "base.html.twig" %}
     
    {% block title %}
        {{ category.catName }}
    {% endblock %} 
     
    {% block body %}
     
        <div class="section">
            <div class="sect-title">{{ category.catName }}</div>
            <div class="sect-child">
                <table>
                    <tr>
                        <td>Topics</td>
                        <td>Answers</td>
                        <td>Views</td>
                        <td>Last post</td>
                    </tr>
                    {% for topic in topics %}
                        <tr>
                            <td class="sect-child-title">
                                <a href="#">{{ topic.topicsubject }}</a>
                                <br>by
                                ,
                                {{ topic.topicdate|time_diff }}
                            </td>
                            <td>
                                nb
                                <!-- answers -->
                            </td>
                            <td>
                                nb
                                <!-- views -->
                            </td>
                            <td>
                                datetime
                                <br>
                                by user
                            </td>
                        </tr>
     
                        {% endfor %}
                </table>
            </div>
        </div>
     
    {% endblock %}

    Je n'arrive pas à récupérer l'username qui se trouve dans l'Entity User afin d'ensuite le rajouter dans mon fichier template Twig.
    J'ai essayé d'ajouter dans la fonction ci-dessus des morceaux de code qui pouvaient fonctionner (selon ma logique ) mais sans résultat.
    Celui-ci m'a donné le nom de tous les utilisateurs qui ont créé un topic (dans l'ordre logique le 1er = user1, le 2nd = user2 et le 3eme = user3 dans la bdd) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $user = $this->getDoctrine()
                ->getRepository(User::class)
                ->findAll();
     
            return $this->render('pages/showCategory.html.twig', [
                'category' => $category,
                'topics' => $topics,
                'user' => $user,
            ]);
    Code Twig : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <td class="sect-child-title">
                                <a href="#">{{ topic.topicsubject }}</a>
                                <br>by
                                {% for user in user %}
                                    by {{ user.username }}
                                {% endfor %}
                                ,
                                {{ topic.topicdate|time_diff }}
                            </td>
    Nom : 15554683873599_Capture2.PNG
Affichages : 2006
Taille : 19,3 Ko

    Vous vous en doutez il me retourne tous les noms via la boucle for..
    Pour aller plus loin, l'Entity Topics possede un topic_by lié en ManyToOne avec l'id de l'Entity User et topic_cat lié avec l'id de l'Entity Categories.

    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
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    //App\Entity\Topics.php
    <?php
     
    namespace App\Entity;
     
    use Doctrine\Common\Collections\ArrayCollection;
    use Doctrine\Common\Collections\Collection;
    use Doctrine\ORM\Mapping as ORM;
     
    /**
     * @ORM\Entity(repositoryClass="App\Repository\TopicsRepository")
     */
    class Topics
    {
        /**
         * @ORM\Id()
         * @ORM\GeneratedValue()
         * @ORM\Column(type="integer")
         */
        private $id;
     
        /**
         * @ORM\Column(type="string", length=255)
         */
        private $topic_subject;
     
        /**
         * @ORM\Column(type="datetime")
         */
        private $topic_date;
     
        /**
         * @ORM\ManyToOne(targetEntity="App\Entity\Categories", inversedBy="topics")
         * @ORM\JoinColumn(nullable=false)
         */
        private $topic_cat;
     
        /**
         * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="topics")
         * @ORM\JoinColumn(nullable=false)
         */
        private $topic_by;
     
        /**
         * @ORM\OneToMany(targetEntity="App\Entity\Replies", mappedBy="reply_topic")
         */
        private $replies;
     
        public function __construct()
        {
            $this->replies = new ArrayCollection();
        }
     
        public function getId(): ?int
        {
            return $this->id;
        }
     
        public function getTopicSubject(): ?string
        {
            return $this->topic_subject;
        }
     
        public function setTopicSubject(string $topic_subject): self
        {
            $this->topic_subject = $topic_subject;
     
            return $this;
        }
     
        public function getSlug(): string
        {
            return (new Slugify())->slugify($this->topic_subject);
        }
     
        public function getTopicDate(): ?\DateTimeInterface
        {
            return $this->topic_date;
        }
     
        public function setTopicDate(\DateTimeInterface $topic_date): self
        {
            $this->topic_date = $topic_date;
     
            return $this;
        }
     
        public function getTopicCat(): ?Categories
        {
            return $this->topic_cat;
        }
     
        public function setTopicCat(?Categories $topic_cat): self
        {
            $this->topic_cat = $topic_cat;
     
            return $this;
        }
     
        public function getTopicBy(): ?User
        {
            return $this->topic_by;
        }
     
        public function setTopicBy(?User $topic_by): self
        {
            $this->topic_by = $topic_by;
     
            return $this;
        }
     
        /**
         * @return Collection|Replies[]
         */
        public function getReplies(): Collection
        {
            return $this->replies;
        }
     
        public function addReply(Replies $reply): self
        {
            if (!$this->replies->contains($reply)) {
                $this->replies[] = $reply;
                $reply->setReplyTopic($this);
            }
     
            return $this;
        }
     
        public function removeReply(Replies $reply): self
        {
            if ($this->replies->contains($reply)) {
                $this->replies->removeElement($reply);
                // set the owning side to null (unless already changed)
                if ($reply->getReplyTopic() === $this) {
                    $reply->setReplyTopic(null);
                }
            }
     
            return $this;
        }
    }
    Merci !

  2. #2
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    351
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 351
    Points : 582
    Points
    582
    Par défaut
    Salut,

    Si tes entités sont liées entre elles via des relations, tu devrais probablement utiliser des fonctions "custom" dans le CategoryRepository (à la place des find() et findAll()) afin de faire les jointures entre tes entités. Ça donnerait quelque chose comme ça (dans l'idée, il y a certainement des choses à ajuster/corriger) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public function getAllTopicsByCategory(Category $category)
    {
        $qb = $this->createQueryBuilder('t')
                ->innerJoin('t.topic_cat', 'c');
                ->innerJoin('t.topic_by', 'u');
                ->andWhere('t.topic_cat = :category')
                ->setParameter('category', $category);
        return $qb
                ->orderBy('t.createdAt', 'DESC')
                ->getQuery()
                ->getResult();
    }

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Technicien GC
    Inscrit en
    Juillet 2017
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien GC
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Juillet 2017
    Messages : 23
    Points : 32
    Points
    32
    Par défaut
    Merci pour ta réponse.

    Mais j'ai déjà essayer de faire une fonction dans CategoriesRepository et TopicsRepository, mais je n'arrive toujours pas à afficher ensuite dans mon template l'username de l'auteur du topic.

    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
     
    //App\Repository\CategoriesRepository
    public function getAllTopicsByCategory($id)
        {
            $con = $this->getEntityManager()->getConnection();
     
            $sql = '
                SELECT * FROM topics t
                JOIN categories c ON t.topic_cat_id = c.id
                JOIN user u ON t.topic_by_id = u.id
                WHERE c.id = :id
                ORDER BY t.topic_date DESC      
            ';
     
            $stmt = $con->prepare($sql);
            $stmt->execute(['id' => $id]);
     
            return $stmt->fetchAll();
        }
    J'ai transformé ton code en version SQL (car je comprends mieux ce qu'il se passe) mais ça me donne le meme résultat.

    Le nom de la categorie s'affiche grace à l'id passé dans l'url, les topics liés à cette catégorie s'affiche bien mais je ne sais pas comment faire pour afficher l'username pour chaque topic concerné..

  4. #4
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    351
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 351
    Points : 582
    Points
    582
    Par défaut
    Salut,

    Je ne suis pas expert en SQL mais ton "SELECT * from topics t" ne retourne-t-il pas seulement les champs de la tableau topics ?
    Si tu veux en plus récupérer des champs de la table user, je pense qu'il faudrait remplacer le * par les colonnes qui t'intéressent en utilisant t.nomDeLaColonne et u.nomDeLaColonne.

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Technicien GC
    Inscrit en
    Juillet 2017
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien GC
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Juillet 2017
    Messages : 23
    Points : 32
    Points
    32
    Par défaut
    J'ai modifié le Repository comme ci-dessous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $sql = '
                SELECT t.*, u.username, c.cat_name 
                FROM topics t
                JOIN categories c ON t.topic_cat_id = c.id
                JOIN user u ON t.topic_by_id = u.id
                WHERE c.id = :id
                ORDER BY t.topic_date DESC      
            ';
    Mais maintenant aurais-tu une idée de comment dévelloper ça dans le controller ?
    Je pense que mon problème viens de là.

  6. #6
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    351
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 351
    Points : 582
    Points
    582
    Par défaut
    Si j'étais toi j'essayerai de "traduire" cette requête SQL sous la forme du QueryBuilder (cf. ma première réponse) dans une fonction custom du Repository.
    Ensuite dans ton contrôleur, tu appelles cette fonction comme tu appelais findAll/findBy et tu transmets la variable contenant les résultats à Twig lors de l'appel à la méthode render().

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Technicien GC
    Inscrit en
    Juillet 2017
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien GC
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Juillet 2017
    Messages : 23
    Points : 32
    Points
    32
    Par défaut
    Voici mes derniers changements récents :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //App\Repository\TopicsRepository.php
    public function findAllTopicsByCategory(Categories $category)
        {
            return $this->createQueryBuilder('t')
                ->andWhere('t.topic_cat = :category')
                ->setParameter('category', $category)
                ->innerJoin('t.topic_cat', 'c')
                ->addSelect('c.cat_name')
                ->getQuery()
                ->getResult()
            ;
        }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    //App\Repository\UserRepository.php
    public function findAllUsernameByTopics()
        {
            return $this->createQueryBuilder('u')
                ->innerJoin('u.topics', 't')
                ->addSelect('t')
                ->getQuery()
                ->getResult();
        }
    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
    //App\Controller\CategoriesController.php
    public function show(Categories $category, string $slug): Response
        {
            if ($category->getSlug() !== $slug) {
                return $this->redirectToRoute('category_show', [
                    'id' => $category->getId(),
                    'slug' => $category->getSlug(),
                ], 301);
            }
     
            $topics = $this->getDoctrine()
                ->getRepository(Topics::class)
                ->findAllTopicsByCategory($category);
     
            // echo '<pre>';
            // var_dump($topics);
            // echo '</pre>';
     
            $userData = $this->getDoctrine()
                ->getRepository(User::class)
                ->findAllUsernameByTopics();
     
            foreach ($userData as $user) {
                $user->getTopics();
            }
     
            return $this->render('pages/showCategory.html.twig', [
                'category' => $category,
                'topics' => $topics,
                'user' => $user,
            ]);
        }
    Code Twig : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //showCategory.html.twig
    //..
    {% for topic in category.topics %}
                        <tr>
                            <td class="sect-child-title">
                                <a href="#">{{ topic.topicsubject }}</a>
                                <br>
                                by {% for user in user %}
                                    {{ user.username }}
                                {% endfor %}
                                ,
                                {{ topic.topicdate|time_diff }}
                            </td>
    //..

    Donc avec les codes ci-dessus, je n'arrive toujours pas à avoir le nom de l'User (username) correspondant au topic.

    J'ai essayé de passer sous une seule fonction dans TopicsRepository avec ce code mais je n'ai pas réussi à récupérer les valeurs.. :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //App\Repository\TopicsRepository.php
    public function findAllTopicsByCategory(Categories $category)
        {
            return $this->createQueryBuilder('t')
                ->andWhere('t.topic_cat = :category')
                ->setParameter('category', $category)
                ->innerJoin('t.topic_cat', 'c')
                ->innerJoin('t.topic_by', 'u')
                ->addSelect('c.cat_name, u.username')
                ->getQuery()
                ->getResult()
            ;
        }

  8. #8
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    351
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 351
    Points : 582
    Points
    582
    Par défaut
    Salut,

    Si les entités Category, User et Topic sont liées entre elles, ça me semble bizarre de les récupérer et de les passer à Twig distinctement car ensuite tu vas être obligé de parcourir toutes les listes pour définir quel objet est lié à quel autre. Il me semble plus logique de récupérer en une seule fois toutes les infos nécessaires et ensuite de boucler sur ce gros objet qui contiendrait la liste des topics pour la catégorie courante, et pour chaque topic l'utilisateur l'ayant créé.

    Essaye de déboguer en utilisant la fonction dump de Twig pour mieux visualiser ce que tu récupères en appelant findAllTopicsByCategory, et selon ce qu'il manque ajuste ton code dans le QueryBuilder. Bon courage !

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Technicien GC
    Inscrit en
    Juillet 2017
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien GC
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Juillet 2017
    Messages : 23
    Points : 32
    Points
    32
    Par défaut
    Salut !
    Merci de ton temps et de répondre à ce sujet

    J'ai éffectué un dump ( dump($topics) ) dans le controller à la suite de l'appel ->findAllTopicsByCategory() qui fais lui appel au dernier code Repository transmis dans mon message précédent avec les 2 innerJoin compris.

    Résultat, il y a bien ce que j'attends :
    Nom : Capture.PNG
Affichages : 1952
Taille : 14,4 Ko

    Maintenant je ne sais pas appeler la ligne username dans mon topics, saurais-tu m'aider ?
    Merci encore.

    EDIT :

    Merci pour ton aide, j'ai donc trouvé la solution, les codes Repository et Controller sont bons, comme je le pensais c'était bien dans mon Template que le problème perssistait, voici ce que j'ai donc écris :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    by {{ topic.topicby.username }}
    SUJET RESOLU

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [2.x] Récupérer la valeur d'une table liée
    Par vanderr dans le forum Symfony
    Réponses: 2
    Dernier message: 24/04/2012, 15h42
  2. Récupérer les valeurs d'un table
    Par lordatef dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 18/10/2011, 13h37
  3. Récupérer les données d'une table liée
    Par ludojojo dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 13/06/2010, 22h24
  4. Réponses: 5
    Dernier message: 27/04/2010, 14h55
  5. [MySQL] Récupérer les valeurs d'une table dans un tableau
    Par bachboucha dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 15/06/2009, 09h50

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