Created
December 8, 2012 14:34
-
-
Save jaspernbrouwer/4240472 to your computer and use it in GitHub Desktop.
Basic Doctrine 2 one-to-many/many-to-one association setup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* This is a basic setup for Doctrine 2 one-to-many/many-to-one associations. | |
* | |
* There are many alternative approaches, additions and optimizations possible, | |
* but this example is only meant to help people getting started with the concept. | |
*/ | |
namespace My\Entity; | |
use Doctrine\ORM\Mapping as ORM; | |
use Doctrine\Common\Collections\ArrayCollection; | |
/** | |
* @ORM\Entity | |
* @ORM\Table( name="person" ) | |
*/ | |
class Person | |
{ | |
/** | |
* @ORM\Column( type="integer" ) | |
* @ORM\GeneratedValue( strategy="IDENTITY" ) | |
* @ORM\Id | |
* @var int | |
*/ | |
protected $id; | |
/** | |
* @ORM\Column( type="string" ) | |
* @var string | |
*/ | |
protected $name; | |
/** | |
* @ORM\OneToMany( targetEntity="My\Entity\Membership", mappedBy="person", orphanRemoval=TRUE ) | |
* @var \Doctrine\Common\Collections\Collection | |
*/ | |
protected $memberships; | |
/** | |
* Constructor. | |
*/ | |
public function __construct() | |
{ | |
$this->memberships = new ArrayCollection(); | |
} | |
/** | |
* @return int | |
*/ | |
public function getId() | |
{ | |
return $this->id; | |
} | |
/** | |
* @return string | |
*/ | |
public function getName() | |
{ | |
return $this->name; | |
} | |
/** | |
* @param string $name | |
* @return \My\Entity\Person | |
*/ | |
public function setName( $name ) | |
{ | |
$this->name = $name; | |
return $this; | |
} | |
/** | |
* @return array | |
*/ | |
public function getMemberships() | |
{ | |
return $this->memberships->toArray(); | |
} | |
/** | |
* @param \My\Entity\Group $group | |
* @return \My\Entity\Membership|null | |
*/ | |
public function getMembershipByGroup( Group $group ) | |
{ | |
foreach( $this->memberships as $membership ) { | |
if( $membership->getGroup() === $group ) { | |
return $membership; | |
} | |
} | |
return null; | |
} | |
/** | |
* @return array | |
*/ | |
public function getGroups() | |
{ | |
$groups = $this->memberships->map( | |
function( $membership ) { | |
return $membership->getGroup(); | |
} | |
); | |
return $groups->toArray(); | |
} | |
/** | |
* @param \My\Entity\Group $group | |
* @return \My\Entity\Person | |
*/ | |
public function removeGroup( Group $group ) | |
{ | |
foreach( $this->memberships as $membership ) { | |
if( $membership->getGroup() === $group ) { | |
$this->memberships->removeElement( $membership ); | |
// sync other side of one-to-many/many-to-one association | |
$group->removePerson( $this ); | |
} | |
} | |
return $this; | |
} | |
/** | |
* For internal use, never call directly. | |
* | |
* @internal | |
* @param \My\Entity\Membership $membership | |
* @return \My\Entity\Person | |
*/ | |
public function addMembership( Membership $membership ) | |
{ | |
$this->memberships->add( $membership ); | |
return $this; | |
} | |
} | |
/** | |
* @ORM\Entity | |
* @ORM\Table( name="membership" ) | |
*/ | |
class Membership | |
{ | |
/** | |
* @ORM\Column( type="integer" ) | |
* @ORM\GeneratedValue( strategy="IDENTITY" ) | |
* @ORM\Id | |
* @var int | |
*/ | |
protected $id; | |
/** | |
* @ORM\Column( type="string" ) | |
* @var string | |
*/ | |
protected $type; | |
/** | |
* @ORM\ManyToOne( targetEntity="My\Entity\Person", inversedBy="memberships" ) | |
* @ORM\JoinColumn( name="person_id", referencedColumnName="id", nullable=FALSE ) | |
* @var \My\Entity\Person | |
*/ | |
protected $person; | |
/** | |
* @ORM\ManyToOne( targetEntity="My\Entity\Group", inversedBy="memberships" ) | |
* @ORM\JoinColumn( name="group_id", referencedColumnName="id", nullable=FALSE ) | |
* @var \My\Entity\Group | |
*/ | |
protected $group; | |
/** | |
* Constructor. | |
* | |
* @param \My\Entity\Person $person | |
* @param \My\Entity\Group $group | |
*/ | |
public function __construct( Person $person, Group $group ) | |
{ | |
$this->person = $person; | |
$this->group = $group; | |
// sync other side of many-to-one associations | |
$person->addMembership( $this ); | |
$group->addMembership( $this ); | |
} | |
/** | |
* @return int | |
*/ | |
public function getId() | |
{ | |
return $this->id; | |
} | |
/** | |
* @return string | |
*/ | |
public function getType() | |
{ | |
return $this->type; | |
} | |
/** | |
* @param string $type | |
* @return \My\Entity\Membership | |
*/ | |
public function setType( $type ) | |
{ | |
$this->type = $type; | |
return $this; | |
} | |
/** | |
* @return \My\Entity\Person | |
*/ | |
public function getPerson() | |
{ | |
return $this->person; | |
} | |
/** | |
* @return \My\Entity\Group | |
*/ | |
public function getGroup() | |
{ | |
return $this->group; | |
} | |
} | |
/** | |
* @ORM\Entity | |
* @ORM\Table( name="group" ) | |
*/ | |
class Group | |
{ | |
/** | |
* @ORM\Column( type="integer" ) | |
* @ORM\GeneratedValue( strategy="IDENTITY" ) | |
* @ORM\Id | |
* @var int | |
*/ | |
protected $id; | |
/** | |
* @ORM\Column( type="string" ) | |
* @var string | |
*/ | |
protected $name; | |
/** | |
* @ORM\OneToMany( targetEntity="My\Entity\Membership", mappedBy="group", orphanRemoval=TRUE ) | |
* @var \Doctrine\Common\Collections\Collection | |
*/ | |
protected $memberships; | |
/** | |
* Constructor. | |
*/ | |
public function __construct() | |
{ | |
$this->memberships = new ArrayCollection(); | |
} | |
/** | |
* @return int | |
*/ | |
public function getId() | |
{ | |
return $this->id; | |
} | |
/** | |
* @return string | |
*/ | |
public function getName() | |
{ | |
return $this->name; | |
} | |
/** | |
* @param string $name | |
* @return \My\Entity\Group | |
*/ | |
public function setName( $name ) | |
{ | |
$this->name = $name; | |
return $this; | |
} | |
/** | |
* @return array | |
*/ | |
public function getMemberships() | |
{ | |
return $this->memberships->toArray(); | |
} | |
/** | |
* @param \My\Entity\Person $person | |
* @return \My\Entity\Membership|null | |
*/ | |
public function getMembershipByPerson( Person $person ) | |
{ | |
foreach( $this->memberships as $membership ) { | |
if( $membership->getPerson() === $person ) { | |
return $membership; | |
} | |
} | |
return null; | |
} | |
/** | |
* @return array | |
*/ | |
public function getPeople() | |
{ | |
$people = $this->memberships->map( | |
function( $membership ) { | |
return $membership->getPerson(); | |
} | |
); | |
return $people->toArray(); | |
} | |
/** | |
* @param \My\Entity\Person $person | |
* @return \My\Entity\Group | |
*/ | |
public function removePerson( Person $person ) | |
{ | |
foreach( $this->memberships as $membership ) { | |
if( $membership->getPerson() === $person ) { | |
$this->memberships->removeElement( $membership ); | |
// sync other side of one-to-many/many-to-one association | |
$person->removeGroup( $this ); | |
} | |
} | |
return $this; | |
} | |
/** | |
* For internal use, never call directly. | |
* | |
* @internal | |
* @param \My\Entity\Membership $membership | |
* @return \My\Entity\Group | |
*/ | |
public function addMembership( Membership $membership ) | |
{ | |
$this->memberships->add( $membership ); | |
return $this; | |
} | |
} | |
/* | |
* Using this setup. | |
* | |
* First person, group and membership: | |
*/ | |
$person1 = new Person(); | |
$person1->setName( 'John Doe' ); | |
$group1 = new Group(); | |
$group1->setName( 'Anonymous' ); | |
// this will also add membership to person and group: | |
$membership1 = new Membership( $person1, $group1 ); | |
$membership1->setType( 'follower' ); | |
$em->persist( $person1 ); | |
$em->persist( $group1 ); | |
$em->persist( $membership1 ); | |
$em->flush(); | |
/* | |
* Second person, add it to the same group: | |
*/ | |
$group1 = $em->find( 'My\Entity\Group', 1 ); | |
$person2 = new Person(); | |
$person2->setName( 'Jane Doe' ); | |
// this will also add membership to person and group: | |
$membership2 = new Membership( $person2, $group1 ); | |
$membership2->setType( 'follower' ); | |
$em->persist( $person2 ); | |
$em->persist( $membership2 ); | |
$em->flush(); | |
/* | |
* Change type of membership of second person: | |
*/ | |
$person2 = $em->find( 'My\Entity\Person', 2 ); | |
$group1 = $em->find( 'My\Entity\Group', 1 ); | |
$membership = $person2->getMembershipByGroup( $group1 ); | |
$membership->setType( 'leader' ); | |
$em->flush(); | |
/* | |
* Remove first person from the group: | |
*/ | |
$person1 = $em->find( 'My\Entity\Person', 1 ); | |
$group1 = $em->find( 'My\Entity\Group', 1 ); | |
// this will also remove person from group, and delete membership from db due to orphan-removal: | |
$person1->removeGroup( $group1 ); | |
$em->flush(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment