app/Customize/Controller/CustomizeTopController.php line 45

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 Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  14. use Symfony\Component\Routing\Annotation\Route;
  15. use Eccube\Repository\ProductRepository;
  16. use Plugin\RecentlyViewedProducts\Service\RecentlyViewedProductService;
  17. use Eccube\Controller\TopController as BaseController;
  18. class CustomizeTopController extends BaseController
  19. {
  20.     /**
  21.      * @var RecentlyViewedProductService
  22.      */
  23.     protected $recentlyViewedProductService;
  24.     /**
  25.      * RecentlyViewedProductController constructor.
  26.      */
  27.     public function __construct(RecentlyViewedProductService $recentlyViewedProductService)
  28.     {
  29.         $this->recentlyViewedProductService $recentlyViewedProductService;
  30.     }
  31.     /**
  32.      * @Route("/books", name="books", methods={"GET"})
  33.      * @Template("@user_data/books.twig")
  34.      */
  35.     public function index()
  36.     {
  37.         $productRepository $this->getDoctrine()->getRepository(\Eccube\Entity\Product::class);
  38.         // ProductにTagもJOINして取得する
  39.         $qb $productRepository->createQueryBuilder('p')
  40.             ->leftJoin('p.ProductTag''pt')
  41.             ->leftJoin('pt.Tag''t')
  42.             ->leftJoin('p.ProductCategories''pc')
  43.             ->leftJoin('pc.Category''c')         
  44.             ->addSelect('pt')
  45.             ->addSelect('t')
  46.             ->addSelect('pc')                        
  47.             ->addSelect('c')                         
  48.             ->where('p.Status = 1')
  49.             ->orderBy('p.id''DESC');
  50.         $Products $qb->getQuery()->getResult();
  51.         $RecentlyViewedProducts array_map(function($RecentlyViewedProduct) {
  52.             return $RecentlyViewedProduct->getProduct();
  53.         }, $this->recentlyViewedProductService->getRecentlyViewedProducts());
  54.         $recommendProducts = [];
  55.         if($this->getUser()){
  56.         $Customer $this->getUser();
  57.         $recentlyViewedProductRepository $this->getDoctrine()->getRepository(\Plugin\RecentlyViewedProducts\Entity\RecentlyViewedProduct::class);
  58.         $histories $recentlyViewedProductRepository->findBy(
  59.           ['Customer' => $Customer->getId()],
  60.           ['viewed_date' => 'DESC'],
  61.           30
  62.         );
  63.       // 履歴のproduct_id一覧を作成
  64.       $viewedProductIds array_map(function($history) {
  65.           return $history->getProduct()->getId();
  66.       }, $histories);
  67.       $historyKeywords = [];
  68.       foreach ($histories as $history) {
  69.           $product $history->getProduct();
  70.           if (!$product) continue;
  71.       
  72.           // 検索ワード
  73.           if ($product->getSearchWord()) {
  74.               $words array_map('trim'explode(','$product->getSearchWord()));
  75.               $historyKeywords array_merge($historyKeywords$words);
  76.           }
  77.           // 著者
  78.           if ($product->getAuthor()) {
  79.               $historyKeywords[] = $product->getAuthor();
  80.           }
  81.       }
  82.       // ユーザーの所属県
  83.       if ($Customer->getPref()) {
  84.           $historyKeywords[] = $Customer->getPref()->getName();
  85.       }
  86.       // 特徴キーワードをユニークにする
  87.       $historyKeywords array_unique($historyKeywords);
  88.       // 全商品を取得
  89.       $allProducts $productRepository->findAll();
  90.       // 各商品のスコアを計算
  91.       $productScores = [];
  92.       foreach ($allProducts as $product) {
  93.           $keywords = [];
  94.       
  95.           // 検索ワード
  96.           if ($product->getSearchWord()) {
  97.               $words array_map('trim'explode(','$product->getSearchWord()));
  98.               $keywords array_merge($keywords$words);
  99.           }
  100.       
  101.           // 著者
  102.           if ($product->getAuthor()) {
  103.               $keywords[] = $product->getAuthor();
  104.           }
  105.       
  106.           // ここでは商品自体に「県」はないのでスキップ
  107.       
  108.           $keywords array_unique($keywords);
  109.       
  110.           // 閲覧履歴の特徴キーワードと比較して一致数をカウント
  111.           $commonCount count(array_intersect($historyKeywords$keywords));
  112.       
  113.           // スコアが高いものだけ残す(ここでは0でも一応保持)
  114.           $productScores[] = [
  115.               'product' => $product,
  116.               'score' => $commonCount,
  117.           ];
  118.       }
  119.       // スコア順にソート(スコア高い順)
  120.       usort($productScores, function($a$b) {
  121.           return $b['score'] <=> $a['score'];
  122.       });
  123.       
  124.       // Twigに渡す用のおすすめ商品リスト作成
  125.       $recommendProducts array_map(function($item) {
  126.           return $item['product'];
  127.       }, array_slice($productScores030)); // 例:おすすめ30件
  128. }
  129.         // Twigへ渡す
  130.         return [
  131.             'Products' => $Products,
  132.             'recommendProducts' => $recommendProducts,
  133.             'RecentlyViewedProducts' => $RecentlyViewedProducts,
  134.         ];
  135.     }
  136. }