<?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\BaseInfo;
use Eccube\Entity\Master\ProductStatus;
use Eccube\Entity\Product;
use Eccube\Entity\Order;
use Eccube\Entity\OrderItem;
use Eccube\Entity\ProductClass;
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\Repository\OrderRepository;
use Eccube\Service\CartService;
use Eccube\Service\PurchaseFlow\PurchaseContext;
use Eccube\Service\PurchaseFlow\PurchaseFlow;
use Knp\Bundle\PaginatorBundle\Pagination\SlidingPagination;
use Knp\Component\Pager\PaginatorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Eccube\Controller\ProductController;
class ProductControllerCustomizer extends ProductController
{
/**
* @var OrderRepository
*/
protected $orderRepository;
/**
* ProductController constructor.
*
* @param PurchaseFlow $cartPurchaseFlow
* @param CustomerFavoriteProductRepository $customerFavoriteProductRepository
* @param CartService $cartService
* @param ProductRepository $productRepository
* @param BaseInfoRepository $baseInfoRepository
* @param AuthenticationUtils $helper
* @param ProductListMaxRepository $productListMaxRepository
* @param OrderRepository $orderRepository
*/
public function __construct(
PurchaseFlow $cartPurchaseFlow,
CustomerFavoriteProductRepository $customerFavoriteProductRepository,
CartService $cartService,
ProductRepository $productRepository,
BaseInfoRepository $baseInfoRepository,
AuthenticationUtils $helper,
ProductListMaxRepository $productListMaxRepository,
OrderRepository $orderRepository
) {
parent::__construct($cartPurchaseFlow,
$customerFavoriteProductRepository,
$cartService,
$productRepository,
$baseInfoRepository,
$helper,
$productListMaxRepository
);
$this->orderRepository = $orderRepository;
}
/**
* 商品一覧画面.
*
* @Route("/products/list", name="product_list", methods={"GET"})
* @Template("Product/list.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->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']);
/*$qb = $this->entityManager->getRepository('Eccube\Entity\Product')
->createQueryBuilder('p');
$qb->innerJoin('p.ProductTag', 'pt')
->innerJoin('pt.Tag', 't')
->andWhere('t = :Tag')
->setParameter('Tag', 17);*/
$query = $qb->getQuery()->getResult();
/** @var SlidingPagination $pagination */
$pagination = $paginator->paginate(
$query,
!empty($searchData['pageno']) ? $searchData['pageno'] : 1,
200
);
$Category = $searchForm->get('category_id')->getData();
/*
// ▼ボツの追加処理ここから
$is_admin = $this->session->has('_security_admin');
$period = '';
$Carts = $this->cartService->getCarts();
foreach ($Carts as $Cart) {
foreach ($Cart->getItems() as $item) {
$period = $item->getPeriod();
}
}
// 受注情報から、予約済みレンタル期間を取得 ←削除
$arrReserved = [];
$arrOrder = $this->orderRepository->findAll();
foreach ($pagination as $Product) {
$arrPeriod = [];
$product_id = $Product->getId();
foreach ($arrOrder as $order) {
if ($order->getOrderStatus() != '購入処理中' && $order->getOrderStatus() != '注文取消し') {
foreach ($order->getItems() as $item) {
$class = $item->getProductClass();
if ($class) {
if ($class->getProduct()->getId() == $product_id) {
$val = $item->getPeriod();
if ($val) {
$arrPeriod[] = $val;
}
}
}
}
}
}
// 商品情報から、貸出不可期間を取得
$invalidity_period = $Product->getInvalidityPeriod();
if ($invalidity_period) {
$arrPeriod[] = $invalidity_period;
}
$arrReserved[] = implode(';', $arrPeriod);
}
// ▲ボツの追加処理ここまで */
// 追加処理ここから
foreach ($pagination as $Product) {
if ($this->isGranted('ROLE_USER')) {
$Customer = $this->getUser();
$Product->setSearchWord($this->customerFavoriteProductRepository->isFavorite($Customer, $Product));
}
else {
$Product->setSearchWord('');
}
}
// 追加処理ここまで
return [
'subtitle' => $this->getPageTitle($searchData),
'pagination' => $pagination,
'search_form' => $searchForm->createView(),
//'forms' => $forms,
'Category' => $Category,
// ▼以下、追加
//'is_admin' => $is_admin,
//'period' => $period,
//'reserved' => implode('|', $arrReserved),
];
}
/**
* 商品詳細画面.
*
* @Route("/products/detail/{id}", name="product_detail", methods={"GET"}, requirements={"id" = "\d+"})
* @Template("Product/detail.twig")
* @ParamConverter("Product", options={"repository_method" = "findWithSortedClassCategories"})
*
* @param Request $request
* @param Product $Product
*
* @return array
*/
public function detail(Request $request, Product $Product)
{
if (!$this->checkVisibility($Product)) {
throw new NotFoundHttpException();
}
$builder = $this->formFactory->createNamedBuilder(
'',
AddCartType::class,
null,
[
'product' => $Product,
'id_add_product_id' => false,
]
);
$event = new EventArgs(
[
'builder' => $builder,
'Product' => $Product,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_PRODUCT_DETAIL_INITIALIZE);
$is_favorite = false;
if ($this->isGranted('ROLE_USER')) {
$Customer = $this->getUser();
$is_favorite = $this->customerFavoriteProductRepository->isFavorite($Customer, $Product);
}
// ▼追加処理ここから
$is_admin = $this->session->has('_security_admin');
$sale_type = '';
foreach ($Product->getProductClasses() as $ProductClass) {
$val = $ProductClass->getSaleType()->getId();
if ($val == 3 || $val == 4) {
$sale_type = 3;
}
}
$period = '';
$Carts = $this->cartService->getCarts();
foreach ($Carts as $Cart) {
foreach ($Cart->getItems() as $item) {
$period = $item->getPeriod();
}
}
// 受注情報から、予約済みレンタル期間を取得
$arrPeriod = [];
foreach ($this->orderRepository->findAll() as $order) {
if ($order->getOrderStatus() != '購入処理中' && $order->getOrderStatus() != '注文取消し') {
foreach ($order->getItems() as $item) {
$class = $item->getProductClass();
if ($class) {
//echo $order->getId();
if ($class->getProduct()->getId() == $Product->getId()) {
$val = $item->getPeriod();
if ($val) {
$vals = explode('|', $val);
$arrPeriod[] = $vals[0];
}
}
}
}
}
}
// 商品情報から、貸出不可期間を取得
$invalidity_period = $Product->getInvalidityPeriod();
if ($invalidity_period) {
$arrPeriod[] = $invalidity_period;
}
$user_status = 0;
if ($this->isGranted('ROLE_USER')) {
$user_status = $this->getUser()->getStatus()->getId();
}
// ▲追加処理ここまで
//var_dump($_SERVER['RENTAL_SETTING']);
return [
'title' => '',
'subtitle' => $Product->getName(),
'form' => $builder->getForm()->createView(),
'Product' => $Product,
'is_favorite' => $is_favorite,
// ▼以下、追加
'is_admin' => $is_admin,
'sale_type' => $sale_type,
'period' => $period,
'reserved' => implode(';', $arrPeriod),
'user_status' => $user_status,
'rental_setting' => $_SERVER['RENTAL_SETTING'],
];
}
/**
* カートに追加.
*
* @Route("/products/add_cart/{id}", name="product_add_cart", methods={"POST"}, requirements={"id" = "\d+"})
*/
public function addCart(Request $request, Product $Product)
{
// エラーメッセージの配列
$errorMessages = [];
if (!$this->checkVisibility($Product)) {
throw new NotFoundHttpException();
}
$builder = $this->formFactory->createNamedBuilder(
'',
AddCartType::class,
null,
[
'product' => $Product,
'id_add_product_id' => false,
]
);
$event = new EventArgs(
[
'builder' => $builder,
'Product' => $Product,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_PRODUCT_CART_ADD_INITIALIZE);
/* @var $form \Symfony\Component\Form\FormInterface */
$form = $builder->getForm();
$form->handleRequest($request);
if (!$form->isValid()) {
throw new NotFoundHttpException();
}
$addCartData = $form->getData();
log_info(
'カート追加処理開始',
[
'product_id' => $Product->getId(),
'product_class_id' => $addCartData['product_class_id'],
'quantity' => $addCartData['quantity'],
'period' => $addCartData['period'], // ▲コード追加
]
);
// カートへ追加
// ▼変更処理ここから
//$this->cartService->addProduct($addCartData['product_class_id'], $addCartData['quantity']);
$this->cartService->addCartItem($addCartData['product_class_id'], $addCartData['quantity'], [
'period' => $addCartData['period'],
]);
// ▲変更処理ここまで
// 明細の正規化
$Carts = $this->cartService->getCarts();
foreach ($Carts as $Cart) {
$result = $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart, $this->getUser()));
// 復旧不可のエラーが発生した場合は追加した明細を削除.
if ($result->hasError()) {
$this->cartService->removeProduct($addCartData['product_class_id']);
foreach ($result->getErrors() as $error) {
$errorMessages[] = $error->getMessage();
}
}
foreach ($result->getWarning() as $warning) {
$errorMessages[] = $warning->getMessage();
}
}
$this->cartService->save();
log_info(
'カート追加処理完了',
[
'product_id' => $Product->getId(),
'product_class_id' => $addCartData['product_class_id'],
'quantity' => $addCartData['quantity'],
]
);
$event = new EventArgs(
[
'form' => $form,
'Product' => $Product,
],
$request
);
$this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_PRODUCT_CART_ADD_COMPLETE);
if ($event->getResponse() !== null) {
return $event->getResponse();
}
if ($request->isXmlHttpRequest()) {
// ajaxでのリクエストの場合は結果をjson形式で返す。
// 初期化
$messages = [];
if (empty($errorMessages)) {
// エラーが発生していない場合
$done = true;
array_push($messages, trans('front.product.add_cart_complete'));
} else {
// エラーが発生している場合
$done = false;
$messages = $errorMessages;
}
return $this->json(['done' => $done, 'messages' => $messages]);
} else {
// ajax以外でのリクエストの場合はカート画面へリダイレクト
foreach ($errorMessages as $errorMessage) {
$this->addRequestError($errorMessage);
}
return $this->redirectToRoute('cart');
}
}
}