app/Customize/Controller/AuctionController.php line 535

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 Customize\Entity\Auction;
  14. use Customize\Entity\Master\AuctionStatus;
  15. use Customize\Event\EccubeEvents;
  16. use Customize\Form\Type\SearchAuctionType;
  17. use Customize\Form\Type\SearchProductType;
  18. use Customize\Repository\AuctionRepository;
  19. use Customize\Repository\BitHistoryRepository;
  20. use Customize\Repository\CustomerFavoriteAuctionRepository;
  21. use Customize\Repository\CustomerFavoriteProductRepository;
  22. use Customize\Repository\ProductRepository;
  23. use Customize\Repository\OrderRepository;
  24. use Eccube\Controller\AbstractController;
  25. use Eccube\Event\EventArgs;
  26. use Eccube\Repository\Master\ProductListMaxRepository;
  27. use Knp\Bundle\PaginatorBundle\Pagination\SlidingPagination;
  28. use Knp\Component\Pager\PaginatorInterface;
  29. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  30. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  31. use Symfony\Component\HttpFoundation\Request;
  32. use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
  33. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  34. use Symfony\Component\Routing\Annotation\Route;
  35. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  36. class AuctionController extends AbstractController
  37. {
  38.     /**
  39.      * @var AuctionRepository
  40.      */
  41.     protected $auctionRepository;
  42.     /**
  43.      * @var BitHistoryRepository
  44.      */
  45.     protected $bitHistoryRepository;
  46.     /**
  47.      * @var CustomerFavoriteAuctionRepository
  48.      */
  49.     protected $customerFavoriteAuctionRepository;
  50.     /**
  51.      * @var CustomerFavoriteProductRepository
  52.      */
  53.     protected $customerFavoriteProductRepository;
  54.     /**
  55.      * @var ProductRepository
  56.      */
  57.     protected $productRepository;
  58.     /**
  59.      * @var ProductListMaxRepository
  60.      */
  61.     protected $productListMaxRepository;
  62.     /**
  63.      * @var OrderRepository
  64.      */
  65.     protected $orderRepository;
  66.     private $title '';
  67.     /**
  68.      * AuctionController constructor.
  69.      */
  70.     public function __construct(
  71.         AuctionRepository $auctionRepository,
  72.         BitHistoryRepository $bitHistoryRepository,
  73.         CustomerFavoriteAuctionRepository $customerFavoriteAuctionRepository,
  74.         CustomerFavoriteProductRepository $customerFavoriteProductRepository,
  75.         ProductRepository $productRepository,
  76.         ProductListMaxRepository $productListMaxRepository,
  77.         OrderRepository $orderRepository,
  78.     ) {
  79.         $this->auctionRepository $auctionRepository;
  80.         $this->bitHistoryRepository $bitHistoryRepository;
  81.         $this->customerFavoriteAuctionRepository $customerFavoriteAuctionRepository;
  82.         $this->customerFavoriteProductRepository $customerFavoriteProductRepository;
  83.         $this->productRepository $productRepository;
  84.         $this->productListMaxRepository $productListMaxRepository;
  85.         $this->orderRepository $orderRepository;
  86.     }
  87.     /**
  88.      * オークション一覧画面.
  89.      *
  90.      * @Route("/auctions/list", name="auction_list", methods={"GET"})
  91.      *
  92.      * @Template("Auction/list.twig")
  93.      */
  94.     public function index(Request $requestPaginatorInterface $paginator)
  95.     {
  96.         if ($this->isGranted('ROLE_USER')) {
  97.             // handleRequestは空のqueryの場合は無視するため
  98.             if ($request->getMethod() === 'GET') {
  99.                 $request->query->set('pageno'$request->query->get('pageno'''));
  100.             }
  101.             // searchForm
  102.             /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
  103.             $builder $this->formFactory->createNamedBuilder(''SearchAuctionType::class);
  104.             if ($request->getMethod() === 'GET') {
  105.                 $builder->setMethod('GET');
  106.             }
  107.             $event = new EventArgs(
  108.                 [
  109.                     'builder' => $builder,
  110.                 ],
  111.                 $request
  112.             );
  113.             $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_AUCTION_INDEX_INITIALIZE);
  114.             /* @var $searchForm \Symfony\Component\Form\FormInterface */
  115.             $searchForm $builder->getForm();
  116.             $searchForm->handleRequest($request);
  117.             // paginator
  118.             $searchData $searchForm->getData();
  119.             $qb $this->auctionRepository->getQueryBuilderBySearchData($searchData);
  120.             $event = new EventArgs(
  121.                 [
  122.                     'searchData' => $searchData,
  123.                     'qb' => $qb,
  124.                 ],
  125.                 $request
  126.             );
  127.             $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_AUCTION_INDEX_SEARCH);
  128.             $searchData $event->getArgument('searchData');
  129.             $query $qb->getQuery()
  130.                 ->useResultCache(true$this->eccubeConfig['eccube_result_cache_lifetime_short']);
  131.             /** @var SlidingPagination $pagination */
  132.             $pagination $paginator->paginate(
  133.                 $query,
  134.                 ! empty($searchData['pageno']) ? $searchData['pageno'] : 1,
  135.                 ! empty($searchData['disp_number']) ? $searchData['disp_number'] : 20
  136.             );
  137.             $Customer $this->getUser();
  138.             $auctionIds = [];
  139.             foreach ($pagination as $Auction) {
  140.                 $auctionIds[] = $Auction->getId();
  141.             }
  142.             $productCounts $this->auctionRepository->countDisplayProductsForAuctions($auctionIds);
  143.             return [
  144.                 'subtitle' => 'オークション一覧',
  145.                 'pagination' => $pagination,
  146.                 'search_form' => $searchForm->createView(),
  147.                 'Customer' => $Customer,
  148.                 'productCounts' => $productCounts,
  149.             ];
  150.         } else {
  151.             // 非会員の場合、ログイン画面を表示
  152.             return $this->redirectToRoute('mypage_login');
  153.         }
  154.     }
  155.     /**
  156.      * オークション詳細画面.
  157.      *
  158.      * @Route("/auctions/detail/{id}", name="auction_detail", methods={"GET"}, requirements={"id" = "\d+"})
  159.      *
  160.      * @Template("Auction/detail.twig")
  161.      *
  162.      * @return array
  163.      */
  164.     public function detail(Request $requestAuction $AuctionPaginatorInterface $paginator)
  165.     {
  166.         if ($this->isGranted('ROLE_USER')) {
  167.             $Customer $this->getUser();
  168.             if (! $this->checkVisibility($Auction)) {
  169.                 throw new NotFoundHttpException();
  170.             }
  171.             if ($Auction->isBefore() && !$Customer->getIsAdmin()) {
  172.                 throw new NotFoundHttpException();
  173.             }
  174.             // handleRequestは空のqueryの場合は無視するため
  175.             if ($request->getMethod() === 'GET') {
  176.                 $request->query->set('pageno'$request->query->get('pageno'''));
  177.                 $request->query->set('orderby'$request->query->get('orderby'3));
  178.             }
  179.             // searchForm
  180.             /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
  181.             $builder $this->formFactory->createNamedBuilder(''SearchProductType::class);
  182.             if ($request->getMethod() === 'GET') {
  183.                 $builder->setMethod('GET');
  184.             }
  185.             $event = new EventArgs(
  186.                 [
  187.                     'builder' => $builder,
  188.                 ],
  189.                 $request
  190.             );
  191.             $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_INDEX_INITIALIZE);
  192.             /* @var $searchForm \Symfony\Component\Form\FormInterface */
  193.             $searchForm $builder->getForm();
  194.             $searchForm->handleRequest($request);
  195.             // paginator
  196.             $searchData $searchForm->getData();
  197.             $searchData['auction_id'] = $Auction->getId();
  198.             $qb $this->productRepository->getQueryBuilderBySearchData($searchData);
  199.             $event = new EventArgs(
  200.                 [
  201.                     'searchData' => $searchData,
  202.                     'qb' => $qb,
  203.                 ],
  204.                 $request
  205.             );
  206.             $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_INDEX_SEARCH);
  207.             $searchData $event->getArgument('searchData');
  208.             $query $qb->getQuery()
  209.                 ->useResultCache(true$this->eccubeConfig['eccube_result_cache_lifetime_short']);
  210.             /** @var SlidingPagination $pagination */
  211.             $pagination $paginator->paginate(
  212.                 $query,
  213.                 ! empty($searchData['pageno']) ? $searchData['pageno'] : 1,
  214.                 ! empty($searchData['disp_number']) ? $searchData['disp_number'] : 20
  215.             );
  216.             // 下見期間かどうか
  217.             $is_preview $Auction->isPreview();
  218.             // 競り後かどうか
  219.             $is_closed $Auction->isClosed();
  220.             // 訂正リストの有無
  221.             $has_correction_list = ! empty($Auction->getCorrectionListProducts());
  222.             $Products $this->productRepository->getTotalProductsForAuction($Auction->getId());
  223.             $biddingCompaniesCounts = [];
  224.             $productIds array_map(function ($Product) {
  225.                 return $Product->getId();
  226.             }, $Products);
  227.             if ($is_closed) {
  228.                 $biddingCompaniesResults $this->bitHistoryRepository->countBiddingCompaniesForProducts($productIds);
  229.             } else {
  230.                 $biddingCompaniesResults $this->productRepository->countBiddingCompaniesForProducts($productIds);
  231.             }
  232.             foreach ($biddingCompaniesResults as $result) {
  233.                 $biddingCompaniesCounts[$result['productId']] = $result['count'];
  234.             }
  235.             foreach ($pagination as $Product) {
  236.                 // もし結果が存在しない場合は 0 をセット
  237.                 $biddingCompaniesCounts[$Product->getId()] = $biddingCompaniesCounts[$Product->getId()] ?? 0;
  238.             }
  239.             $isUnpaid = !empty($this->orderRepository->getNotPaidOrder($Customer)) ? true false;
  240.             return [
  241.                 'title' => $this->title,
  242.                 'subtitle' => $Auction->getName(),
  243.                 'Auction' => $Auction,
  244.                 'auctionId' => $Auction->getId(),
  245.                 'pagination' => $pagination,
  246.                 'search_form' => $searchForm->createView(),
  247.                 'Customer' => $Customer,
  248.                 'is_preview' => $is_preview,
  249.                 'is_closed' => $is_closed,
  250.                 'has_correction_list' => $has_correction_list,
  251.                 'biddingCompaniesCounts' => $biddingCompaniesCounts,
  252.                 'isUnpaid' => $isUnpaid
  253.             ];
  254.         } else {
  255.             // 非会員の場合、ログイン画面を表示
  256.             //  ログイン後の画面遷移先を設定
  257.             $this->setLoginTargetPath($this->generateUrl('auction_detail', ['id' => $Auction->getId()], UrlGeneratorInterface::ABSOLUTE_URL));
  258.             return $this->redirectToRoute('mypage_login');
  259.         }
  260.     }
  261.     /**
  262.      * 競り中画面.
  263.      *
  264.      * @Route("/starting_auctions/detail/{id}", name="starting_auction_detail", methods={"GET"}, requirements={"id" = "\d+"})
  265.      *
  266.      * @Template("Product/starting_detail.twig")
  267.      *
  268.      * @return array
  269.      */
  270.     public function startingDetail(Request $requestAuction $Auction)
  271.     {
  272.         if ($this->isGranted('ROLE_USER')) {
  273.             if (! $this->checkVisibility($Auction)) {
  274.                 throw new NotFoundHttpException();
  275.             }
  276.             $Customer $this->getUser();
  277.             $Products $this->productRepository->getProductsSortedByAuctionNo($Auction->getId());
  278.             $ProductsCount count($this->productRepository->getTotalProductsForAuction($Auction->getId()));
  279.             $firstProductId = !empty($Products) ? $Products[0]['id'] : 0;
  280.             
  281.             $nextProductImages = [];
  282.             $auctionNos array_map(function ($Product) {
  283.                 return $Product->getAuctionNo();
  284.             }, $Products);
  285.             if (!empty($auctionNos)) {
  286.                 $minAuctionNo min($auctionNos);
  287.                 $nextProducts $this->productRepository->findNextProducts($Auction->getId(), $minAuctionNo);
  288.                 foreach ($Products as $Product) {
  289.                     $filteredProducts array_filter($nextProducts, function($nextProduct) use ($Product) {
  290.                         return $nextProduct->getAuctionNo() > $Product->getAuctionNo();
  291.                     });
  292.                 
  293.                     // 2件だけ取得
  294.                     $nextProductImages[$Product->getId()] = array_slice($filteredProducts02);
  295.                 }
  296.             };
  297.             $productIds array_map(function ($Product) {
  298.                 return $Product->getId();
  299.             }, $Products);
  300.             $biddingCompaniesCounts = [];
  301.             $biddingCompaniesResults $this->productRepository->countBiddingCompaniesForProducts($productIds);
  302.             foreach ($biddingCompaniesResults as $result) {
  303.                 $biddingCompaniesCounts[$result['productId']] = $result['count'];
  304.             }
  305.             $isFavorites = [];
  306.             $favorites $this->customerFavoriteProductRepository->getFavoritesForCustomer($Customer$productIds);
  307.             foreach ($Products as $Product) {
  308.                 $isFavorites[$Product->getId()] = in_array($Product->getId(), $favorites);
  309.             }
  310.             $startPrices = [];
  311.             $startPricesResults $this->productRepository->getStartPrices($productIds);
  312.             foreach ($startPricesResults as $result) {
  313.                 $startPrices[$result['productId']] =  number_format($result['startPrice']);
  314.             }
  315.             
  316.             $limitPrices = [];
  317.             $settingPersents = [];
  318.             $canBids = [];
  319.             $isOwns = [];
  320.             foreach ($Products as $Product) {
  321.                 $limitPrices[$Product->getId()] = $Product->getLimitPrice();
  322.                 $settingPersents[$Product->getId()] = $Product->getSettingPersent();
  323.                 $canBids[$Product->getId()] = $Product->getTenderPrice($Customer) != && $Product->getNowPrice() == $Product->getTenderPrice($Customer) ? false true;
  324.                 $isOwns[$Product->getId()] = $Product->getCustomer() == $Customer true false;
  325.             }
  326.             $randomBytes random_bytes(32);
  327.             $token hash('sha256'$randomBytes);
  328.             $hashedToken hash('sha256'$token);
  329.             $Customer->setToken($hashedToken);
  330.             $this->entityManager->persist($Customer);
  331.             $this->entityManager->flush();
  332.             $socketHostUrl getenv('SOCKET_HOST_URL');
  333.             $isUnpaid = !empty($this->orderRepository->getNotPaidOrder($Customer)) ? true false;
  334.             // 競り後かどうか
  335.             $is_closed $Auction->isClosed();
  336.             return [
  337.                 'title' => $this->title,
  338.                 'Auction' => $Auction,
  339.                 'Products' => $Products,
  340.                 'limitPrices' => json_encode($limitPrices),
  341.                 'settingPersents' => json_encode($settingPersents),
  342.                 'nextProductImages' => $nextProductImages,
  343.                 'token' => $token,
  344.                 'Customer' => $Customer,
  345.                 'isFavorites' => $isFavorites,
  346.                 'biddingCompaniesCounts' => $biddingCompaniesCounts,
  347.                 'canBids' => json_encode($canBids),
  348.                 'isOwns' => json_encode($isOwns),
  349.                 'startPrices' => json_encode($startPrices),
  350.                 'socketHostUrl' => $socketHostUrl,
  351.                 'ProductsCount' => $ProductsCount,
  352.                 'isUnpaid' => $isUnpaid,
  353.                 'is_closed' => $is_closed,
  354.                 'firstProductId' => $firstProductId
  355.             ];
  356.         } else {
  357.             // 非会員の場合、ログイン画面を表示
  358.             return $this->redirectToRoute('mypage_login');
  359.         }
  360.     }
  361.     /**
  362.      * お気に入り追加.
  363.      *
  364.      * @Route("/auctions/add_favorite/{id}", name="auction_add_favorite", requirements={"id" = "\d+"}, methods={"GET", "POST"})
  365.      */
  366.     public function addFavorite(Request $requestAuction $Auction)
  367.     {
  368.         $this->checkVisibility($Auction);
  369.         $event = new EventArgs(
  370.             [
  371.                 'Auction' => $Auction,
  372.             ],
  373.             $request
  374.         );
  375.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_AUCTION_FAVORITE_ADD_INITIALIZE);
  376.         if ($this->isGranted('ROLE_USER')) {
  377.             $Customer $this->getUser();
  378.             $this->customerFavoriteAuctionRepository->addFavorite($Customer$Auction);
  379.             $this->session->getFlashBag()->set('auction_detail.just_added_favorite'$Auction->getId());
  380.             $event = new EventArgs(
  381.                 [
  382.                     'Auction' => $Auction,
  383.                 ],
  384.                 $request
  385.             );
  386.             $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_AUCTION_FAVORITE_ADD_COMPLETE);
  387.             return $this->redirect($_SERVER['HTTP_REFERER']);
  388.         } else {
  389.             // 非会員の場合、ログイン画面を表示
  390.             //  ログイン後の画面遷移先を設定
  391.             $this->setLoginTargetPath($_SERVER['HTTP_REFERER']);
  392.             $this->session->getFlashBag()->set('eccube.add.favorite'true);
  393.             $event = new EventArgs(
  394.                 [
  395.                     'Auction' => $Auction,
  396.                 ],
  397.                 $request
  398.             );
  399.             $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_AUCTION_FAVORITE_ADD_COMPLETE);
  400.             return $this->redirectToRoute('mypage_login');
  401.         }
  402.     }
  403.     /**
  404.      * お気に入り削除.
  405.      *
  406.      * @Route("/auctions/remove_favorite/{id}", name="auction_remove_favorite", requirements={"id" = "\d+"}, methods={"GET", "POST"})
  407.      */
  408.     public function removeFavorite(Request $requestAuction $Auction)
  409.     {
  410.         if ($this->isGranted('ROLE_USER')) {
  411.             $Customer $this->getUser();
  412.             $CustomerFavoriteAuction $this->customerFavoriteAuctionRepository->findOneBy(['Customer' => $Customer'Auction' => $Auction]);
  413.             if ($CustomerFavoriteAuction) {
  414.                 $this->customerFavoriteAuctionRepository->delete($CustomerFavoriteAuction);
  415.             } else {
  416.                 throw new BadRequestHttpException();
  417.             }
  418.             $event = new EventArgs(
  419.                 [
  420.                     'Customer' => $Customer,
  421.                     'CustomerFavoriteAuction' => $CustomerFavoriteAuction,
  422.                 ],
  423.                 $request
  424.             );
  425.             $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_AUCTION_FAVORITE_REMOVE_COMPLETE);
  426.             return $this->redirect($_SERVER['HTTP_REFERER']);
  427.         } else {
  428.             // 非会員の場合、ログイン画面を表示
  429.             return $this->redirectToRoute('mypage_login');
  430.         }
  431.     }
  432.     /**
  433.      * オークションのstart_date/end_dateを登録
  434.      *
  435.      * @Route("/auctions/register_date/{id}", name="register_date", requirements={"id" = "\d+"}, methods={"GET", "POST"})
  436.      */
  437.     public function registerDate(Request $requestAuction $Auction) {
  438.         if ($request->request->get('type') == 'start') {
  439.             $Auction->setStartDate(new \DateTime());
  440.         } else {
  441.             $Auction->setEndDate(new \DateTime());
  442.         }
  443.         $this->entityManager->flush();
  444.         return $this->json(['done' => true]);
  445.     }
  446.     /**
  447.      * 開催中のオークションを取得
  448.      *
  449.      * @Route("/auctions/start_auction_list", name="start_auction_list", methods={"GET", "POST"})
  450.      */
  451.     public function startAuctionList(Request $request) {
  452.         $startAuction $this->auctionRepository->getStartAuction();
  453.         return $this->json(json_encode($startAuction));
  454.     }
  455.     protected function getPageTitle($searchData)
  456.     {
  457.         if (isset($searchData['name']) && ! empty($searchData['name'])) {
  458.             return trans('front.auction.search_result');
  459.         } elseif (isset($searchData['category_id']) && $searchData['category_id']) {
  460.             return $searchData['category_id']->getName();
  461.         } else {
  462.             return trans('front.auction.all_auctions');
  463.         }
  464.     }
  465.     /**
  466.      * 閲覧可能なオークションかどうかを判定
  467.      *
  468.      *
  469.      * @return bool 閲覧可能な場合はtrue
  470.      */
  471.     protected function checkVisibility(Auction $Auction)
  472.     {
  473.         $is_admin $this->session->has('_security_admin');
  474.         // 管理ユーザの場合はステータスやオプションにかかわらず閲覧可能.
  475.         if (! $is_admin) {
  476.             // 公開ステータスでない商品は表示しない.
  477.             if ($Auction->getStatus()->getId() !== AuctionStatus::DISPLAY_SHOW) {
  478.                 return false;
  479.             }
  480.         }
  481.         return true;
  482.     }
  483. }