<?php
declare(strict_types=1);
namespace Slivki\Paginator\WorkExample;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\PaginatorInterface;
use Slivki\Entity\WorkExample;
use Slivki\Message\Query\Beauty\Offer\GetWorkExampleOfMasterQuery;
use Slivki\Message\Query\WorkExample\GetWorkExamplesQuery;
use function sprintf;
final class WorkExamplePaginator implements WorkExamplePaginatorInterface
{
private EntityManagerInterface $entityManager;
private PaginatorInterface $paginator;
public function __construct(
EntityManagerInterface $entityManager,
PaginatorInterface $paginator
) {
$this->entityManager = $entityManager;
$this->paginator = $paginator;
}
public function findAllByQuery(GetWorkExamplesQuery $query): PaginationInterface
{
$queryBuilder = $this->entityManager->createQueryBuilder();
$expr = $queryBuilder->expr();
$currentUserPosition = $query->getCurrentUserPosition();
$queryBuilder
->addSelect('workExample')
->addSelect(
sprintf(
'%s as %s',
$currentUserPosition === null
? 0
: $expr->min(
sprintf(
"ST_Distance(geoLocation.point, GeomFromEWKT('SRID=4326;POINT(%s %s)'))",
$currentUserPosition->getLatitude(),
$currentUserPosition->getLongitude(),
),
),
WorkExamplePaginatorInterface::DISTANCE_SORT_FIELD,
),
)
->from(WorkExample::class, 'workExample')
->innerJoin('workExample.offer', 'offer')
->innerJoin('workExample.geoLocations', 'geoLocation')
->addGroupBy('workExample')
->addOrderBy($query->getSortField(), $query->getSortDirection())
;
if (null !== $query->getCategoryId()) {
$queryBuilder
->innerJoin('offer.categories', 'category')
->andWhere($expr->eq('category', ':categoryId'))
->setParameter('categoryId', $query->getCategoryId())
;
}
if (null !== $query->getOfferId()) {
$queryBuilder->andWhere($expr->eq('workExample.offer', ':offerId'));
$queryBuilder->setParameter('offerId', $query->getOfferId());
}
if (null !== $query->getMinPrice()) {
$queryBuilder->andWhere($expr->gte('workExample.price', ':minPrice'));
$queryBuilder->setParameter('minPrice', $query->getMinPrice());
}
if (null !== $query->getMaxPrice()) {
$queryBuilder->andWhere($expr->lte('workExample.price', ':maxPrice'));
$queryBuilder->setParameter('maxPrice', $query->getMaxPrice());
}
return $this->paginator->paginate($queryBuilder->getQuery(), $query->getPage(), $query->getPerPage());
}
public function findByMaster(GetWorkExampleOfMasterQuery $query): PaginationInterface
{
$queryBuilder = $this->entityManager->createQueryBuilder();
$expr = $queryBuilder->expr();
$queryBuilder
->addSelect('workExample')
->from(WorkExample::class, 'workExample')
->andWhere($expr->eq('workExample.beautyMaster', ':masterId'))
->setParameter('masterId', $query->getMasterId());
return $this->paginator->paginate($queryBuilder->getQuery(), $query->getPage(), $query->getPerPage());
}
}