<?php
declare(strict_types=1);
namespace Slivki\Paginator\Beauty\Master;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\PaginatorInterface;
use Slivki\Entity\BeautyMaster;
use Slivki\Entity\GeoLocation;
use Slivki\Message\Query\Beauty\Category\GetMastersWithFilterQuery as GetMastersWithFilterQueryForCategory;
use Slivki\Message\Query\Beauty\Offer\GetMastersWithFilterQuery as GetMastersWithFilterQueryForOffer;
final class MasterPaginator implements MasterPaginatorInterface
{
private EntityManagerInterface $entityManager;
private PaginatorInterface $paginator;
public function __construct(
EntityManagerInterface $entityManager,
PaginatorInterface $paginator
) {
$this->entityManager = $entityManager;
$this->paginator = $paginator;
}
public function findAllMasterForOfferQueryByFilter(GetMastersWithFilterQueryForOffer $query): PaginationInterface
{
$queryBuilder = $this->entityManager->createQueryBuilder();
$expr = $queryBuilder->expr();
$locationIdsSubQuery = $this->entityManager->createQueryBuilder()
->addSelect('gl.ID')
->from(GeoLocation::class, 'gl')
->innerJoin('gl.offers', 'o')
->andWhere($expr->eq('o.ID', ':offerId'));
$queryBuilder
->addSelect('bm')
->from(BeautyMaster::class, 'bm')
->innerJoin('bm.locations', 'l')
->andWhere($expr->in('l.ID', $locationIdsSubQuery->getDQL()))
->andWhere($expr->isNull('bm.position'))
->addGroupBy('bm.id')
->addOrderBy($expr->asc('bm.id'))
->setParameter('offerId', $query->getOfferId());
if (null !== $query->getLevel()) {
$queryBuilder
->andWhere($expr->eq('bm.level', ':level'))
->setParameter('level', $query->getLevel());
}
return $this->paginator->paginate($queryBuilder->getQuery(), $query->getPage(), $query->getPerPage());
}
public function findAllMasterForCategoryQueryByFilter(GetMastersWithFilterQueryForCategory $query): PaginationInterface
{
$queryBuilder = $this->entityManager->createQueryBuilder();
$expr = $queryBuilder->expr();
$queryBuilder
->addSelect('bm')
->addSelect('RAND() as HIDDEN rand')
->from(BeautyMaster::class, 'bm')
->innerJoin('bm.categories', 'c')
->innerJoin('bm.locations', 'l')
->innerJoin('l.offers', 'o')
->andWhere($expr->eq('c.ID', ':categoryId'))
->andWhere($expr->eq('o.active', ':offerActive'))
->andWhere($expr->eq('o.hidden', ':offerHidden'))
->andWhere($expr->between('current_timestamp()', 'o.activeSince', 'o.activeTill'))
->andWhere($expr->isNull('bm.position'))
->addOrderBy($expr->asc('rand'))
->setParameters([
'categoryId' => $query->getCategoryId(),
'offerActive' => true,
'offerHidden' => false,
]);
if (null !== $query->getLevel() && $query->getLevel() > 0) {
$queryBuilder->andWhere($expr->eq('bm.level', ':level'))
->setParameter('level', $query->getLevel());
}
return $this->paginator->paginate($queryBuilder->getQuery(), $query->getPage(), $query->getPerPage());
}
}