*/ #[ORM\OneToMany(targetEntity: Label::class, mappedBy: 'book', cascade: ['persist', 'remove'], fetch: 'EAGER', orphanRemoval: true)] #[ORM\OrderBy(['label' => 'ASC'])] private Collection $labels; /** @var Collection */ #[ORM\OneToMany(targetEntity: BorrowHistory::class, mappedBy: 'book', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['at' => 'DESC'])] private Collection $borrowHistory; public function __construct() { $this->labels = new ArrayCollection(); $this->borrowHistory = new ArrayCollection(); } public static function fromOusted(OustedBook $ousted): self { $book = new self(); $book->copyDataFrom($ousted); return $book; } public function getBorrow(): ?Borrow { return $this->borrow; } public function isBorrowed(): bool { return $this->borrow !== null; } public function lendTo(string $who, \DateTimeImmutable $at): void { if ($this->isBorrowed()) { throw new \LogicException(\sprintf('Book %d is already borrowed.', $this->id)); } $this->borrow = new Borrow($this, $who, $at); } public function giveBack(\DateTimeImmutable $at): void { if (!$this->borrow instanceof Borrow) { throw new \LogicException(\sprintf('Book %d is not borrowed.', $this->id)); } $this->borrowHistory->add(new BorrowHistory($this, $this->borrow->getWho(), $this->borrow->getAt(), $at)); $this->borrow = null; } /** * @return Collection */ public function getLabels(): Collection { return $this->labels; } protected function createLabel(string $label, LabelType $type): Label { return new Label($this, $label, $type); } /** * @return Collection */ public function getBorrowHistory(): Collection { return $this->borrowHistory; } public function addBorrowHistory(string $who, \DateTimeImmutable $at, \DateTimeImmutable $till): void { $this->borrowHistory->add(new BorrowHistory($this, $who, $at, $till)); } }