<?php
namespace App\Controller\Front;
use App\Entity\Category;
use App\Entity\Declination;
use App\Entity\Produit;
use App\Entity\ProduitDeclinationValue;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
class CategoryController extends AbstractController
{
use ImageTrait;
/** @var EntityManagerInterface */
private $em;
/**
* @var Serializer
*/
private $serializer;
public function __construct(EntityManagerInterface $manager, SerializerInterface $serializer)
{
$this->em = $manager;
$this->serializer = $serializer;
}
/**
* @Route("/api/product-list-by-category", name="product_list_by_category", options={"expose"=true}, methods={"GET"})
*/
public function getProductsAPI(Request $request): Response
{
$category_id = $request->query->get('id');
$page = $request->query->get('page');
$orderBy = $request->query->get('orderBy');
$categories=[(int)$category_id];
$category = $this->em->getRepository(Category::class)->find($category_id);
if (!$category) {
throw $this->createNotFoundException('Category Not Found');
}
foreach ($category->getSubCategories() as $child) {
$categories[] = $child->getId();
foreach ($child->getSubCategories() as $sub_child) {
$categories[] = $sub_child->getId();
}
}
//Les Filtres de recherche
$tailles = preg_split('@,@', $request->query->get('tailles'), NULL, PREG_SPLIT_NO_EMPTY);
$couleurs = preg_split('@,@', $request->query->get('couleurs'), NULL, PREG_SPLIT_NO_EMPTY);
$maxPrice = floatval($request->query->get('maxPrice'));
$minPrice = floatval($request->query->get('minPrice'));
// get the product repository
$produits = $this->em->getRepository(Produit::class);
// build the query for the doctrine paginator
$query = $produits->createQueryBuilder('p');
$query->where('p.categories IN (:cat)')
->setParameter('cat', $categories)
->andWhere('p.deletedAt is null')
->andWhere('p.showInWebSite = 1')
->andWhere('p.price_ttc between :minPrice and :maxPrice')
->setParameter('maxPrice', $maxPrice)
->setParameter('minPrice', $minPrice);
// Appliquer les filtres de tailles si ils sont appliqués
if( $tailles && !$couleurs) {
$declination = $this->em->getRepository(Declination::class)->find(1);
$query->innerJoin('App\Entity\ProduitDeclinationValue', 'd', 'with', 'd.produit=p')
->innerJoin('App\Entity\GroupDeclinationValue', 'g', 'with', 'g.produitDeclination= d')
->innerJoin('App\Entity\ValueDeclination', 'v', 'with', 'v= g.value')
->andWhere("v.name in (:tailles)")
->andWhere('v.declination = :declination')
->setParameter('declination', $declination)
->setParameter('tailles', $tailles);
}
// Appliquer les filtres de couleurs si ils sont appliqués seulement
if( $couleurs && !$tailles) {
$declination = $this->em->getRepository(Declination::class)->find(2);
$query->innerJoin('App\Entity\ProduitDeclinationValue', 'd', 'with', 'd.produit=p')
->innerJoin('App\Entity\GroupDeclinationValue', 'g', 'with', 'g.produitDeclination= d')
->innerJoin('App\Entity\ValueDeclination', 'v', 'with', 'v= g.value')
->andWhere("v.id in (:couleurs) or v.parent in (:couleurs)")
->andWhere('v.declination = :declination')
->setParameter('declination', $declination)
->setParameter('couleurs', $couleurs);
}
// Appliquer les filtres de tailles et couleurs appliqués les deux
if( $tailles && $couleurs) {
$declinationTaille = $this->em->getRepository(Declination::class)->find(1);
$declinationCouleur = $this->em->getRepository(Declination::class)->find(2);
// Fusionner les deux filtres en un seul
$filtres = array_merge($tailles, $couleurs);
$query->innerJoin('App\Entity\ProduitDeclinationValue', 'd', 'with', 'd.produit=p')
->innerJoin('App\Entity\GroupDeclinationValue', 'g', 'with', 'g.produitDeclination= d')
->innerJoin('App\Entity\ValueDeclination', 'v', 'with', 'v= g.value')
->andWhere("v.name in (:tailles) or v.id in (:couleurs) or v.parent in (:couleurs)")
/* ->andWhere('v.declination = :declinationTaille OR v.declination = :declinationCouleur')
->setParameter('declinationTaille', $declinationTaille)*/
->setParameter('couleurs', $couleurs)
->setParameter('tailles', $tailles);
}
// Order by
switch ($orderBy) {
case 1:
$query->orderBy('p.name', 'ASC');
break;
case 2:
$query->orderBy('p.name', 'DESC');
break;
case 3:
$query->orderBy('p.price_ttc', 'ASC');
break;
case 4:
$query->orderBy('p.price_ttc', 'DESC');
break;
case 5:
$query->orderBy('p.createdAt', 'ASC');
break;
case 6:
$query->orderBy('p.createdAt', 'DESC');
break;
}
// set page size
$pageSize = $request->query->get('pageSize');;
// load doctrine Paginator
$paginator = new \Doctrine\ORM\Tools\Pagination\Paginator($query);
// you can get total items
$totalItems = count($paginator);
// get total pages
$pagesCount = ceil($totalItems / $pageSize);
// now get one page's items:
$paginator
->getQuery()
->setFirstResult($pageSize * ($page-1)) // set the offset
->setMaxResults($pageSize); // set the limit
$data= array();
foreach ($paginator as $pageItem) {
// do stuff with results...
array_push($data,$pageItem);
}
foreach ($data as $product){
$product->image = $this->getDefaultImage( $product);
}
// Les nombres de pages
$pages = array();
for ($i = max($page - 3, 1); $i <= min($page + 3, $pagesCount); $i++) {
array_push($pages, $i);
}
/* // build the query for the doctrine paginator
$query = $produits->createQueryBuilder('p')
->where('p.name like :search OR p.description like :search OR p.reference like :search')
->setParameter('search', '%'.$search.'%')
->andWhere('p.deletedAt is null');*/
$response = [
'res' => 'OK',
'data' => $data,
//'taillesFilter' => $taillesFilter,
'pagesCount' => $pagesCount,
'total' => $totalItems,
'pages' => $pages,
'message' => 'Produits récupérés avec succès.',
];
return new jsonResponse($response);
}
/**
* @Route("/category/{id}/{name?}", options={"expose"=true}, name="category_new",requirements={"id"="\d+"})
*/
public function indexNew(Request $request, $id): Response
{
$category = $this->em->getRepository(Category::class)->find($id);
if (!$category) {
throw $this->createNotFoundException('Category Not Found');
}
// Récupérer les catégories fils
$categories = [];
array_push($categories,$category);
foreach ($category->getSubCategories() as $child) {
array_push($categories,$child);
foreach ($child->getSubCategories() as $sub) {
array_push($categories,$sub);
}
}
return $this->render('front/category/index.html.twig', [
'category_id' => $id,
'categories' => $categories,
'categorie' => $category ? $category : null,
]);
}
/**
* @Route("/category-dec/{id}/{name?}", options={"expose"=true}, name="category_dec",requirements={"id"="\d+"})
*/
public function indexDec(Request $request, $id): Response
{
$category = $this->em->getRepository(Category::class)->find($id);
if (!$category) {
throw $this->createNotFoundException('Category Not Found');
}
// Récupérer les catégories fils
$categories = [];
array_push($categories,$category);
foreach ($category->getSubCategories() as $child) {
array_push($categories,$child);
foreach ($child->getSubCategories() as $sub) {
array_push($categories,$sub);
}
}
return $this->render('front/dec/index.html.twig', [
'category_id' => $id,
'categories' => $categories,
'categorie' => $category ? $category : null,
]);
}
/**
* @Route("/api/dec-list-by-category", name="dec_list_by_category", options={"expose"=true}, methods={"GET"})
*/
public function getProductsDecAPI(Request $request): Response
{
$category_id = $request->query->get('id');
$page = $request->query->get('page');
$orderBy = $request->query->get('orderBy');
$category = $this->em->getRepository(Category::class)->find($category_id);
// Récupérer les catégories fils
$categories = [];
array_push($categories,$category);
foreach ($category->getSubCategories() as $child) {
array_push($categories,$child);
foreach ($child->getSubCategories() as $sub) {
array_push($categories,$sub);
}
}
//Les Filtres de recherche
$tailles = preg_split('@,@', $request->query->get('tailles'), NULL, PREG_SPLIT_NO_EMPTY);
$couleurs = preg_split('@,@', $request->query->get('couleurs'), NULL, PREG_SPLIT_NO_EMPTY);
$maxPrice = floatval($request->query->get('maxPrice'));
$minPrice = floatval($request->query->get('minPrice'));
// get the product dec repository
$produits = $this->em->getRepository(ProduitDeclinationValue::class);
// build the query for the doctrine paginator
$query = $produits->createQueryBuilder('d');
$query->innerJoin('App\Entity\Produit', 'p', 'with', 'd.produit=p')
->where('p.categories in (:cat)')
->setParameter('cat', $categories)
->andWhere('p.deletedAt is null')
->andWhere('p.showInWebSite = 1')
->andWhere('p.price_ttc between :minPrice and :maxPrice')
->setParameter('maxPrice', $maxPrice)
->setParameter('minPrice', $minPrice)
->groupBy('p.id,v.id');
// Appliquer les filtres de tailles si ils sont ne pas appliqués
if( !$tailles && !$couleurs) {
$declination = $this->em->getRepository(Declination::class)->find(1);
$query->innerJoin('App\Entity\GroupDeclinationValue', 'g', 'with', 'g.produitDeclination= d')
->innerJoin('App\Entity\ValueDeclination', 'v', 'with', 'v= g.value')
->andWhere('v.declination=2');
}
// Appliquer les filtres de tailles si ils sont appliqués
if( $tailles && !$couleurs) {
$declination = $this->em->getRepository(Declination::class)->find(1);
$query->innerJoin('App\Entity\GroupDeclinationValue', 'g', 'with', 'g.produitDeclination= d')
->innerJoin('App\Entity\ValueDeclination', 'v', 'with', 'v= g.value')
->andWhere("v.name in (:tailles)")
->setParameter('tailles', $tailles);
}
// Appliquer les filtres de couleurs si ils sont appliqués seulement
if( $couleurs && !$tailles) {
$declination = $this->em->getRepository(Declination::class)->find(2);
$query->innerJoin('App\Entity\GroupDeclinationValue', 'g', 'with', 'g.produitDeclination= d')
->innerJoin('App\Entity\ValueDeclination', 'v', 'with', 'v= g.value')
->andWhere("v.id in (:couleurs) or v.parent in (:couleurs)")
->setParameter('couleurs', $couleurs);
}
// Appliquer les filtres de tailles et couleurs appliqués les deux
if( $tailles && $couleurs) {
$declinationTaille = $this->em->getRepository(Declination::class)->find(1);
$declinationCouleur = $this->em->getRepository(Declination::class)->find(2);
// Fusionner les deux filtres en un seul
$filtres = array_merge($tailles, $couleurs);
$query->innerJoin('App\Entity\GroupDeclinationValue', 'g', 'with', 'g.produitDeclination= d')
->innerJoin('App\Entity\ValueDeclination', 'v', 'with', 'v= g.value')
->andWhere("v.name in (:tailles) or v.id in (:couleurs) or v.parent in (:couleurs)")
->setParameter('couleurs', $couleurs)
->setParameter('tailles', $tailles)
->groupBy('v.declination')
->having('v.declination=2');
}
// Order by
switch ($orderBy) {
case 1:
$query->orderBy('p.name', 'ASC');
break;
case 2:
$query->orderBy('p.name', 'DESC');
break;
case 3:
$query->orderBy('p.price_ttc', 'ASC');
break;
case 4:
$query->orderBy('p.price_ttc', 'DESC');
break;
case 5:
$query->orderBy('p.createdAt', 'ASC');
break;
case 6:
$query->orderBy('p.createdAt', 'DESC');
break;
}
// set page size
$pageSize = $request->query->get('pageSize');;
// load doctrine Paginator
$paginator = new \Doctrine\ORM\Tools\Pagination\Paginator($query);
// you can get total items
$totalItems = count($paginator);
// get total pages
$pagesCount = ceil($totalItems / $pageSize);
// now get one page's items:
$paginator
->getQuery()
->setFirstResult($pageSize * ($page-1)) // set the offset
->setMaxResults($pageSize); // set the limit
$data= array();
foreach ($paginator as $pageItem) {
// do stuff with results...
$pageItem->setImage($this->getDefaultImage(null, $pageItem));
array_push($data,$pageItem);
}
// Les nombres de pages
$pages = array();
for ($i = max($page - 3, 1); $i <= min($page + 3, $pagesCount); $i++) {
array_push($pages, $i);
}
$response = [
'res' => 'OK',
'data' => $data,
'pagesCount' => $pagesCount,
'total' => $totalItems,
'pages' => $pages,
'message' => 'Produits récupérés avec succès.',
];
return new jsonResponse($response);
}
// Non utilisé
/*public function categoriesDropdownList(): Response {
$sql = 'select * from category limit 100';
$stmt = $this->em->getConnection()->prepare($sql);
$categories = $stmt->executeQuery()->fetchAllAssociative();
return $this->render('front/category/_categoriesDropdownList.html.twig', [
'categories' => $categories
]);
}*/
}