Files
clinicpro/src/Clinic/Repository/ClinicRepository.php
T
hamed 4bb65c7502 feat(clinic): enhance clinic listing with additional details and address information
- Updated the clinic API response to include new fields: title, phone, logo, images_clinic, doctors_count, city, state, 24_7, and field_working_days.
- Modified the ClinicController to fetch and include city and state information based on the clinic's address.
- Refactored the toListArray method in the Clinic entity to accept city and state parameters.
- Added a new method in the ClinicRepository to retrieve city and province names for each clinic based on their address.
2026-06-18 15:03:36 +03:30

136 lines
4.4 KiB
PHP

<?php
namespace App\Clinic\Repository;
use App\Auth\Entity\User;
use App\Clinic\Entity\Clinic;
use App\Doctor\Entity\Doctor;
use App\Doctor\Entity\DoctorAddress;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Doctrine\Persistence\ManagerRegistry;
class ClinicRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Clinic::class);
}
public function findByUuid(string $uuid): ?Clinic
{
return $this->findOneBy(['uuid' => $uuid]);
}
/** @return Clinic[] */
public function findByDoctor(Doctor $doctor): array
{
return $this->createQueryBuilder('c')
->innerJoin('c.doctors', 'd')
->where('d.id = :doctorId')
->setParameter('doctorId', $doctor->getId())
->getQuery()
->getResult();
}
public function findByUser(User $user): ?Clinic
{
return $this->findOneBy(['user' => $user]);
}
public function findWithFilters(array $filters): array
{
$page = max(1, (int) ($filters['page'] ?? 1));
$limit = min(50, max(1, (int) ($filters['limit'] ?? 10)));
$sort = strtoupper($filters['sort'] ?? 'DESC') === 'ASC' ? 'ASC' : 'DESC';
$qb = $this->createQueryBuilder('c')
->leftJoin('c.specialties', 's')
->distinct();
// City/province live on the clinic's address (DoctorAddress.clinicId),
// not on the clinic itself. DoctorAddress has no Doctrine relation to
// Clinic, so join on the scalar clinicId with a WITH condition.
if (!empty($filters['city']) || !empty($filters['state'])) {
$qb->join(DoctorAddress::class, 'addr', Join::WITH, 'addr.clinicId = c.id');
if (!empty($filters['city'])) {
$qb->andWhere('IDENTITY(addr.city) = :city')->setParameter('city', (int) $filters['city']);
}
if (!empty($filters['state'])) {
$qb->andWhere('IDENTITY(addr.province) = :state')->setParameter('state', (int) $filters['state']);
}
}
if (!empty($filters['specialty'])) {
$qb->andWhere('s.id = :specialty')->setParameter('specialty', (int) $filters['specialty']);
}
$qb->orderBy('c.id', $sort);
$total = (new Paginator($qb))->count();
$results = $qb->setFirstResult(($page - 1) * $limit)
->setMaxResults($limit)
->getQuery()
->getResult();
return [
'items' => $results,
'total' => $total,
'page' => $page,
'limit' => $limit,
'totalPages' => (int) ceil($total / $limit),
];
}
/**
* City/province names for each clinic, taken from the clinic's address
* (DoctorAddress.clinicId). Returns [clinicId => ['city' => ?string, 'state' => ?string]].
*
* @param int[] $clinicIds
* @return array<int, array{city: ?string, state: ?string}>
*/
public function findAddressLocations(array $clinicIds): array
{
if ($clinicIds === []) {
return [];
}
$rows = $this->getEntityManager()->createQueryBuilder()
->select('addr.clinicId AS clinic_id', 'cityCat.name AS city', 'provinceCat.name AS state')
->from(DoctorAddress::class, 'addr')
->leftJoin('addr.city', 'cityCat')
->leftJoin('addr.province', 'provinceCat')
->where('addr.clinicId IN (:ids)')
->setParameter('ids', $clinicIds)
->getQuery()
->getResult();
$map = [];
foreach ($rows as $row) {
$id = (int) $row['clinic_id'];
if (!isset($map[$id])) {
$map[$id] = ['city' => $row['city'], 'state' => $row['state']];
}
}
return $map;
}
public function save(Clinic $clinic, bool $flush = true): void
{
$this->getEntityManager()->persist($clinic);
if ($flush) {
$this->getEntityManager()->flush();
}
}
public function remove(Clinic $clinic, bool $flush = true): void
{
$this->getEntityManager()->remove($clinic);
if ($flush) {
$this->getEntityManager()->flush();
}
}
}