<?php
declare(strict_types=1);
namespace Slivki\Repository\Category;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Slivki\Entity\Category;
use Slivki\Entity\MainMenu;
use Slivki\Exception\CategoryNotFoundException;
final class CategoryRepository extends ServiceEntityRepository implements CategoryRepositoryInterface
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Category::class);
}
/**
* @throws CategoryNotFoundException
*/
public function getById(int $id): Category
{
$category = $this->findById($id);
if (!$category instanceof Category) {
throw CategoryNotFoundException::missingId($id);
}
return $category;
}
public function findById(int $id): ?Category
{
$queryBuilder = $this->createQueryBuilder('category');
$expr = $queryBuilder->expr();
return $queryBuilder
->andWhere($expr->eq('category.ID', ':id'))
->setParameter('id', $id)
->getQuery()
->getOneOrNullResult();
}
public function findByIds(array $ids): array
{
$queryBuilder = $this->createQueryBuilder('category');
$expr = $queryBuilder->expr();
return $queryBuilder
->andWhere($expr->in('category.ID', ':ids'))
->setParameter('ids', $ids)
->getQuery()
->getResult();
}
/**
* @return Category[]
*/
public function getActiveExcludedFreeSubCategories(Category $category): array
{
return $category->getSubCategories()->filter(
static fn (Category $subCategory): bool =>
false === $subCategory->isPast()
&& true === $subCategory->isActive()
&& \in_array(
$subCategory->getCategoryType()->getID(),
[Category::DEFAULT_CATEGORY_TYPE, Category::SERVICE_CATEGORY_TYPE],
true
)
&& Category::OFFER_CATEGORY_ID === $subCategory->getDomainObjectID()
)->toArray();
}
public function findCategoryByMainMenu(MainMenu $mainMenu): ?Category
{
if (!\in_array($mainMenu->getType(), [MainMenu::TYPE_OFFER_CATEGORY, MainMenu::TYPE_SALE_CATEGORY], true)) {
return null;
}
return $this->findById($mainMenu->getEntityID());
}
public function findTopActiveDefaultTypeCategoriesByCitySortedByName(array $cityIds): array
{
$qb = $this->createQueryBuilder('category');
$expr = $qb->expr();
return $qb
->innerJoin('category.city', 'city')
->andWhere($expr->in('city.ID', ':cityIds'))
->andWhere($expr->eq('category.active', ':active'))
->andWhere($expr->eq('category.typeID', ':defaultCategoryType'))
->andWhere($expr->eq('category.domainObjectID', ':domainObjectID'))
->andWhere('category.parents is empty')
->setParameters([
'cityIds' => $cityIds,
'active' => true,
'defaultCategoryType' => Category::DEFAULT_CATEGORY_TYPE,
'domainObjectID' => Category::OFFER_CATEGORY_ID,
])
->addOrderBy($expr->asc('category.name'))
->getQuery()
->getResult();
}
public function findActiveOfferCategoriesByCityIdAndPattern(int $cityId, string $pattern): array
{
$queryBuilder = $this->createQueryBuilder('category');
$expr = $queryBuilder->expr();
return $queryBuilder
->andWhere($expr->eq('category.city', ':cityId'))
->andWhere($expr->eq('category.active', ':active'))
->andWhere($expr->eq('category.past', ':past'))
->andWhere($expr->eq('category.domainObjectID', ':domainObjectId'))
->andWhere(
$expr->like(
$expr->lower('category.name'),
':pattern',
),
)
->andWhere($expr->in('category.typeID', ':types'))
->setParameters([
'cityId' => $cityId,
'pattern' => \sprintf('%%%s%%', \mb_strtolower($pattern)),
'active' => true,
'past' => false,
'types' => [Category::DEFAULT_CATEGORY_TYPE, Category::SERVICE_CATEGORY_TYPE],
'domainObjectId' => Category::OFFER_CATEGORY_ID,
])
->addOrderBy('category.ID')
->getQuery()
->getResult();
}
public function findActiveMeOnMapCategoriesByCityId(int $cityId): array
{
$queryBuilder = $this->createQueryBuilder('category');
$expr = $queryBuilder->expr();
return $queryBuilder
->andWhere($expr->eq('category.city', ':cityId'))
->andWhere($expr->eq('category.meOnMapActive', ':active'))
->andWhere($expr->eq('category.past', ':past'))
->andWhere($expr->eq('category.active', ':active'))
->setParameters([
'cityId' => $cityId,
'active' => true,
'past' => false,
])
->addOrderBy('category.meOnMapPosition')
->addOrderBy('category.ID')
->getQuery()
->getResult();
}
public function findActiveMeOnMapFeaturedCategoriesByCityId(int $cityId): array
{
$queryBuilder = $this->createQueryBuilder('category');
$expr = $queryBuilder->expr();
return $queryBuilder
->andWhere($expr->eq('category.city', ':cityId'))
->andWhere($expr->eq('category.meOnMapFeaturedActive', ':meOnMapFeaturedActive'))
->andWhere($expr->eq('category.past', ':past'))
->andWhere($expr->eq('category.active', ':categoryActive'))
->setParameters([
'cityId' => $cityId,
'meOnMapFeaturedActive' => true,
'categoryActive' => true,
'past' => false,
])
->addOrderBy('category.meOnMapFeaturedPosition')
->addOrderBy('category.ID')
->getQuery()
->getResult();
}
}