app/Customize/Controller/ProductController.php line 314

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.ec-cube.co.jp/
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Customize\Controller;
  13. use Eccube\Controller\AbstractController;
  14. use Eccube\Entity\BaseInfo;
  15. use Eccube\Entity\Master\ProductStatus;
  16. use Eccube\Entity\Product;
  17. use Eccube\Event\EccubeEvents;
  18. use Eccube\Event\EventArgs;
  19. use Eccube\Form\Type\AddCartType;
  20. use Eccube\Form\Type\Master\ProductListMaxType;
  21. use Eccube\Form\Type\Master\ProductListOrderByType;
  22. use Eccube\Form\Type\SearchProductType;
  23. use Eccube\Repository\BaseInfoRepository;
  24. use Eccube\Repository\CategoryRepository;
  25. use Eccube\Repository\CustomerFavoriteProductRepository;
  26. use Eccube\Repository\Master\ProductListMaxRepository;
  27. use Eccube\Repository\ProductRepository;
  28. use Eccube\Service\CartService;
  29. use Eccube\Service\PurchaseFlow\PurchaseContext;
  30. use Eccube\Service\PurchaseFlow\PurchaseFlow;
  31. use Knp\Bundle\PaginatorBundle\Pagination\SlidingPagination;
  32. use Knp\Component\Pager\Paginator;
  33. use Plugin\Recommend4\Repository\RecommendProductRepository;
  34. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  35. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  36. use Symfony\Component\HttpFoundation\Request;
  37. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  38. use Symfony\Component\Routing\Annotation\Route;
  39. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  40. class ProductController extends AbstractController
  41. {
  42.     /**
  43.      * @var PurchaseFlow
  44.      */
  45.     protected $purchaseFlow;
  46.     /**
  47.      * @var CustomerFavoriteProductRepository
  48.      */
  49.     protected $customerFavoriteProductRepository;
  50.     /**
  51.      * @var CartService
  52.      */
  53.     protected $cartService;
  54.     /**
  55.      * @var ProductRepository
  56.      */
  57.     protected $productRepository;
  58.     /**
  59.      * @var BaseInfo
  60.      */
  61.     protected $BaseInfo;
  62.     /**
  63.      * @var AuthenticationUtils
  64.      */
  65.     protected $helper;
  66.     /**
  67.      * @var ProductListMaxRepository
  68.      */
  69.     protected $productListMaxRepository;
  70.     /**
  71.      * @var RecommendProductRepository
  72.      */
  73.     protected $recommendProductRepository;
  74.     /**
  75.      * @var CategoryRepository
  76.      */
  77.     protected $categoryRepository;
  78.     private $title '';
  79.     protected $shopDialogueId 100;
  80.     protected $shopEnsembleId 101;
  81.     protected $shopEnsembledeuxId 1217;
  82.     protected $shopFlairId 102;
  83.     protected $shopGatheringId 413;
  84.     /**
  85.      * ProductController constructor.
  86.      *
  87.      * @param PurchaseFlow $cartPurchaseFlow
  88.      * @param CustomerFavoriteProductRepository $customerFavoriteProductRepository
  89.      * @param CartService $cartService
  90.      * @param ProductRepository $productRepository
  91.      * @param BaseInfoRepository $baseInfoRepository
  92.      * @param AuthenticationUtils $helper
  93.      * @param ProductListMaxRepository $productListMaxRepository
  94.      */
  95.     public function __construct(
  96.         PurchaseFlow $cartPurchaseFlow,
  97.         CustomerFavoriteProductRepository $customerFavoriteProductRepository,
  98.         CartService $cartService,
  99.         ProductRepository $productRepository,
  100.         BaseInfoRepository $baseInfoRepository,
  101.         AuthenticationUtils $helper,
  102.         ProductListMaxRepository $productListMaxRepository,
  103.         RecommendProductRepository $recommendProductRepository,
  104.         CategoryRepository $categoryRepository
  105.     ) {
  106.         $this->purchaseFlow $cartPurchaseFlow;
  107.         $this->customerFavoriteProductRepository $customerFavoriteProductRepository;
  108.         $this->cartService $cartService;
  109.         $this->productRepository $productRepository;
  110.         $this->BaseInfo $baseInfoRepository->get();
  111.         $this->helper $helper;
  112.         $this->productListMaxRepository $productListMaxRepository;
  113.         $this->recommendProductRepository $recommendProductRepository;
  114.         $this->categoryRepository $categoryRepository;
  115.     }
  116.     /**
  117.      * 商品一覧画面.
  118.      *
  119.      * @Route("/products/list", name="product_list")
  120.      * @Template("Product/list.twig")
  121.      */
  122.     public function index(Request $requestPaginator $paginator)
  123.     {
  124.         $shop $request->query->get('shop');
  125.         if ($shop == 'dialogue') {
  126.             $request->query->set('category_id'100);
  127.         } elseif ($shop == 'ensemble') {
  128.             $request->query->set('category_id'101);
  129.         } elseif ($shop == 'ensembledeux') {
  130.             $request->query->set('category_id'1217);
  131.         } elseif ($shop == 'flair') {
  132.             $request->query->set('category_id'102);
  133.         } elseif ($shop == 'gathering') {
  134.             $request->query->set('category_id'413);
  135.         }
  136.         // Doctrine SQLFilter
  137.         if ($this->BaseInfo->isOptionNostockHidden()) {
  138.             $this->entityManager->getFilters()->enable('option_nostock_hidden');
  139.         }
  140.         // handleRequestは空のqueryの場合は無視するため
  141.         if ($request->getMethod() === 'GET') {
  142.             $request->query->set('pageno'$request->query->get('pageno'''));
  143.         }
  144.         // searchForm
  145.         /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
  146.         $builder $this->formFactory->createNamedBuilder(''SearchProductType::class);
  147.         if ($request->getMethod() === 'GET') {
  148.             $builder->setMethod('GET');
  149.         }
  150.         $event = new EventArgs(
  151.             [
  152.                 'builder' => $builder,
  153.             ],
  154.             $request
  155.         );
  156.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_INITIALIZE$event);
  157.         /* @var $searchForm \Symfony\Component\Form\FormInterface */
  158.         $searchForm $builder->getForm();
  159.         $searchForm->handleRequest($request);
  160.         // paginator
  161.         $searchData $searchForm->getData();
  162.         $searchData['is_special_sort'] = true;
  163.         $qb $this->productRepository->getQueryBuilderBySearchData($searchData);
  164.         $event = new EventArgs(
  165.             [
  166.                 'searchData' => $searchData,
  167.                 'qb' => $qb,
  168.             ],
  169.             $request
  170.         );
  171.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_SEARCH$event);
  172.         $searchData $event->getArgument('searchData');
  173.         $query $qb->getQuery()
  174.             ->useResultCache(true$this->eccubeConfig['eccube_result_cache_lifetime_short']);
  175.         /** @var SlidingPagination $pagination */
  176.         $pagination $paginator->paginate(
  177.             $query,
  178.             !empty($searchData['pageno']) ? $searchData['pageno'] : 1,
  179.             !empty($searchData['disp_number']) ? $searchData['disp_number']->getId() : $this->productListMaxRepository->findOneBy([], ['sort_no' => 'ASC'])->getId()
  180.         );
  181.         $ids = [];
  182.         foreach ($pagination as $Product) {
  183.             $ids[] = $Product->getId();
  184.         }
  185.         $ProductsAndClassCategories $this->productRepository->findProductsWithSortedClassCategories($ids'p.id');
  186.         // addCart form
  187.         $forms = [];
  188.         foreach ($pagination as $Product) {
  189.             /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
  190.             $product null;
  191.             if (array_key_exists($Product->getId(), $ProductsAndClassCategories)) {
  192.                 $product $ProductsAndClassCategories[$Product->getId()];
  193.             }
  194.             $builder $this->formFactory->createNamedBuilder(
  195.                 '',
  196.                 AddCartType::class,
  197.                 null,
  198.                 [
  199.                     'product' => $product,
  200.                     'allow_extra_fields' => true,
  201.                 ]
  202.             );
  203.             $addCartForm $builder->getForm();
  204.             $forms[$Product->getId()] = $addCartForm->createView();
  205.         }
  206.         // 表示件数
  207.         $builder $this->formFactory->createNamedBuilder(
  208.             'disp_number',
  209.             ProductListMaxType::class,
  210.             null,
  211.             [
  212.                 'required' => false,
  213.                 'allow_extra_fields' => true,
  214.             ]
  215.         );
  216.         if ($request->getMethod() === 'GET') {
  217.             $builder->setMethod('GET');
  218.         }
  219.         $event = new EventArgs(
  220.             [
  221.                 'builder' => $builder,
  222.             ],
  223.             $request
  224.         );
  225.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_DISP$event);
  226.         $dispNumberForm $builder->getForm();
  227.         $dispNumberForm->handleRequest($request);
  228.         // ソート順
  229.         $builder $this->formFactory->createNamedBuilder(
  230.             'orderby',
  231.             ProductListOrderByType::class,
  232.             null,
  233.             [
  234.                 'required' => false,
  235.                 'allow_extra_fields' => true,
  236.             ]
  237.         );
  238.         if ($request->getMethod() === 'GET') {
  239.             $builder->setMethod('GET');
  240.         }
  241.         $event = new EventArgs(
  242.             [
  243.                 'builder' => $builder,
  244.             ],
  245.             $request
  246.         );
  247.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_ORDER$event);
  248.         $orderByForm $builder->getForm();
  249.         $orderByForm->handleRequest($request);
  250.         $Category $searchForm->get('category_id')->getData();
  251.         return [
  252.             'subtitle' => $this->getPageTitle($searchData),
  253.             'pagination' => $pagination,
  254.             'search_form' => $searchForm->createView(),
  255.             'disp_number_form' => $dispNumberForm->createView(),
  256.             'order_by_form' => $orderByForm->createView(),
  257.             'forms' => $forms,
  258.             'Category' => $Category,
  259.             'shop' => $shop,
  260.         ];
  261.     }
  262.     /**
  263.      * 商品詳細画面.
  264.      *
  265.      * @Route("/products/detail/{id}", name="product_detail", methods={"GET"}, requirements={"id" = "\d+"})
  266.      * @Template("Product/detail.twig")
  267.      * @ParamConverter("Product", options={"repository_method" = "findWithSortedClassCategories"})
  268.      *
  269.      * @param Request $request
  270.      * @param Product $Product
  271.      *
  272.      * @return array
  273.      */
  274.     public function detail(Request $requestProduct $Product)
  275.     {
  276.         if (!$this->checkVisibility($Product)) {
  277.             throw new NotFoundHttpException();
  278.         }
  279.         $builder $this->formFactory->createNamedBuilder(
  280.             '',
  281.             AddCartType::class,
  282.             null,
  283.             [
  284.                 'product' => $Product,
  285.                 'id_add_product_id' => false,
  286.             ]
  287.         );
  288.         $event = new EventArgs(
  289.             [
  290.                 'builder' => $builder,
  291.                 'Product' => $Product,
  292.             ],
  293.             $request
  294.         );
  295.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_DETAIL_INITIALIZE$event);
  296.         $is_favorite false;
  297.         if ($this->isGranted('ROLE_USER')) {
  298.             $Customer $this->getUser();
  299.             $is_favorite $this->customerFavoriteProductRepository->isFavorite($Customer$Product);
  300.         }
  301.         $brand '';
  302.         $shop '';
  303.         foreach ($Product->getProductCategories() as $category) {
  304.             $category $category->getCategory();
  305.             if ($category->getParent() && $category->getParent()->getId() == '3') {
  306.                 $brand $category;
  307.             }
  308.             if ($category->getParent() && $category->getParent()->getId() == '2') {
  309.                 $shop $category;
  310.             }
  311.         }
  312.         // addCart form
  313.         $forms = [];
  314.         // $recommendProducts = $this->recommendProductRepository->getRecommendProduct();
  315.         // $category_id = 1097;
  316.         $category_id $this->shopDialogueId;
  317.         $shopName strtolower($shop->getName());
  318.         if ($shopName == 'dialogue') {
  319.             // $category_id = 1097;
  320.             $category_id $this->shopDialogueId;
  321.         } else if ($shopName == 'ensemble') {
  322.             // $category_id = 1098;
  323.             $category_id $this->shopEnsembleId;
  324.         } else if ($shopName == 'ensemble deux') {
  325.             // $category_id = 1099;
  326.             $shopName 'ensembledeux';
  327.             $category_id $this->shopEnsembledeuxId;
  328.         } else if ($shopName == 'flair') {
  329.             // $category_id = 1100;
  330.             $category_id $this->shopFlairId;
  331.         } else if ($shopName == 'gathering') {
  332.             // $category_id = 1101;
  333.             $category_id $this->shopGatheringId;
  334.         }
  335.         $recomend $Product->getRecommend();
  336.         if ($recomend) {
  337.             $recomend explode(','$recomend);
  338.             $recommendProducts $this->getProductsInRecommend($recomend3);
  339.         } else {
  340.             // 設定なし
  341.             $recommendProducts $this->getProductsInCategory($category_id3$Product->getId(), $brand);
  342.         }
  343.         // $ids = [];
  344.         // foreach ($recommendProducts as $item) {
  345.         //     $ids[] = $item->getId();
  346.         // }
  347.         // $ProductsAndClassCategories = $this->productRepository->findProductsWithSortedClassCategories($ids, 'p.id');
  348.         // foreach ($recommendProducts as $item) {
  349.         //     /* @var $builderForRecommends \Symfony\Component\Form\FormBuilderInterface */
  350.         //     $builderForRecommends = $this->formFactory->createNamedBuilder(
  351.         //         '',
  352.         //         AddCartType::class,
  353.         //         null,
  354.         //         [
  355.         //             'product' => $ProductsAndClassCategories[$item->getId()],
  356.         //             'allow_extra_fields' => true,
  357.         //         ]
  358.         //     );
  359.         //     $addCartForm = $builderForRecommends->getForm();
  360.         //     $forms[$item->getId()] = $addCartForm->createView();
  361.         // }
  362.         return [
  363.             'title' => $this->title,
  364.             'subtitle' => $Product->getName(),
  365.             'form' => $builder->getForm()->createView(),
  366.             'RecommendProducts' => $recommendProducts,
  367.             // 'forms' => $forms,
  368.             'Product' => $Product,
  369.             'is_favorite' => $is_favorite,
  370.             'shop' => $shopName,
  371.             'Brand' => $brand,
  372.         ];
  373.     }
  374.     /**
  375.      * お気に入り追加.
  376.      *
  377.      * @Route("/products/add_favorite/{id}", name="product_add_favorite", requirements={"id" = "\d+"})
  378.      */
  379.     public function addFavorite(Request $requestProduct $Product)
  380.     {
  381.         $this->checkVisibility($Product);
  382.         $event = new EventArgs(
  383.             [
  384.                 'Product' => $Product,
  385.             ],
  386.             $request
  387.         );
  388.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_INITIALIZE$event);
  389.         if ($this->isGranted('ROLE_USER')) {
  390.             $Customer $this->getUser();
  391.             $this->customerFavoriteProductRepository->addFavorite($Customer$Product);
  392.             $this->session->getFlashBag()->set('product_detail.just_added_favorite'$Product->getId());
  393.             $event = new EventArgs(
  394.                 [
  395.                     'Product' => $Product,
  396.                 ],
  397.                 $request
  398.             );
  399.             $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_COMPLETE$event);
  400.             return $this->redirectToRoute('product_detail', ['id' => $Product->getId()]);
  401.         } else {
  402.             // 非会員の場合、ログイン画面を表示
  403.             //  ログイン後の画面遷移先を設定
  404.             $this->setLoginTargetPath($this->generateUrl('product_add_favorite', ['id' => $Product->getId()]));
  405.             $this->session->getFlashBag()->set('eccube.add.favorite'true);
  406.             $event = new EventArgs(
  407.                 [
  408.                     'Product' => $Product,
  409.                 ],
  410.                 $request
  411.             );
  412.             $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_COMPLETE$event);
  413.             return $this->redirectToRoute('mypage_login');
  414.         }
  415.     }
  416.     /**
  417.      * カートに追加.
  418.      *
  419.      * @Route("/products/add_cart/{id}", name="product_add_cart", methods={"POST"}, requirements={"id" = "\d+"})
  420.      */
  421.     public function addCart(Request $requestProduct $Product)
  422.     {
  423.         // エラーメッセージの配列
  424.         $errorMessages = [];
  425.         if (!$this->checkVisibility($Product)) {
  426.             throw new NotFoundHttpException();
  427.         }
  428.         $builder $this->formFactory->createNamedBuilder(
  429.             '',
  430.             AddCartType::class,
  431.             null,
  432.             [
  433.                 'product' => $Product,
  434.                 'id_add_product_id' => false,
  435.             ]
  436.         );
  437.         $event = new EventArgs(
  438.             [
  439.                 'builder' => $builder,
  440.                 'Product' => $Product,
  441.             ],
  442.             $request
  443.         );
  444.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_INITIALIZE$event);
  445.         /* @var $form \Symfony\Component\Form\FormInterface */
  446.         $form $builder->getForm();
  447.         $form->handleRequest($request);
  448.         if (!$form->isValid()) {
  449.             throw new NotFoundHttpException();
  450.         }
  451.         $addCartData $form->getData();
  452.         log_info(
  453.             'カート追加処理開始',
  454.             [
  455.                 'product_id' => $Product->getId(),
  456.                 'product_class_id' => $addCartData['product_class_id'],
  457.                 'quantity' => $addCartData['quantity'],
  458.             ]
  459.         );
  460.         // カートへ追加
  461.         $this->cartService->addProduct($addCartData['product_class_id'], $addCartData['quantity']);
  462.         // 明細の正規化
  463.         $Carts $this->cartService->getCarts();
  464.         foreach ($Carts as $Cart) {
  465.             $result $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart$this->getUser()));
  466.             // 復旧不可のエラーが発生した場合は追加した明細を削除.
  467.             if ($result->hasError()) {
  468.                 $this->cartService->removeProduct($addCartData['product_class_id']);
  469.                 foreach ($result->getErrors() as $error) {
  470.                     $errorMessages[] = $error->getMessage();
  471.                 }
  472.             }
  473.             foreach ($result->getWarning() as $warning) {
  474.                 $errorMessages[] = $warning->getMessage();
  475.             }
  476.         }
  477.         $this->cartService->save();
  478.         log_info(
  479.             'カート追加処理完了',
  480.             [
  481.                 'product_id' => $Product->getId(),
  482.                 'product_class_id' => $addCartData['product_class_id'],
  483.                 'quantity' => $addCartData['quantity'],
  484.             ]
  485.         );
  486.         $event = new EventArgs(
  487.             [
  488.                 'form' => $form,
  489.                 'Product' => $Product,
  490.             ],
  491.             $request
  492.         );
  493.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_COMPLETE$event);
  494.         if ($event->getResponse() !== null) {
  495.             return $event->getResponse();
  496.         }
  497.         if ($request->isXmlHttpRequest()) {
  498.             // ajaxでのリクエストの場合は結果をjson形式で返す。
  499.             // 初期化
  500.             $done null;
  501.             $messages = [];
  502.             if (empty($errorMessages)) {
  503.                 // エラーが発生していない場合
  504.                 $done true;
  505.                 array_push($messagestrans('front.product.add_cart_complete'));
  506.             } else {
  507.                 // エラーが発生している場合
  508.                 $done false;
  509.                 $messages $errorMessages;
  510.             }
  511.             return $this->json(['done' => $done'messages' => $messages]);
  512.         } else {
  513.             // ajax以外でのリクエストの場合はカート画面へリダイレクト
  514.             foreach ($errorMessages as $errorMessage) {
  515.                 $this->addRequestError($errorMessage);
  516.             }
  517.             return $this->redirectToRoute('cart');
  518.         }
  519.     }
  520.     /**
  521.      * ページタイトルの設定
  522.      *
  523.      * @param  null|array $searchData
  524.      *
  525.      * @return str
  526.      */
  527.     protected function getPageTitle($searchData)
  528.     {
  529.         if (isset($searchData['name']) && !empty($searchData['name'])) {
  530.             return trans('front.product.search_result');
  531.         } elseif (isset($searchData['category_id']) && $searchData['category_id']) {
  532.             return $searchData['category_id']->getName();
  533.         } else {
  534.             return trans('front.product.all_products');
  535.         }
  536.     }
  537.     /**
  538.      * 閲覧可能な商品かどうかを判定
  539.      *
  540.      * @param Product $Product
  541.      *
  542.      * @return boolean 閲覧可能な場合はtrue
  543.      */
  544.     protected function checkVisibility(Product $Product)
  545.     {
  546.         $is_admin $this->session->has('_security_admin');
  547.         // 管理ユーザの場合はステータスやオプションにかかわらず閲覧可能.
  548.         if (!$is_admin) {
  549.             // 在庫なし商品の非表示オプションが有効な場合.
  550.             // if ($this->BaseInfo->isOptionNostockHidden()) {
  551.             //     if (!$Product->getStockFind()) {
  552.             //         return false;
  553.             //     }
  554.             // }
  555.             // 公開ステータスでない商品は表示しない.
  556.             if ($Product->getStatus()->getId() !== ProductStatus::DISPLAY_SHOW) {
  557.                 return false;
  558.             }
  559.         }
  560.         return true;
  561.     }
  562.     /**
  563.      * おすすめ商品一覧画面.
  564.      *
  565.      * @Route("/products/recommends", name="product_recommend_list")
  566.      * @Template("Product/recommend.twig")
  567.      */
  568.     public function product_recommend_list(Request $requestPaginator $paginator)
  569.     {
  570.         $pagination $paginator->paginate(
  571.             $this->recommendProductRepository->getRecommendProductQuery(),
  572.             $request->query->getInt('pageno'1),
  573.             25
  574.         );
  575.         return [
  576.             'recommend' => true,
  577.             'pagination' => $pagination,
  578.         ];
  579.     }
  580.     private function getProductsInCategory($categry_id$count$productId$brand null)
  581.     {
  582.         $category $this->categoryRepository->find($categry_id);
  583.         $qb $this->productRepository->createQueryBuilder('p')
  584.             ->addSelect("(CASE WHEN (CASE WHEN MAX(pc.stock) IS NULL THEN 0 ELSE MAX(pc.stock) END) + (CASE WHEN MAX(pc.stock_unlimited) IS NULL THEN 0 ELSE  MAX(pc.stock_unlimited) END) = 0 THEN '0000-00-00 00:00:00_0000-00-00 00:00:00' ELSE CONCAT(CASE WHEN p.published_at IS NULL THEN '0000-00-00 00:00:00' ELSE p.published_at END, '_', p.create_date) END) AS HIDDEN sort_field")
  585.             ->andWhere('p.id <> :pid')
  586.             ->setParameter('pid'$productId)
  587.             ->andWhere('p.Status = 1')
  588.             ->andWhere('p.published_at is NULL OR p.published_at <= :now')
  589.             ->setParameter('now', new \DateTime())
  590.             ->andWhere('pc.visible = :visible')
  591.             ->setParameter('visible'true);
  592.         $qb->innerJoin('p.ProductClasses''pc')
  593.             ->innerJoin('p.ProductCategories''pct')
  594.             ->innerJoin('pct.Category''c')
  595.             ->andWhere($qb->expr()->in('pct.Category'':Categories'))
  596.             ->setParameter('Categories', [$category]);
  597.         if (!empty($brand)) {
  598.             $qb->andWhere($qb->expr()->in('pct.Category'':Categories'))
  599.                 ->setParameter('Categories', [$brand]);
  600.         }
  601.         $qb->groupBy('p.id')
  602.             ->addOrderBy('sort_field''DESC')
  603.             ->addOrderBy('p.id''DESC');
  604.         $products $qb
  605.             ->setMaxResults($count)
  606.             ->getQuery()
  607.             ->getResult();
  608.         return $products;
  609.     }
  610.     private function getProductsInRecommend($recommend$count)
  611.     {
  612.         log_info("getlog" print_r($recommendtrue));
  613.         $qb $this->productRepository->createQueryBuilder('p')
  614.             ->andWhere('p.Status = 1')
  615.             ->andWhere('p.published_at is NULL OR p.published_at <= :now')
  616.             ->setParameter('now', new \DateTime())
  617.         ;
  618.         $qb->andWhere($qb->expr()->in('p.id'$recommend));
  619.         $qb->innerJoin('p.ProductCategories''pct')
  620.             ->innerJoin('pct.Category''c')
  621.             ->addOrderBy('p.id''DESC')
  622.             ->groupBy('p.id');
  623.         $products $qb
  624.             ->setMaxResults($count)
  625.             ->getQuery()
  626.             ->getResult();
  627.         return $products;
  628.     }
  629. }