Les relations entre entités avec Doctrine2
|
Mise à jour : 02/05/2012
20 752 visites depuis 7 jours,
dont 818 sur ce chapitre
classé 17/786
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?php /** * @ORM\Entity */ class Client { /** * @ORM\OneToOne(targetEntity="Namespace\Bundle\Entity\Adresse") */ private $adresse; // ... } /** * @ORM\Entity */ class Adresse { // Nul besoin de rajouter une propriété ici. // ... } |
1 | @ORM\OneToOne(targetEntity="Namespace\Bundle\Entity\Adresse", cascade={"remove", "persist"}) |
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 | <?php // Namespace\Bundle\Entity\Client /** * @ORM\Entity */ class Client { /** * @ORM\OneToOne(targetEntity="Namespace\Bundle\Entity\Adresse") */ private $adresse; // On définit le getter et le setter associé. public function getAdresse() { return $this->adresse; } // Ici, on force le type de l'argument à être une instance de notre entité Adresse. public function setAdresse(\Namespace\Bundle\Entity\Adresse $adresse) { $this->adresse = $adresse; } } |
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 | <?php // Dans le contrôleur, pour ajouter un nouveau client et son adresse : public function creerClientAction() { $client = new Client; // $client->setNom() etc $adresse = new Adresse; // $adresse->setRue() etc // On lie l'adresse au client $client->setAdresse($adresse); // On récupère l'EntityManager $em = $this->getDoctrine()->getEntityManager(); // On persiste les deux nouvelles entités $em->persist($client); $em->persist($adresse); // On déclenche l'enregistrement $em->flush(); return new Response('OK'); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <?php // Dans le contrôleur toujours, mais pour modifier l'adresse déjà existante d'un client déjà existant : public function modifierAdresseAction($id_client) { $em = $this->getDoctrine()->getEntityManager(); // On récupère le client. $client = $em->getRepository('SdzBlogBundle:Client')->find($id_client); // On modifie le numéro de l'adresse. $client->getAdresse()->setNumero(35); // On n'a pas besoin de persister notre client (si vous le faites aucune erreur n'est déclenchée, Doctrine l'ignore). // Rappelez-vous il l'est automatiquement car on l'a récupéré depuis Doctrine. // Pas non plus besoin de persister l'adresse ici, car elle est également récupérée par Doctrine. // On déclenche la modification. $em->flush(); return new Response('OK'); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?php /** * @ORM\Entity */ class Client { // Nul besoin de rajouter de propriété, ici. // ... } /** * @ORM\Entity */ class Adresse { /** * @ORM\ManyToOne(targetEntity="Namespace\Bundle\Entity\Client") */ private $client; // ... } |
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 | <?php // Dans le fichier de l'entité. /** * @ORM\Entity */ class Adresse { /** * @ORM\ManyToOne(targetEntity="Namespace\Bundle\Entity\Client") */ private $client; // On définit le getter et le setter associé. public function getClient() { return $this->client; } // Ici, on force le type de l'argument à être une instance de notre entité Client. public function setClient(\Namespace\Bundle\Entity\Client $client) { $this->client = $client; } } |
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 | <?php // Dans le contrôleur, pour ajouter un nouveau client et ses adresses : public function creerClientAction() { $client = new Client; // $client->setNom() etc $adresse1 = new Adresse; // $adresse1->setRue() etc $adresse2 = new Adresse; // $adresse2->setRue() etc // On lie les adresses au client. $adresse1->setClient($client); $adresse2->setClient($client); // On récupère l'EntityManager. $em = $this->getDoctrine()->getEntityManager(); // On persiste nos trois entités $em->persist($client); $em->persist($adresse1); $em->persist($adresse2); // On déclenche l'enregistrement. $em->flush(); return new Response('OK'); } |
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 | <?php // Dans le contrôleur toujours, mais pour modifier une adresse déjà existante : use Symfony\Component\Security\Core\Exception\AccessDeniedException; public function modifierAdresseAction($id_adresse) { $em = $this->getDoctrine()->getEntityManager(); // On récupère l'adresse. $adresse = $em->getRepository('SdzBlogBundle:Adresse')->find($id_adresse); // On vérifie que l'adresse correspond au client en session (par exemple). if($adresse->getClient()->getId() != $this->get('session')->get('client_id')) { throw new AccessDeniedException("Vous n'avez pas le droit de modifier cette adresse."); } // On modifie le numéro de l'adresse. $adresse->setNumero(35); // On n'est pas obligé de persister notre $adresse car on l'a récupéré depuis Doctrine. // On ne passe pas du tout par le client ici en fait, donc pas besoin de persist non plus pour lui. // On déclenche la modification. $em->flush(); return new Response('OK'); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?php /** * @ORM\Entity */ class Membre { /** * @ORM\ManyToMany(targetEntity="Namespace\Bundle\Entity\Groupe") */ private $groupes; // ... } /** * @ORM\Entity */ class Groupe { // Nul besoin d'ajouter une propriété, ici. // ... } |
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 | <?php // Dans le fichier de l'entité. /** * @ORM\Entity */ class Membre { /** * @ORM\ManyToMany(targetEntity="Namespace\Bundle\Entity\Groupe") */ private $groupes; // Comme la propriété groupes doit être un ArrayCollection, souvenez-vous ; // on doit la définir dans un constructeur. public function __construct() { $this->groupes = new \Doctrine\Common\Collections\ArrayCollection; } // On est dans le côté propriétaire, on définit le getter. // Notez le « s » à getGroupes, on récupère une liste de groupes ici ! public function getGroupes() { return $this->groupes; } // Le setter. Attention, on n'a pas un setGroupes() mais un addGroupe() sans « s » ! public function addGroupe(\Namespace\Bundle\Entity\Groupe $groupe) { // On traite vraiment notre ArrayCollection comme un tableau. $this->groupes[] = $groupe; } } |
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 | <?php // Dans le contrôleur, pour ajouter un nouveau membre à plusieurs groupes existants : public function ajouterMembreAction() { $membre = new Membre; // $membre->setPseudo() etc // On récupère l'EntityManager. $em = $this->getDoctrine()->getEntityManager(); // On récupère les groupes par défaut à l'inscription d'un membre. // Cette méthode n'existe pas, il faudrait la créer bien sûr. $groupes = $em->getRepository('SdzBlogBundle:Groupe')->getGroupesParDefaut(); // $groupes est ici un ArrayCollection, et voyez par la suite, on le traite comme un tableau normal. // Pour chaque groupe, on y ajoute le nouveau membre. foreach($groupes as $groupe) { $membre->addGroupe($groupe); } // On persiste juste le membre. // En effet, les groupes existent déjà et on ne les modifie pas, donc pas besoin de les persister. // Et la relation entre membre et groupe, c'est le membre qui la gère, donc persister le membre persistera la relation. $em->persist($membre); // On déclenche l'enregistrement. $em->flush(); return new Response('OK'); } |
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 | <?php // Dans le contrôleur toujours, mais pour enlever d'un groupe un membre : public function enleverGroupeAction($groupe) { $em = $this->getDoctrine()->getEntityManager(); // On récupère le membre, bien sûr on suppose ici que son id est stocké en session. $membre_id = $this->get('session')->get('membre_id'); $membre = $em->getRepository('SdzBlogBundle:Membre')->find($membre_id); // On enlève le groupe. // Ici, on fait appel à la méthode removeElement() de l'ArrayCollection groupes. // Attention ici $groupe est bien une instance de Group, et pas seulement un id. $membre->getGroupes()->removeElement($groupe); // On a modifié la relation membre-groupe, or c'est le membre qui en est le propriétaire. // Donc on persiste le membre pour persister la relation. $em->persist($membre); // On déclenche la modification. $em->flush(); return new Response('OK'); } |
.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?php /** * @ORM\Entity */ class Commande_Produit { /** * @ORM\Id * @ORM\ManyToOne(targetEntity="Namespace\Bundle\Entity\Commande") */ private $commande; /** * @ORM\Id * @ORM\ManyToOne(targetEntity="Namespace\Bundle\Entity\Produit") */ private $produit; // Et les autres attributs comme la quantite, etc. // ... } |
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 | <?php /** * @ORM\Entity */ class Commande_Produit { /** * @ORM\Id * @ORM\ManyToOne(targetEntity="Namespace\Bundle\Entity\Commande") */ private $commande; /** * @ORM\Id * @ORM\ManyToOne(targetEntity="Namespace\Bundle\Entity\Produit") */ private $produit; // On définit le getter et le setter pour Commande public function getCommande() { return $this->commande; } public function setCommande(\Namespace\Bundle\Entity\Commande $commande) { $this->commande = $commande; } // On définit le getter et le setter pour Produit public function getProduit() { return $this->produit; } public function setProduit(\Namespace\Bundle\Entity\Produit $produit) { $this->produit = $produit; } } |
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 | <?php // Dans le contrôleur public function creerCommandeAction() { $em = $this->getDoctrine() ->getEntityManager(); // Les produits existent déjà, on les récupère depuis la bdd $liste_produits = $em->getRepository('SdzBlogBundle:Produit') ->findAll(); // Pour l'exemple, notre Commande contient tous les Produit // On crée la Commande $commande = new Commande; // On attribue les produits à la commande $i = 0; foreach($liste_produits as $produit) { // On crée une nouvelle "relation entre 1 produit et 1 commande" $commandeProduit[$i] = new Commande_Produit; // On définit la commande, qui est ici toujours la même $commandeProduit[$i]->setCommande($commande); // On définit le produit, qui change ici dans la boucle foreach $commandeProduit[$i]->setProduit($produit); // Arbitrairement, on dit que chaque produit est commandé en 3 exemplaires $commandeProduit[$i]->setQuantite(3); // Et bien sûr, on persiste cette relation $em->persist($commandeProduit[$i]); $i++; // On incrémente le $i qui ne sert qu'à indexer le tableau $commandeProduit } // On n'oublie pas de persister la commande $em->persist($commande); // Pas besoin de persister les produits : ils n'ont pas changé et, de plus, // ils sont déjà persistés car on les a récupéré depuis Doctrine // On déclenche l'enregistrement. $em->flush(); return new Response('OK'); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <?php // Dans le contrôleur : public function voirCommandeAction($id_commande) { $em = $this->getDoctrine() ->getEntityManager(); // On récupère la commande $commande = $em->getRepository('SdzBlogBundle:Commande') ->find($id_commande); // On récupère les commandeProduits pour la commande $commande $commandeProduits = $em->getRepository('SdzBlogBundle:Commande_Produit') ->findByCommande($commande); // On affiche la vue Twig : return $this->render('SdzBlogBundle:TestCommande:commande.html.twig', array( 'commandeProduits' => $commandeProduits 'commande' => $commande) ); } |
1 2 3 4 5 6 | Liste des produits de la commande {{ commande.nom }} :
<ul>
{% for commandeProduit in commandeProduits %}
<li>{{ commandeProduit.quantite }} exemplaire(s) du produit {{ commandeProduit.produit.nom }} ;</li>
{% endfor %}
</ul>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php /** * @ORM\Entity */ class Client { /** * @ORM\OneToMany(targetEntity="Namespace\Bundle\Entity\Adresse", mappedBy="client") */ private $adresses; // Ici adresses prend un "s", car on a plusieurs adresses pour un client. // ... } |
.1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php /** * @ORM\Entity */ class Adresse { /** * @ORM\ManyToOne(targetEntity="Namespace\Bundle\Entity\Client", inversedBy="adresses") */ private $client; // ... } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?php /** * @ORM\Entity */ class Client { /** * @ORM\OneToMany(targetEntity="Namespace\Bundle\Entity\Adresse", mappedBy="client") */ private $adresses; public function getAdresses() { return $this->adresses; } public function addAdresse(\Namespace\Bundle\Entity\Adresse $adresse) { $this->adresses[] = $adresse; } // ... } |
1 2 3 4 5 6 7 | <?php // Création des entités $client = new Client; $adresse = new Adresse; // On lie l'adresse au client $client->addAdresse($adresse); |
1 2 3 4 5 6 7 8 9 10 | <?php // Création des entités $client = new Client; $adresse = new Adresse; // On lie l'adresse au client $client->addAdresse($adresse); // On lie le client à l'adresse $adresse->setClient($client); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?php /** * @ORM\Entity */ class Client { /** * @ORM\OneToMany(targetEntity="Namespace\Bundle\Entity\Adresse", mappedBy="client") */ private $adresses; public function getAdresses() { return $this->adresses; } public function addAdresse(\Namespace\Bundle\Entity\Adresse $adresse) { $this->adresses[] = $adresse; $adresse->setClient($this); } // ... } |