<?php
declare(strict_types=1);
namespace Slivki\Repository\City;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\Persistence\ManagerRegistry;
use Slivki\Entity\City;
use Slivki\Exception\CityNotFoundException;
final class CityRepository extends ServiceEntityRepository implements CityRepositoryInterface
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, City::class);
}
/**
* @return City[]
*/
public function getActiveCities(): array
{
$qb = $this->createQueryBuilder('city');
$expr = $qb->expr();
return $qb
->andWhere($expr->eq('city.active', ':active'))
->setParameter('active', true)
->addOrderBy($expr->asc('city.position'))
->addOrderBy($expr->asc('city.name'))
->getQuery()
->getResult();
}
public function findById(int $id): ?City
{
$qb = $this->createQueryBuilder('c');
$expr = $qb->expr();
return $qb
->andWhere($expr->eq('c.ID', ':id'))
->setParameters([
'id' => $id,
])
->getQuery()
->getOneOrNullResult();
}
public function getById(int $id): City
{
$city = $this->findById($id);
if (!$city instanceof City) {
throw new CityNotFoundException();
}
return $city;
}
public function findActiveNearestCity(string $latitude, string $longitude): ?City
{
$qb = $this->createQueryBuilder('city');
$expr = $qb->expr();
return $qb
->andWhere($expr->eq('city.active', ':active'))
->addOrderBy($expr->min(
\sprintf('ST_Distance(city.point, GeomFromEWKT(\'SRID=4326;POINT(%s)\'))', \implode(' ', [$latitude, $longitude])))
)
->addGroupBy('city.ID')
->setParameters([
'active' => true,
])
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
}
public function findAllSortByName(): array
{
$qb = $this->createQueryBuilder('c');
$expr = $qb->expr();
return $qb
->andWhere($expr->eq('c.active', ':active'))
->setParameter('active', true)
->addOrderBy($expr->asc('c.name'))
->getQuery()
->getResult();
}
public function findActiveByDomain(string $domain): ?City
{
$queryBuilder = $this->createQueryBuilder('city');
$expr = $queryBuilder->expr();
return $queryBuilder
->andWhere($expr->eq('city.active', ':active'))
->andWhere($expr->eq('city.domain', ':domain'))
->setParameters(
[
'active' => true,
'domain' => $domain,
]
)
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
}
}