Relationship::class])] #[ORM\Entity] #[DiscriminatorColumn(name: 'relation_id', type: 'integer')] #[ORM\Table(name: 'chill_person_relationships')] #[RelationshipNoDuplicate] class Relationship implements TrackCreationInterface, TrackUpdateInterface { use TrackCreationTrait; use TrackUpdateTrait; #[Assert\NotNull] #[Serializer\Groups(['read', 'write'])] #[ORM\ManyToOne(targetEntity: Person::class)] #[ORM\JoinColumn(nullable: false)] private ?Person $fromPerson = null; #[Serializer\Groups(['read'])] #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER)] private ?int $id = null; #[Assert\NotNull] #[Serializer\Groups(['read', 'write'])] #[ORM\ManyToOne(targetEntity: Relation::class)] #[ORM\JoinColumn(nullable: false, name: 'relation_id', referencedColumnName: 'id')] private ?Relation $relation = null; #[Assert\Type(type: 'bool', message: 'This must be of type boolean')] #[Serializer\Groups(['read', 'write'])] #[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN)] private bool $reverse; #[Assert\NotNull] #[Serializer\Groups(['read', 'write'])] #[ORM\ManyToOne(targetEntity: Person::class)] #[ORM\JoinColumn(nullable: false)] private ?Person $toPerson = null; public function getFromPerson(): ?Person { return $this->fromPerson; } public function getId(): ?int { return $this->id; } /** * Return the opposite person of the @see{counterpart} person. * * this is the from person if the given is associated to the To, * or the To person otherwise. * * @throw RuntimeException if the counterpart is neither in the from or to person */ public function getOpposite(Person $counterpart): Person { if ($this->fromPerson !== $counterpart && $this->toPerson !== $counterpart) { // during tests, comparing using equality does not work. We have to compare the ids if ( ($this->fromPerson->getId() === $counterpart->getId() && $this->toPerson->getId() === $counterpart->getId()) || null === $counterpart->getId() ) { throw new \RuntimeException(sprintf('the counterpart is neither the from nor to person for this relationship, expecting counterpart from %d and available %d and %d', $counterpart->getId(), $this->getFromPerson()->getId(), $this->getToPerson()->getId())); } } if ($this->fromPerson === $counterpart || $this->fromPerson->getId() === $counterpart->getId()) { return $this->toPerson; } return $this->fromPerson; } public function getRelation(): ?Relation { return $this->relation; } public function getReverse(): ?bool { return $this->reverse; } public function getToPerson(): ?Person { return $this->toPerson; } public function setFromPerson(?Person $fromPerson): self { $this->fromPerson = $fromPerson; return $this; } public function setRelation(?Relation $relation): self { $this->relation = $relation; return $this; } public function setReverse(bool $reverse): self { $this->reverse = $reverse; return $this; } public function setToPerson(?Person $toPerson): self { $this->toPerson = $toPerson; return $this; } }