app/Plugin/Ranking/Controller/Block/RankingController.php line 229

Open in your IDE?
  1. <?php
  2. namespace Plugin\Ranking\Controller\Block;
  3. use Eccube\Controller\AbstractController;
  4. use Eccube\Entity\Master\ProductStatus;
  5. use Eccube\Repository\ProductRepository;
  6. use Symfony\Component\HttpFoundation\RequestStack;
  7. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  8. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  9. use Symfony\Component\Routing\Annotation\Route;
  10. use Symfony\Component\HttpFoundation\Request;
  11. use Eccube\Repository\OrderItemRepository;
  12. use Eccube\Application;
  13. use Eccube\Entity\Master\OrderStatus;
  14. use Eccube\Entity\OrderItem;
  15. use Eccube\Entity\Product;
  16. use Eccube\Entity\ProductCategory;
  17. use Plugin\Ranking\Repository\ConfigRepository;
  18. use Symfony\Component\DependencyInjection\ContainerInterface;
  19. class RankingController extends AbstractController
  20. {
  21.     /**
  22.      * @var RequestStack
  23.      */
  24.     protected $session;
  25.     /**
  26.      * @var ProductRepository
  27.      */
  28.     protected $productRepository;
  29.     
  30.     /**
  31.      * @var OrderItemRepository
  32.      */
  33.     protected $orderItemRepository;
  34.     /**
  35.      * @var ConfigRepository
  36.      */
  37.     protected $configRepository;
  38.     protected $containerInterface;
  39.     public function __construct(
  40.         SessionInterface $session,
  41.         ProductRepository $productRepository,
  42.         OrderItemRepository $orderItemRepository,
  43.         ConfigRepository $configRepository,
  44.         ContainerInterface $container
  45.     ) {
  46.         $this->session $session;
  47.         $this->productRepository $productRepository;
  48.         $this->orderItemRepository $orderItemRepository;
  49.         $this->configRepository $configRepository;
  50.         $this->containerInterface $container;
  51.     }
  52.     /**
  53.      * @Route("/block/ranking", name="block_ranking")
  54.      * @Template("Block/ranking.twig")
  55.      *
  56.      * @param Request $request
  57.      * @return array
  58.      */
  59.     public function index(Request $requestApplication $app) {
  60.         $rankingProducts = [];
  61.         // ランキング設定情報取得
  62.         $Config $this->configRepository->get();
  63.         // 注文日期間指定
  64.         $targetPeriod $Config->getTargetPeriod();
  65.         // 終了日(当日0時0分0秒)
  66.         $endDate date("Y/m/d 0:00:00");
  67.         $endDate date("Y/m/d H:i:s"strtotime('-9hour'));
  68.         // 開始日
  69.         if        ($targetPeriod == 5){$startDate date("Y/m/d 0:00:00"strtotime('-1 month'));    // 設定値が過去1ヶ月の場合、1ヶ月前の0時0分0秒
  70.         }else if($targetPeriod == 4){$startDate date("Y/m/d 0:00:00"strtotime('-3 week'));    // 設定値が過去3週間の場合、3週間前の0時0分0秒
  71.         }else if($targetPeriod == 3){$startDate date("Y/m/d 0:00:00"strtotime('-2 week'));    // 設定値が過去2週間の場合、2週間前の0時0分0秒
  72.         }else if($targetPeriod == 2){$startDate date("Y/m/d 0:00:00"strtotime('-1 week'));    // 設定値が過去1週間の場合、1週間前の0時0分0秒
  73.         }else                        {$startDate date("Y/m/d 0:00:00"strtotime('-1 day'));    // それ以外の場合は設定値が前日と見なし、前日の0時0分0秒
  74.         }
  75.         $categories $this->productRepository->getSupplierCategories();
  76.         // 自動ランキングデータ取得
  77.         // * 商品別注文データを注文日で範囲指定、重複する商品をグルーピング化し、注文数が多い商品順に取得
  78.         $query $this->orderItemRepository->createQueryBuilder('oi');
  79.         $subQuery $this->entityManager->createQueryBuilder();
  80.         $subQuery->select('pc');
  81.         $subQuery->from(ProductCategory::class, 'pc');
  82.         $subQuery->where($subQuery->expr()->in('pc.Category'$categories));
  83.         $subQuery->andWhere('pc.Product = p.id');
  84.         $query $query
  85.             ->select("COUNT(o.order_date) AS order_count, p.id AS product_id")
  86.             ->innerJoin('oi.Order''o')
  87.             ->innerJoin('oi.Product''p')
  88.             ->andWhere('oi.Product IS NOT NULL')                    // 商品ID必須(手数料等を除外)
  89.             ->andWhere('o.order_date IS NOT NULL')                    // 注文日必須
  90.             ->andWhere('o.OrderStatus != '.OrderStatus::RETURNED)    // 返品を除外
  91.             ->andWhere('o.OrderStatus != '.OrderStatus::CANCEL)        // 注文取消しを除外
  92.             ->andWhere("o.order_date >= '".$startDate."'")            // 注文日範囲指定 開始日
  93.             ->andWhere("o.order_date < '".$endDate."'")
  94.             ->andWhere('p.is_separately = 0')
  95.             ->andWhere($query->expr()->not($query->expr()->exists($subQuery->getDQL())))    
  96.             ->groupBy('p.id')
  97.             // ->orderBy('order_count', 'DESC')
  98.             ->addOrderBy('order_count''DESC')
  99.             ->addOrderBy('product_id''DESC')
  100.         ;
  101.             
  102.         // ギフトバッグ商品を除外
  103.         $giftbagProductIdList explode(","env('ECCUBE_GIFTBAG_ID_LIST'""));
  104.         $giftbagProductIdList array_map('intval'$giftbagProductIdList);    
  105.         if(count($giftbagProductIdList) > 0){
  106.             $query
  107.                 ->andWhere($query->expr()->notin('p.id'':giftbagProductIdList'))
  108.                 ->setParameter('giftbagProductIdList'$giftbagProductIdList);
  109.         }
  110.         // GARAGEカテゴリ商品を除外
  111.         $garageCategoryId = (int)env('GARAGE_PRODUCT_CATEGORY_ID'"");
  112.         if(is_numeric($garageCategoryId)){
  113.             $query
  114.                 // ->leftJoin('p.ProductCategories', 'grPct')
  115.                 // ->leftJoin('grPct.Category', 'grC')
  116.                 // ->andWhere('(
  117.                 //     grC.id != :garageCategoryId or
  118.                 //     grC.id IS NULL
  119.                 // )')
  120.                 // ->setParameter('garageCategoryId', $garageCategoryId);
  121.                 ->leftJoin('p.ProductCategories''grPct''WITH''grPct.category_id = :garageCategoryId')
  122.                 ->andWhere('grPct.category_id IS NULL')
  123.                 ->setParameter('garageCategoryId'$garageCategoryId);
  124.         }
  125.         // 「非公開」「廃止」の商品を除外
  126.         $query
  127.             ->andWhere('p.Status = :Status')
  128.             ->setParameter('Status'ProductStatus::DISPLAY_SHOW)
  129.         ;
  130.         $query $query->setMaxResults(10)->getQuery();
  131.         // echo $query->getSQL();
  132.         $autoRankingList $query->getResult();
  133.         // echo var_dump($autoRankingList)."<br><br>";
  134.         // ランキング枠設定情報をもとにランキングデータ配列生成
  135.         // array(
  136.         //    0 => ['product_id' => 商品ID, 'order_count' => 注文数],    # 枠1
  137.         //    1 => ['product_id' => 商品ID, 'order_count' => 注文数]    # 枠2
  138.         //  .
  139.         //  .
  140.         //  .
  141.         // )
  142.         $rankingList = [];
  143.         $configArray $this->configRepository->createQueryBuilder('cfg')->where('cfg.id = 1')->getQuery()->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY)[0];
  144.         for($i 1$i <= 10$i++){
  145.             if(!isset($configArray['frame'.$i.'_type']) || !isset($configArray['frame'.$i.'_value'])) continue;
  146.             // ランキング枠タイプが自動の場合、該当順位の商品IDを設定
  147.             // (自動ランキングデータに該当順位のデータが存在しない場合は注文0件と見なしスキップ)
  148.             if(!$configArray['frame'.$i.'_type']){
  149.                 if(!isset($autoRankingList[$i 1])) continue;
  150.                 $rankingList[] = [
  151.                     'product_id' => $autoRankingList[$i 1]['product_id'],
  152.                     'order_count' => $autoRankingList[$i 1]['order_count']
  153.                 ];
  154.             
  155.             // それ以外の場合ランキング枠タイプが手動と見なし、指定商品IDを設定
  156.             }else{
  157.                 $rankingList[] = [
  158.                     'product_id' => $configArray['frame'.$i.'_value'],
  159.                     'order_count' => null
  160.                 ];
  161.             }
  162.         }
  163.         // echo var_dump($rankingList).'<br><br>';
  164.         
  165.         // 該当する商品IDの一次配列を生成し、全ての商品情報取得
  166.         $productIdList array_column($rankingList'product_id');
  167.         // echo var_dump($productIdList)."<br><br>";
  168.         $query $this->productRepository->createQueryBuilder('p');
  169.         $query $query
  170.             ->select('p')
  171.             ->where($query->expr()->in('p.id'':productIdList'))
  172.             ->setParameter('productIdList'$productIdList)
  173.             ->getQuery()
  174.         ;
  175.         $productList $query->getResult();
  176.         if (count($productList) > 0) {
  177.             $rankingProducts array_map(function($item) use($productList){
  178.                 $targetProduct array_merge(
  179.                     array_filter($productList, function($product) use($item){
  180.                         return ($product['id'] == $item['product_id']);
  181.                     })
  182.                 );
  183.                 $item['Product'] = $targetProduct[0] ?? [];
  184.     
  185.                 $product $item['Product'];
  186.                 $rate $this->containerInterface->get(\Plugin\ProductReview4\Repository\ProductReviewRepository::class)->getAvgAll($product);
  187.                 $product->review_ave round($rate['recommend_avg']);
  188.                 $product->review_cnt intval($rate['review_count']);
  189.     
  190.                 return $item;
  191.             }, $rankingList);
  192.         } else {
  193.             $rankingProducts = [];
  194.         }
  195.         // ランキングデータ配列に商品情報を追加
  196.         
  197.         
  198.         return [
  199.             'AutoPlay' => $Config->getSliderAutoPlay(),
  200.             'SliderDesign' => $Config->getSliderDesign(),
  201.             'RankingProducts' => $rankingProducts
  202.         ];
  203.     }
  204.     /**
  205.      * @Route("/block/ranking_month", name="block_ranking_month")
  206.      * @Template("Block/ranking_month.twig")
  207.      *
  208.      * @param Request $request
  209.      * @return array
  210.      */
  211.     public function indexRankingMonth(Request $requestApplication $app) {
  212.         $rankingProductsMonth = [];
  213.         $existingBlock $this->entityManager->getRepository(\Eccube\Entity\Block::class)->findOneBy(['file_name' => 'ranking_month']);
  214.         if (empty($existingBlock)) {
  215.             $Block = new \Eccube\Entity\Block();
  216.             $deviceType $this->entityManager->getRepository(\Eccube\Entity\Master\DeviceType::class)
  217.                 ->find(\Eccube\Entity\Master\DeviceType::DEVICE_TYPE_PC);
  218.             $Block
  219.                 ->setDeviceType($deviceType)
  220.                 ->setUseController(true)
  221.                 ->setDeletable(false)
  222.                 ->setName('マンスリーランキング')
  223.                 ->setFileName('ranking_month');
  224.             $this->entityManager->persist($Block);
  225.             $this->entityManager->flush();
  226.         }
  227.         $Config $this->configRepository->get();
  228.         $targetPeriod $Config->getTargetPeriod();
  229.         $startDate date("Y/m/01 0:00:00");
  230.         $endDate date("Y/m/d H:i:s"strtotime('-9hour'));
  231.         
  232.         $categories $this->productRepository->getSupplierCategories();
  233.         $query $this->orderItemRepository->createQueryBuilder('oi');
  234.         $subQuery $this->entityManager->createQueryBuilder();
  235.         $subQuery->select('pc');
  236.         $subQuery->from(ProductCategory::class, 'pc');
  237.         $subQuery->where($subQuery->expr()->in('pc.Category'$categories));
  238.         $subQuery->andWhere('pc.Product = p.id');
  239.         $query $query
  240.             ->select("COUNT(o.order_date) AS order_count, p.id AS product_id")
  241.             ->innerJoin('oi.Order''o')
  242.             ->innerJoin('oi.Product''p')
  243.             ->andWhere('oi.Product IS NOT NULL')                    // 商品ID必須(手数料等を除外)
  244.             ->andWhere('o.order_date IS NOT NULL')                    // 注文日必須
  245.             ->andWhere('o.OrderStatus != '.OrderStatus::RETURNED)    // 返品を除外
  246.             ->andWhere('o.OrderStatus != '.OrderStatus::CANCEL)        // 注文取消しを除外
  247.             ->andWhere("o.order_date >= '".$startDate."'")            // 注文日範囲指定 開始日
  248.             ->andWhere("o.order_date < '".$endDate."'")
  249.             ->andWhere('p.is_separately = 0')
  250.             ->andWhere($query->expr()->not($query->expr()->exists($subQuery->getDQL())))    
  251.             ->groupBy('p.id')
  252.             ->addOrderBy('order_count''DESC')
  253.             ->addOrderBy('product_id''DESC')
  254.         ;
  255.             
  256.         $giftbagProductIdList explode(","env('ECCUBE_GIFTBAG_ID_LIST'""));
  257.         $giftbagProductIdList array_map('intval'$giftbagProductIdList);    
  258.         if(count($giftbagProductIdList) > 0){
  259.             $query
  260.                 ->andWhere($query->expr()->notin('p.id'':giftbagProductIdList'))
  261.                 ->setParameter('giftbagProductIdList'$giftbagProductIdList);
  262.         }
  263.         $garageCategoryId = (int)env('GARAGE_PRODUCT_CATEGORY_ID'"");
  264.         if(is_numeric($garageCategoryId)){
  265.             $query
  266.                 ->leftJoin('p.ProductCategories''grPct''WITH''grPct.category_id = :garageCategoryId')
  267.                 ->andWhere('grPct.category_id IS NULL')
  268.                 ->setParameter('garageCategoryId'$garageCategoryId);
  269.         }
  270.         $query
  271.             ->andWhere('p.Status = :Status')
  272.             ->setParameter('Status'ProductStatus::DISPLAY_SHOW)
  273.         ;
  274.         $query $query->setMaxResults(10)->getQuery();
  275.         $autoRankingList $query->getResult();
  276.     
  277.         $productIdList array_column($autoRankingList'product_id');
  278.         $query $this->productRepository->createQueryBuilder('p');
  279.         $query $query
  280.             ->select('p')
  281.             ->where($query->expr()->in('p.id'':productIdList'))
  282.             ->setParameter('productIdList'$productIdList)
  283.             ->getQuery()
  284.         ;
  285.         $productList $query->getResult();
  286.         if (count($productList) > 0) {
  287.             $rankingProductsMonth array_map(function($item) use($productList){
  288.                 $targetProduct array_merge(
  289.                     array_filter($productList, function($product) use($item){
  290.                         return ($product['id'] == $item['product_id']);
  291.                     })
  292.                 );
  293.                 $item['Product'] = $targetProduct[0] ?? [];
  294.     
  295.                 $product $item['Product'];
  296.                 $rate $this->containerInterface->get(\Plugin\ProductReview4\Repository\ProductReviewRepository::class)->getAvgAll($product);
  297.                 $product->review_ave round($rate['recommend_avg']);
  298.                 $product->review_cnt intval($rate['review_count']);
  299.     
  300.                 return $item;
  301.             }, $autoRankingList);
  302.         } else {
  303.             $rankingProductsMonth = [];
  304.         }
  305.         
  306.         return [
  307.             'RankingProductsMonth' => $rankingProductsMonth
  308.         ];
  309.     }
  310. }