src/Entity/Driver.php line 19
<?phpnamespace App\Entity;use App\Repository\DriverRepository;use Doctrine\ORM\Mapping as ORM;/*** A driver's profile. Authentication stays on User (ROLE_DRIVER); this entity* only carries the driving-specific data.** A driver has no coordinates of their own: their position IS the position of* the tuk they drive, so getLatitude()/getLongitude() read through to the Tuk.** @ORM\Entity(repositoryClass=DriverRepository::class)* @ORM\Table(name="driver")* @ORM\HasLifecycleCallbacks()*/class Driver{/*** @ORM\Id* @ORM\GeneratedValue* @ORM\Column(type="integer")*/private ?int $id = null;/*** @ORM\OneToOne(targetEntity=User::class)* @ORM\JoinColumn(nullable=false, unique=true)*/private User $user;/*** The tuk this driver drives. Inverse side — Tuk owns the join column.* @ORM\OneToOne(targetEntity=Tuk::class, mappedBy="driver")*/private ?Tuk $tuk = null;/*** Public-facing photo path, shown to the passenger when choosing a tuk.* @ORM\Column(type="string", length=500, nullable=true)*/private ?string $photo = null;/*** @ORM\Column(type="string", length=50, nullable=true)*/private ?string $licenseNumber = null;/*** Languages the driver speaks, as ISO 639-1 codes, e.g. ["en", "hy"].* @ORM\Column(type="json")*/private array $languages = [];/*** Average rating, 0.0–5.0.* @ORM\Column(type="decimal", precision=2, scale=1, options={"default": "5.0"})*/private string $rating = '5.0';/*** How many ratings $rating is averaged over.* @ORM\Column(type="integer", options={"default": 0})*/private int $ratingCount = 0;/*** Completed tours, shown as experience on the driver card.* @ORM\Column(type="integer", options={"default": 0})*/private int $tripCount = 0;/*** Running total of the gratuities passengers have added after their tours,* in dram. Kept as an aggregate here so the driver's profile can show it* without summing the whole booking table on every page view.** @ORM\Column(type="integer", options={"default": 0})*/private int $tipsAmd = 0;/*** @ORM\Column(type="boolean", options={"default": true})*/private bool $isActive = true;/*** @ORM\Column(type="datetime_immutable")*/private \DateTimeImmutable $createdAt;/*** @ORM\Column(type="datetime_immutable", nullable=true)*/private ?\DateTimeImmutable $updatedAt = null;public function __construct(){$this->createdAt = new \DateTimeImmutable();}/*** @ORM\PreUpdate()*/public function onPreUpdate(): void{$this->updatedAt = new \DateTimeImmutable();}public function getId(): ?int{return $this->id;}public function getUser(): User{return $this->user;}public function setUser(?User $user): self{$this->user = $user;return $this;}public function getTuk(): ?Tuk{return $this->tuk;}public function setTuk(?Tuk $tuk): self{$this->tuk = $tuk;return $this;}public function getPhoto(): ?string{return $this->photo;}public function setPhoto(?string $photo): self{$this->photo = $photo;return $this;}public function getLicenseNumber(): ?string{return $this->licenseNumber;}public function setLicenseNumber(?string $licenseNumber): self{$this->licenseNumber = $licenseNumber;return $this;}public function getLanguages(): array{return $this->languages;}public function setLanguages(array $languages): self{$this->languages = array_values(array_unique($languages));return $this;}public function getRating(): float{return (float) $this->rating;}public function setRating(float $rating): self{$this->rating = number_format(max(0.0, min(5.0, $rating)), 1, '.', '');return $this;}public function getRatingCount(): int{return $this->ratingCount;}public function setRatingCount(int $ratingCount): self{$this->ratingCount = $ratingCount;return $this;}/*** Fold a new 1–5 star rating into the running average.*/public function addRating(int $stars): self{$stars = max(1, min(5, $stars));$total = $this->getRating() * $this->ratingCount + $stars;$this->ratingCount++;$this->setRating($total / $this->ratingCount);return $this;}public function getTripCount(): int{return $this->tripCount;}public function setTripCount(int $tripCount): self{$this->tripCount = $tripCount;return $this;}public function getTipsAmd(): int{return $this->tipsAmd;}public function setTipsAmd(int $tipsAmd): self{$this->tipsAmd = max(0, $tipsAmd);return $this;}/*** Fold a gratuity into the running total.*/public function addTip(int $amountAmd): self{$this->tipsAmd += max(0, $amountAmd);return $this;}public function isActive(): bool{return $this->isActive;}public function setIsActive(bool $isActive): self{$this->isActive = $isActive;return $this;}public function getCreatedAt(): \DateTimeImmutable{return $this->createdAt;}public function getUpdatedAt(): ?\DateTimeImmutable{return $this->updatedAt;}// ── Read-through helpers: a driver is wherever their tuk is ──────────public function getName(): string{return $this->user->getName();}public function getLatitude(): ?float{return $this->tuk?->getLatitude();}public function getLongitude(): ?float{return $this->tuk?->getLongitude();}public function isOnline(): bool{return $this->tuk !== null && $this->tuk->isOnline();}public function __toString(): string{return $this->user->getName() ?? '';}}