<?php
namespace App\EntityManager;
use App\Entity\GalleryPic;
use App\Entity\Product;
use App\Entity\ProductAttribute;
use App\Entity\ProductAttributeOption;
use App\Entity\ProductCategory;
use App\Entity\ProductCompany;
use App\Entity\ProductFavorite;
use App\Entity\ProductSell;
use App\Entity\ProductShop;
use App\Entity\ProductShopBrand;
use App\Entity\ProductShopVote;
use App\Entity\ProductVote;
use App\Entity\User;
use App\Model\SearchProduct;
use App\Model\SearchShopList;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Bundle\PaginatorBundle\Pagination\SlidingPagination;
use Knp\Component\Pager\PaginatorInterface;
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Psr\SimpleCache\CacheInterface;
use Symfony\Component\Asset\Package;
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
class ProductManager extends AbstractEntityManager
{
protected $translator;
protected $package;
protected $requestStack;
protected $imagineCacheManager;
public function __construct(
EntityManagerInterface $entityManager,
TokenStorageInterface $tokenStorage,
CacheInterface $cache,
RequestStack $requestStack,
PaginatorInterface $paginator,
Security $security,
TranslatorInterface $translator,
CacheManager $liipCache
) {
parent::__construct($entityManager, $tokenStorage, $cache, $requestStack, $paginator, $security);
$this->translator = $translator;
$this->requestStack = $requestStack;
$this->package = new Package(new EmptyVersionStrategy());
$this->imagineCacheManager = $liipCache;
}
public function getCategories(?SearchProduct $searchObject): array
{
return $this->entityManager->getRepository(ProductCategory::class)->getCategs($searchObject);
}
public function getListCategories(SearchProduct $searchObject): array
{
return $this->entityManager->getRepository(ProductCategory::class)->getListCategs($searchObject);
}
public function getCategoryTree($categid = 0, $type = 0, $order = 'name')
{
return $this->entityManager->getRepository(ProductCategory::class)->getCategTree($categid, $type, $order);
}
public function getAllParentCategories(SearchProduct $searchObject): array
{
return $this->entityManager->getRepository(ProductCategory::class)->getAllParentCategories($searchObject);
}
public function getAttributes(SearchProduct $searchObject): array
{
$attributes = $this->entityManager->getRepository(ProductAttribute::class)->getAttributes($searchObject);
foreach ($attributes as $key => $attribute) {
$attributes[$key]->options = $this->entityManager
->getRepository(ProductAttributeOption::class)
->getAttributeOptions($attribute);
}
return $attributes;
}
public function getProductList(SearchProduct $searchObject, ?array $listCategories): SlidingPagination
{
/** @var SlidingPagination $products */
$products = $this->paginator->paginate(
$this->entityManager->getRepository(Product::class)->getProducts(
$searchObject,
$listCategories,
$this->getUser()
),
$this->getRequest()->query->getInt('page', 1),
Product::LIMIT_PER_PAGE,
[
PaginatorInterface::DEFAULT_SORT_FIELD_NAME => 'p.createdAt',
PaginatorInterface::DEFAULT_SORT_DIRECTION => 'desc',
PaginatorInterface::SORT_FIELD_WHITELIST => [
'p.createdAt',
'p.name',
'p.totalFavorite',
],
]
);
foreach ($products as $key => $product) {
$products[$key]->votes = $this->getProductVoteDetails($product);
$products[$key]->imgs = $this->getThumbPicture($product);
}
return $products;
}
public function getShopList(SearchShopList $searchObject): SlidingPagination
{
/** @var SlidingPagination $shops */
$shops = $this->paginator->paginate(
$this->entityManager->getRepository(ProductShop::class)->getShops($searchObject, $this->getUser()),
$this->getRequest()->query->getInt('page', 1),
ProductShop::LIMIT_PER_PAGE,
[
PaginatorInterface::DEFAULT_SORT_FIELD_NAME => 'ps.updatedAt',
PaginatorInterface::DEFAULT_SORT_DIRECTION => 'desc',
PaginatorInterface::SORT_FIELD_WHITELIST => [
'ps.updatedAt',
'ps.name',
'totalvotes',
],
]
);
return $shops;
}
public function getProductVoteDetails(Product $product)
{
$details = $this->entityManager->getRepository(ProductVote::class)->getProductVoteDetails($product);
$details[0]['avgvotes'] = intval(round($details[0]['avgvotes'], 0));
return $details[0];
}
public function getProductVotes(Product $product)
{
return $this->entityManager->getRepository(ProductVote::class)->getProductVotes($product);
}
public function getProductFavorite(Product $product)
{
return $this->entityManager->getRepository(ProductFavorite::class)->getProductFavorite($product);
}
public function getBrandResellers(Product $product)
{
$brandresellers = $this->entityManager->getRepository(ProductShop::class)->getBrandResellers($product);
foreach ($brandresellers as $key => $brandreseller) {
$brandresellers[$key]['avgvotes'] = intval(round($brandreseller['avgvotes'], 0));
}
return $brandresellers;
}
public function getTotalResellers(Product $product)
{
$totalresellers = $this->entityManager->getRepository(ProductSell::class)->getTotalResellers($product);
return $totalresellers[0];
}
public function getResellers(Product $product, bool $onlineShop = false, ?int $limit = null)
{
$resellers = null;
$totalresellers = $this->entityManager->getRepository(ProductSell::class)->getResellers(
$product,
$onlineShop,
$limit
);
foreach ($totalresellers as $key => $totalreseller) {
$resellers[$key]['data'] = $totalreseller;
$resellers[$key]['count'] = $this->getCountShopVotes($totalreseller->getShop());
}
return $resellers;
}
public function getSells(Product $product)
{
return $this->entityManager->getRepository(ProductSell::class)->findBy(['product' => $product]);
}
public function getLastComment(SearchProduct $searchObject)
{
return $this->entityManager->getRepository(ProductVote::class)->getLastComment($searchObject);
}
public function getThumbPicture(Product $product)
{
$picture = null;
$pos1 = strpos($product->getDescription(), '[thumb=');
if ($pos1 !== false) {
$pos1 = $pos1 + strlen('[thumb=');
$pos2 = strpos($product->getDescription(), ']', $pos1);
$picid = substr($product->getDescription(), $pos1, $pos2 - $pos1);
$picture = $this->entityManager->getRepository(GalleryPic::class)->find($picid);
}
return $picture;
}
public function getModerators(): array
{
return $this->entityManager->getRepository(User::class)->getUsersWithRoles(
User::ROLE_PRODUCT_ADMIN
);
}
public function getAllCompanies(): array
{
return $this->entityManager->getRepository(ProductCompany::class)->getAllCompanies();
}
public function createCompany(ProductCompany $company): ProductCompany
{
$this->entityManager->persist($company);
$this->entityManager->flush();
return $company;
}
public function getShopBrands(ProductShop $productShop)
{
$shopBrands = $this->entityManager->getRepository(ProductShopBrand::class)->getShopBrands(
$productShop,
$this->getUser()
);
return $shopBrands;
}
public function getCountShopVotes(ProductShop $productShop)
{
$shopVotes = $this->entityManager->getRepository(ProductShopVote::class)->getCountShopVotes($productShop);
$shopVotes = $shopVotes[0];
$shopVotes['avgvotes'] = intval(round($shopVotes['avgvotes'], 0));
return $shopVotes;
}
public function getShopVotes(ProductShop $productShop)
{
return $this->entityManager->getRepository(ProductShopVote::class)->getShopVotes($productShop);
}
public function toggleFavorite(Product $product): bool
{
$added = true;
$isFavorite = $this->entityManager->getRepository(ProductFavorite::class)
->findOneBy(
[
'user' => $this->getUser(),
'product' => $product,
]
);
if ($isFavorite instanceof ProductFavorite) {
$added = false;
$product->setTotalFavorite($product->getTotalFavorite() - 1);
$this->entityManager->remove($isFavorite);
$this->entityManager->flush();
} else {
$favorite = (new ProductFavorite())
->setProduct($product)
->setUser($this->getUser());
$product->setTotalFavorite($product->getTotalFavorite() + 1);
$this->entityManager->persist($favorite);
}
$this->entityManager->persist($product);
$this->entityManager->flush();
return $added;
}
public function hasFavorite(Product $product): bool
{
$isFavorite = $this->entityManager->getRepository(ProductFavorite::class)
->findOneBy(
[
'user' => $this->getUser(),
'product' => $product,
]
);
return ($isFavorite instanceof ProductFavorite);
}
public function getEvaluation(Product $product): ?ProductVote
{
return $this->entityManager->getRepository(ProductVote::class)
->findOneBy(
[
'product' => $product,
'createdBy' => $this->getUser(),
]
);
}
public function hasEvaluation(Product $product)
{
return $this->getEvaluation($product) instanceof ProductVote;
}
public function addEvaluation(Product $product, ProductVote $evaluation): void
{
$evaluation->setProduct($product);
$evaluation->setCreatedBy($this->getUser());
$this->entityManager->persist($evaluation);
$this->entityManager->flush();
}
public function editEvaluation(ProductVote $evaluation): void
{
// $this->updateScore($evaluation->getProduct());
$this->entityManager->persist($evaluation->getProduct());
$this->entityManager->persist($evaluation);
$this->entityManager->flush();
}
public function deleteEvaluation(ProductVote $evaluation)
{
$this->entityManager->remove($evaluation);
$this->entityManager->flush();
}
public function getShopEvaluation(ProductShop $shop): ?ProductShopVote
{
return $this->entityManager->getRepository(ProductShopVote::class)
->findOneBy(
[
'shop' => $shop,
'user' => $this->getUser(),
]
);
}
public function hasShopEvaluation(ProductShop $shop)
{
return $this->getShopEvaluation($shop) instanceof ProductShopVote;
}
public function addShopEvaluation(ProductShop $shop, ProductShopVote $evaluation): void
{
$evaluation->setShop($shop);
$evaluation->setUser($this->getUser());
$this->entityManager->persist($evaluation);
$this->entityManager->flush();
}
public function editShopEvaluation(ProductShopVote $evaluation): void
{
// $this->updateScore($evaluation->getShop());
$this->entityManager->persist($evaluation->getShop());
$this->entityManager->persist($evaluation);
$this->entityManager->flush();
}
public function deleteShopEvaluation(ProductShopVote $evaluation)
{
$this->entityManager->remove($evaluation);
$this->entityManager->flush();
}
}