<?php
namespace App\Repository;
use App\Entity\Cube;
use App\Entity\Prod;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Contracts\Cache\ItemInterface;
use Symfony\Contracts\Cache\TagAwareCacheInterface;
/**
* @extends ServiceEntityRepository<Cube>
*
* @method Cube|null find($id, $lockMode = null, $lockVersion = null)
* @method Cube|null findOneBy(array $criteria, array $orderBy = null)
* @method Cube[] findAll()
* @method Cube[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class CubeRepository extends ServiceEntityRepository
{
public function __construct(
ManagerRegistry $registry,
private CharvalRepository $charvalRepository,
private ProdRepository $prodRepository,
private TagAwareCacheInterface $appCache,
private RequestStack $requestStack,
)
{
parent::__construct($registry, Cube::class);
}
public function save(Cube $entity, bool $flush = false): void
{
$this->getEntityManager()->persist($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
public function remove(Cube $entity, bool $flush = false): void
{
$this->getEntityManager()->remove($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
/**
* Универсальный фильтр по кубу
* пример:
* $filters = ['color' => '111', 'size' => '222', 'pack' => 1]
*/
public function filter(string $model, array $filters): array
{
$qb = $this->em->createQueryBuilder()
->select('t')
->from(Cube::class, 't')
->where('t.model = :model')
->setParameter('model', $model);
foreach ($filters as $field => $value) {
switch ($field) {
case 'size': $qb->andWhere('s.name = :size')->setParameter('size', $value); break;
case 'color': $qb->andWhere('c.name = :color')->setParameter('color', $value); break;
case 'pack': $qb->andWhere('pack.name = :pack')->setParameter('pack', $value); break;
}
}
return $qb->getQuery()->getResult();
}
public function getColors(string $model, int $size, string $inpack, int $prod_id_except = 0): array
{
$colors = $this->appCache->get('cube_'.$model."_s".$size."_i".$inpack."_".$this->requestStack->getCurrentRequest()->getLocale(), function (ItemInterface $item) use ($model, $size, $inpack, $prod_id_except): array {
if ($prod_id_except) {
$sql = "SELECT prod, `color` FROM cube WHERE `model` = '".$model."' AND `size` = $size AND inpack = '$inpack' AND prod != $prod_id_except";
} else {
$sql = "SELECT prod, `color` FROM cube WHERE `model` = '".$model."' AND `size` = $size AND inpack = '$inpack' GROUP BY color order by size";
}
$results = $this->getEntityManager()->getConnection()->prepare($sql)->executeQuery()->fetchAllAssociative();
$colors = [];
foreach ($results as $k => $r) {
if (!isset($colors[$k])) {
$colors[$k] = [];
}
$colors[$k]['prod'] = $this->prodRepository->find($r['prod']);
$colors[$k]['color'] = $this->charvalRepository->find($r['color']);
}
return $colors;
});
return $colors;
}
public function getSizes(string $model, int $color, string $inpack, int $prod_id_except = 0): array
{
$sizes = $this->appCache->get('cube_'.$model."_c".$color."_i".$inpack."_".$this->requestStack->getCurrentRequest()->getLocale(), function (ItemInterface $item) use ($model, $color, $inpack, $prod_id_except): array {
if ($prod_id_except) {
$sql = "SELECT prod, `size` FROM cube WHERE `model` = '".$model."' AND `color` = $color AND inpack = '$inpack' prod != $prod_id_except";
} else {
$sql = "SELECT prod, `size` FROM cube WHERE `model` = '".$model."' AND `color` = $color AND inpack = '$inpack' GROUP BY size order by color";
}
$results = $this->getEntityManager()->getConnection()->prepare($sql)->executeQuery()->fetchAllAssociative();
$sizes = [];
foreach ($results as $k => $r) {
if (!isset($sizes[$k])) {
$sizes[$k] = [];
}
$sizes[$k]['prod'] = $this->prodRepository->find($r['prod']);
$sizes[$k]['size'] = $this->charvalRepository->find($r['size']);
}
return $sizes;
});
return $sizes;
}
public function getPacks(string $model, int $color, int $size, int $prod_id_except = 0): array
{
$packs = $this->appCache->get('cube_'.$model."_c".$color."_s".$size."_".$this->requestStack->getCurrentRequest()->getLocale(), function (ItemInterface $item) use ($model, $color, $size, $prod_id_except): array {
if ($prod_id_except) {
$sql = "SELECT prod, `inpack` FROM cube WHERE `model` = '".$model."' AND `color` = $color AND `size` = $size AND prod != $prod_id_except";
} else {
$sql = "SELECT prod, `inpack` FROM cube WHERE `model` = '".$model."' AND `color` = $color AND `size` = $size GROUP BY inpack order by prod";
}
$results = $this->getEntityManager()->getConnection()->prepare($sql)->executeQuery()->fetchAllAssociative();
$packs = [];
foreach ($results as $k => $r) {
if (!isset($packs[$k])) {
$packs[$k] = [];
}
$packs[$k]['prod'] = $this->prodRepository->find($r['prod']);
$packs[$k]['inpack'] = $packs[$k]['prod']->getInpack();
}
return $packs;
});
return $packs;
}
public function getProd(string $model, int $size, int $color, string $inpack): ?Prod
{
$sql = "SELECT `prod` FROM cube WHERE `model` = '".$model."' AND `color` = $color AND `size` = $size AND `inpack` = '$inpack'";
$results = $this->getEntityManager()->getConnection()->prepare($sql)->executeQuery()->fetchAssociative();
if (isset($results['prod'])) {
return $this->prodRepository->find($results['prod']);
} else {
return null;
}
}
}