<?php
/*
* This file is part of EC-CUBE
*
* Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
*
* http://www.ec-cube.co.jp/
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Customize\Controller;
use Eccube\Entity\Product;
use Eccube\Event\EccubeEvents;
use Eccube\Event\EventArgs;
use Eccube\Form\Type\AddCartType;
use Eccube\Form\Type\SearchProductType;
use Eccube\Repository\BaseInfoRepository;
use Eccube\Repository\CustomerFavoriteProductRepository;
use Eccube\Repository\Master\ProductListMaxRepository;
use Eccube\Repository\ProductRepository;
use Eccube\Service\CartService;
use Eccube\Service\PurchaseFlow\PurchaseFlow;
use Knp\Component\Pager\PaginatorInterface;
use Plugin\PinpointSaleDx\Repository\ProductPinpointRepository;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class ProductController extends \Eccube\Controller\ProductController
{
/**
* @var PurchaseFlow
*/
protected $purchaseFlow;
/**
* @var CustomerFavoriteProductRepository
*/
protected $customerFavoriteProductRepository;
/**
* @var CartService
*/
protected $cartService;
/**
* @var ProductRepository
*/
protected $productRepository;
/**
* @var BaseInfo
*/
protected $BaseInfo;
/**
* @var AuthenticationUtils
*/
protected $helper;
/**
* @var ProductListMaxRepository
*/
protected $productListMaxRepository;
private $title = '';
protected ProductPinpointRepository $productPinpointRepository;
public function __construct(
ProductPinpointRepository $productPinpointRepository,
PurchaseFlow $cartPurchaseFlow,
CustomerFavoriteProductRepository $customerFavoriteProductRepository,
CartService $cartService,
ProductRepository $productRepository,
BaseInfoRepository $baseInfoRepository,
AuthenticationUtils $helper,
ProductListMaxRepository $productListMaxRepository
) {
$this->productPinpointRepository = $productPinpointRepository;
$this->purchaseFlow = $cartPurchaseFlow;
$this->customerFavoriteProductRepository = $customerFavoriteProductRepository;
$this->cartService = $cartService;
$this->productRepository = $productRepository;
$this->BaseInfo = $baseInfoRepository->get();
$this->helper = $helper;
$this->productListMaxRepository = $productListMaxRepository;
}
/**
* 商品一覧画面.
*
* @Route("/products/sale", name="product_sale", methods={"GET"})
* @Template("Product/sale.twig")
*/
public function index(Request $request, PaginatorInterface $paginator)
{
// Doctrine SQLFilter
if ($this->BaseInfo->isOptionNostockHidden()) {
$this->entityManager->getFilters()->enable('option_nostock_hidden');
}
// handleRequestは空のqueryの場合は無視するため
if ($request->getMethod() === 'GET') {
$request->query->set('pageno', $request->query->get('pageno', ''));
}
// searchForm
/* @var $builder \Symfony\Component\Form\FormBuilderInterface */
$builder = $this->formFactory->createNamedBuilder('', SearchProductType::class);
if ($request->getMethod() === 'GET') {
$builder->setMethod('GET');
}
$event = new EventArgs(
[
'builder' => $builder,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_PRODUCT_INDEX_INITIALIZE);
/* @var $searchForm \Symfony\Component\Form\FormInterface */
$searchForm = $builder->getForm();
$searchForm->handleRequest($request);
// paginator
$searchData = $searchForm->getData();
$qb = $this->productPinpointRepository->getQueryBuilderBySearchData($searchData);
$event = new EventArgs(
[
'searchData' => $searchData,
'qb' => $qb,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_PRODUCT_INDEX_SEARCH);
$searchData = $event->getArgument('searchData');
$query = $qb->getQuery()
->useResultCache(true, $this->eccubeConfig['eccube_result_cache_lifetime_short']);
/** @var SlidingPagination $pagination */
$pagination222 = $paginator->paginate(
$query,
!empty($searchData['pageno']) ? $searchData['pageno'] : 1,
!empty($searchData['disp_number']) ? $searchData['disp_number']->getId() : $this->productListMaxRepository->findOneBy([], ['sort_no' => 'ASC'])->getId(),
[
'wrap-queries' => true
]
);
$ids = [];
foreach ($pagination222 as $PinpointProduct) {
$ids[] = $PinpointProduct->getProductClass()->getProduct()->getId();
}
$ProductsAndClassCategories = $this->productRepository->findProductsWithSortedClassCategories($ids, 'p.id');
// addCart form
$forms = [];
foreach ($pagination222 as $PinpointProduct) {
$Product = $PinpointProduct->getProductClass()->getProduct();
/* @var $builder \Symfony\Component\Form\FormBuilderInterface */
$builder = $this->formFactory->createNamedBuilder(
'',
AddCartType::class,
null,
[
'product' => $ProductsAndClassCategories[$Product->getId()],
'allow_extra_fields' => true,
]
);
$addCartForm = $builder->getForm();
$forms[$Product->getId()] = $addCartForm->createView();
}
$Category = $searchForm->get('category_id')->getData();
return [
'subtitle' => $this->getPageTitle($searchData),
'pagination' => $pagination222,
'search_form' => $searchForm->createView(),
'forms' => $forms,
'Category' => $Category,
];
}
/**
* 商品一覧画面.
*
* @Route("/products/new", name="new_product", methods={"GET"})
* @Template("Product/new.twig")
*/
public function new(Request $request, PaginatorInterface $paginator)
{
// Doctrine SQLFilter
if ($this->BaseInfo->isOptionNostockHidden()) {
$this->entityManager->getFilters()->enable('option_nostock_hidden');
}
// handleRequestは空のqueryの場合は無視するため
if ($request->getMethod() === 'GET') {
$request->query->set('pageno', $request->query->get('pageno', ''));
}
// searchForm
/* @var $builder \Symfony\Component\Form\FormBuilderInterface */
$builder = $this->formFactory->createNamedBuilder('', SearchProductType::class);
if ($request->getMethod() === 'GET') {
$builder->setMethod('GET');
}
$event = new EventArgs(
[
'builder' => $builder,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_PRODUCT_INDEX_INITIALIZE);
/* @var $searchForm \Symfony\Component\Form\FormInterface */
$searchForm = $builder->getForm();
$searchForm->handleRequest($request);
// paginator
$searchData = $searchForm->getData();
$qb = $this->productRepository->getQueryBuilderBySearchData($searchData);
$event = new EventArgs(
[
'searchData' => $searchData,
'qb' => $qb,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_PRODUCT_INDEX_SEARCH);
$searchData = $event->getArgument('searchData');
$query = $qb->getQuery()
->useResultCache(true, $this->eccubeConfig['eccube_result_cache_lifetime_short']);
/** @var SlidingPagination $pagination */
$pagination = $paginator->paginate(
$query,
!empty($searchData['pageno']) ? $searchData['pageno'] : 1,
!empty($searchData['disp_number']) ? $searchData['disp_number']->getId() : $this->productListMaxRepository->findOneBy([], ['sort_no' => 'ASC'])->getId()
);
$ids = [];
foreach ($pagination as $Product) {
$ids[] = $Product->getId();
}
$ProductsAndClassCategories = $this->productRepository->findProductsWithSortedClassCategories($ids, 'p.id');
// addCart form
$forms = [];
foreach ($pagination as $Product) {
/* @var $builder \Symfony\Component\Form\FormBuilderInterface */
$builder = $this->formFactory->createNamedBuilder(
'',
AddCartType::class,
null,
[
'product' => $ProductsAndClassCategories[$Product->getId()],
'allow_extra_fields' => true,
]
);
$addCartForm = $builder->getForm();
$forms[$Product->getId()] = $addCartForm->createView();
}
$Category = $searchForm->get('category_id')->getData();
return [
'subtitle' => $this->getPageTitle($searchData),
'pagination' => $pagination,
'search_form' => $searchForm->createView(),
'forms' => $forms,
'Category' => $Category,
];
}
/**
* お気に入り追加.
*
* @Route("/products/add_favorite/{id}", name="product_add_favorite", requirements={"id" = "\d+"}, methods={"GET", "POST"})
*/
public function addFavorite(Request $request, Product $Product)
{
$this->checkVisibility($Product);
$event = new EventArgs(
[
'Product' => $Product,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_INITIALIZE);
if ($this->isGranted('ROLE_USER')) {
$Customer = $this->getUser();
$this->customerFavoriteProductRepository->addFavorite($Customer, $Product);
$this->session->getFlashBag()->set('product_detail.just_added_favorite', $Product->getId());
$event = new EventArgs(
[
'Product' => $Product,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_COMPLETE);
if ($request->isXmlHttpRequest()) {
return $this->json([
'done' => true
]);
} else {
return $this->redirectToRoute('product_detail', ['id' => $Product->getId()]);
}
} else {
// 非会員の場合、ログイン画面を表示
// ログイン後の画面遷移先を設定
$this->setLoginTargetPath($this->generateUrl('product_add_favorite', ['id' => $Product->getId()], UrlGeneratorInterface::ABSOLUTE_URL));
$this->session->getFlashBag()->set('eccube.add.favorite', true);
$event = new EventArgs(
[
'Product' => $Product,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_COMPLETE);
if ($request->isXmlHttpRequest()) {
return $this->json([
'done' => false
]);
} else {
return $this->redirectToRoute('mypage_login');
}
}
}
/**
* お気に入り商品を削除する.
*
* @Route("/product/favorite/{id}/delete", name="product_favorite_delete", methods={"DELETE"}, requirements={"id" = "\d+"})
*/
public function delete(Request $request, Product $Product)
{
$this->isTokenValid();
/** @var \Eccube\Entity\Customer $Customer */
$Customer = $this->getUser();
log_info('お気に入り商品削除開始', [$Customer->getId(), $Product->getId()]);
$CustomerFavoriteProduct = $this->customerFavoriteProductRepository->findOneBy(['Customer' => $Customer, 'Product' => $Product]);
if ($CustomerFavoriteProduct) {
$this->customerFavoriteProductRepository->delete($CustomerFavoriteProduct);
} else {
throw new BadRequestHttpException();
}
$event = new EventArgs(
[
'Customer' => $Customer,
'CustomerFavoriteProduct' => $CustomerFavoriteProduct,
], $request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_MYPAGE_MYPAGE_DELETE_COMPLETE);
log_info('お気に入り商品削除完了', [$Customer->getId(), $CustomerFavoriteProduct->getId()]);
if ($request->isXmlHttpRequest()) {
return $this->json([
"done" => true
]);
}
return $this->redirect($this->generateUrl('mypage_favorite'));
}
}