src/Eccube/Controller/Block/RelatedProductController.php line 52

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 Eccube\Controller\Block;
  13. use Eccube\Controller\AbstractController;
  14. use Eccube\Repository\ProductRepository;
  15. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\RequestStack;
  18. use Symfony\Component\Routing\Annotation\Route;
  19. class RelatedProductController extends AbstractController
  20. {
  21.     /**
  22.      * @var ProductRepository
  23.      */
  24.     protected $productRepository;
  25.     /**
  26.      * @var RequestStack
  27.      */
  28.     protected $requestStack;
  29.     /**
  30.      * RelatedProductController constructor.
  31.      */
  32.     public function __construct(ProductRepository $productRepositoryRequestStack $requestStack)
  33.     {
  34.         $this->productRepository $productRepository;
  35.         $this->requestStack $requestStack;
  36.     }
  37.     /**
  38.      * 関連商品ブロック
  39.      * 商品詳細ページ:商品情報編集で登録した「関連商品」(RelatedProduct42 プラグイン)を表示。
  40.      * プラグイン未使用時は同一カテゴリの商品。それ以外のページでは新着順。
  41.      *
  42.      * @Route("/block/related_product", name="block_related_product", methods={"GET"})
  43.      * @Template("Block/related_product.twig")
  44.      */
  45.     public function index(Request $request)
  46.     {
  47.         $Products = [];
  48.         $maxResults 8;
  49.         $mainRequest $this->requestStack->getMainRequest();
  50.         if ($mainRequest && $mainRequest->attributes->get('_route') === 'product_detail') {
  51.             $productId $mainRequest->attributes->get('id');
  52.             if ($productId) {
  53.                 $Product $this->productRepository->find($productId);
  54.                 if ($Product) {
  55.                     // 商品情報編集で登録した「関連商品」(RelatedProduct42 プラグイン)を優先
  56.                     $Products $this->getRelatedProductsFromPlugin($Product$maxResults);
  57.                     // プラグインで取得できなかった場合は同一カテゴリの商品で補う
  58.                     if (empty($Products) && $Product->getProductCategories()) {
  59.                         $categoryIds = [];
  60.                         foreach ($Product->getProductCategories() as $ProductCategory) {
  61.                             $Category $ProductCategory->getCategory();
  62.                             if ($Category) {
  63.                                 $categoryIds[] = $Category->getId();
  64.                             }
  65.                         }
  66.                         if (!empty($categoryIds)) {
  67.                             $Products $this->productRepository->getProductsByCategoryIds(
  68.                                 $categoryIds,
  69.                                 $maxResults 1
  70.                             );
  71.                             $Products array_values(array_filter($Products, function ($p) use ($Product) {
  72.                                 return $p->getId() !== $Product->getId();
  73.                             }));
  74.                             $Products array_slice($Products0$maxResults);
  75.                         }
  76.                     }
  77.                 }
  78.             }
  79.         }
  80.         if (empty($Products)) {
  81.             $qb $this->productRepository->createQueryBuilder('p')
  82.                 ->addSelect(['pc''pi''tr''ps'])
  83.                 ->innerJoin('p.ProductClasses''pc')
  84.                 ->leftJoin('p.ProductImage''pi')
  85.                 ->leftJoin('pc.TaxRule''tr')
  86.                 ->leftJoin('pc.ProductStock''ps')
  87.                 ->andWhere('p.Status = 1')
  88.                 ->andWhere('pc.visible = :visible')
  89.                 ->setParameter('visible'true)
  90.                 ->orderBy('p.create_date''DESC')
  91.                 ->setMaxResults($maxResults);
  92.             $Products $qb->getQuery()->getResult();
  93.         }
  94.         return [
  95.             'Products' => $Products,
  96.         ];
  97.     }
  98.     /**
  99.      * 関連商品プラグイン(RelatedProduct42)で登録された関連商品を取得
  100.      *
  101.      * @param \Eccube\Entity\Product $Product 表示中商品
  102.      * @param int $maxResults 最大件数
  103.      * @return \Eccube\Entity\Product[]
  104.      */
  105.     private function getRelatedProductsFromPlugin($Product$maxResults)
  106.     {
  107.         foreach (['Plugin\RelatedProduct42\Entity\RelatedProduct''Plugin\RelatedProduct4\Entity\RelatedProduct'] as $entityClass) {
  108.             if (!class_exists($entityClass)) {
  109.                 continue;
  110.             }
  111.             try {
  112.                 $repo $this->entityManager->getRepository($entityClass);
  113.                 $orderBy method_exists($entityClass'getSortNo') ? ['sortNo' => 'ASC'] : [];
  114.                 $relatedEntities $repo->findBy(
  115.                     ['Product' => $Product],
  116.                     $orderBy,
  117.                     $maxResults
  118.                 );
  119.                 $products = [];
  120.                 foreach ($relatedEntities as $Related) {
  121.                     $child method_exists($Related'getChildProduct') ? $Related->getChildProduct() : null;
  122.                     if ($child && $child->getId() !== $Product->getId()) {
  123.                         $products[] = $child;
  124.                     }
  125.                 }
  126.                 return $products;
  127.             } catch (\Throwable $e) {
  128.                 continue;
  129.             }
  130.         }
  131.         return [];
  132.     }
  133. }