app/Plugin/ProductOption4/ProductOptionEvent.php line 443

Open in your IDE?
  1. <?php
  2. /**
  3.  * Created by PhpStorm.
  4.  * User: hls
  5.  * Date: 2019-08-02
  6.  * Time: 15:31
  7.  */
  8. namespace Plugin\ProductOption4;
  9. use Doctrine\Common\Collections\ArrayCollection;
  10. use Doctrine\ORM\EntityManager;
  11. use Eccube\Application;
  12. use Eccube\Entity\Delivery;
  13. use Eccube\Entity\Order;
  14. use Eccube\Entity\OrderItem;
  15. use Eccube\Entity\Product;
  16. use Eccube\Event\EccubeEvents;
  17. use Eccube\Event\EventArgs;
  18. use Eccube\Event\TemplateEvent;
  19. use Eccube\Form\Type\Admin\OrderType;
  20. use Eccube\Form\Type\Admin\SearchProductType;
  21. use Eccube\Repository\BaseInfoRepository;
  22. use Eccube\Repository\Master\ProductStatusRepository;
  23. use Eccube\Service\CartService;
  24. use Eccube\Service\OrderHelper;
  25. use Eccube\Service\PurchaseFlow\PurchaseFlow;
  26. use Plugin\ProductOption4\Entity\ProductOptionCategory;
  27. use Plugin\ProductOption4\Entity\ProductOptionName;
  28. use Plugin\ProductOption4\Entity\ProductOptionOrderItemGroup;
  29. use Plugin\ProductOption4\Entity\ProductOptionShoppingCartItemGroup;
  30. use Plugin\ProductOption4\Events\CartEvent;
  31. use Plugin\ProductOption4\Events\ShoppingEvent;
  32. use Plugin\ProductOption4\Repository\ProductOptionCategoryRepository;
  33. use Plugin\ProductOption4\Repository\ProductOptionNameRepository;
  34. use Psr\Container\ContainerInterface;
  35. use Symfony\Bundle\TwigBundle\TwigEngine;
  36. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  37. use Symfony\Component\Form\FormFactory;
  38. use Symfony\Component\Form\FormFactoryBuilderInterface;
  39. use Symfony\Component\HttpFoundation\Request;
  40. use Symfony\Component\Serializer\SerializerInterface;
  41. use Plugin\ProductOption4\Service\MailService;
  42. class ProductOptionEvent implements EventSubscriberInterface
  43. {
  44.     /**
  45.      * @var ProductOptionNameRepository
  46.      */
  47.     protected $productOptionNameRepository;
  48.     /**
  49.      * @var CartService
  50.      */
  51.     protected $cartService;
  52.     private $app;
  53.     private $container;
  54.     protected $baseInfo;
  55.     protected $cartFlow;
  56.     protected $orderHelper;
  57.     /**
  58.      * @var EntityManager
  59.      */
  60.     protected $entityManager;
  61.     /**
  62.      * @var ProductOptionCategoryRepository
  63.      */
  64.     protected $productOptionCategoryRepository;
  65.     /**
  66.      * @var TwigEngine
  67.      */
  68.     protected $twigEngine;
  69.     /**
  70.      * @var Request
  71.      */
  72.     protected $request;
  73.     /**
  74.      * @var FormFactory
  75.      */
  76.     protected $formFactory;
  77.     /**
  78.      * @var SerializerInterface
  79.      */
  80.     protected $serializer;
  81.     /**
  82.      * @var MailService
  83.      */
  84.     protected $mailService;
  85.     public function __construct(ProductOptionCategoryRepository $productOptionCategoryRepository,
  86.                                 ProductOptionNameRepository $productOptionNameRepository,
  87.                                 Application $app,
  88.                                 ContainerInterface $container,
  89.                                 CartService $cartService,
  90.                                 BaseInfoRepository $baseInfoRepository,
  91.                                 PurchaseFlow $cartFlow,
  92.                                 OrderHelper $orderHelper,
  93.                                 FormFactory $formFactory,
  94.                                 SerializerInterface $serializer,
  95.                                 MailService $mailService
  96.     )
  97.     {
  98.         $this->productOptionCategoryRepository $productOptionCategoryRepository;
  99.         $this->productOptionNameRepository $productOptionNameRepository;
  100.         $this->app $app;
  101.         $this->container $container;
  102.         $this->cartService $cartService;
  103.         $this->baseInfo $baseInfoRepository->get();
  104.         $this->cartFlow $cartFlow;
  105.         $this->orderHelper $orderHelper;
  106.         $this->entityManager $this->container->get('doctrine.orm.entity_manager');
  107.         $this->twigEngine $this->container->get('templating');
  108.         $this->request $this->container->get('request_stack')->getMasterRequest();
  109.         $this->formFactory $formFactory;
  110.         $this->serializer $serializer;
  111.         $this->mailService $mailService;
  112.     }
  113.     /**
  114.      * @return array
  115.      */
  116.     public static function getSubscribedEvents()
  117.     {
  118.         return [
  119.             'Product/detail.twig' => 'productDetailEvent',
  120.             // // shopping cart page override
  121.             'Cart/index.twig' => 'twigFrontendCartIndexEvent',
  122.             // 'Shopping/index.twig' => 'twigFrontendShoppingIndexEvent',
  123.             'Block/cart.twig' => 'twigFrontendBlockCartEvent',
  124.             // 'Shopping/confirm.twig' => 'twigFrontendShoppingConfirm',
  125.             // My page order history
  126.             'Mypage/history.twig' => 'twigMypageHistory',
  127.             '@admin/Product/index.twig' => 'adminProductIndexTemplateEvent',
  128.             // override the admin product edit page, add the extra product edit option html
  129.             '@admin/Product/product.twig' => 'adminProductTemplateEvent',
  130.             '@admin/Product/csv_product.twig' => 'adminCsvProductTemplateEvent',
  131.             // backend order edit page override
  132.             '@admin/Order/edit.twig' => 'adminOrderEditTemplateEvent',
  133.             // override order export event
  134.             '@admin/Order/index.twig' => 'adminOrderIndexTemplateEvent',
  135.             // override export pdf
  136.             '@admin/Order/order_pdf.twig' => 'adminOrderPdfTemplateEvent',
  137.             EccubeEvents::ADMIN_PRODUCT_EDIT_COMPLETE => 'adminEditComplete',
  138.             EccubeEvents::FRONT_PRODUCT_CART_ADD_INITIALIZE => 'frontendCartAddInit',
  139.             // 添加产品后处理产品option
  140.             EccubeEvents::FRONT_PRODUCT_CART_ADD_COMPLETE => 'frontendCartAddComplete',
  141.             EccubeEvents::FRONT_SHOPPING_COMPLETE_INITIALIZE => 'frontendShoppingComplete',
  142.         ];
  143.     }
  144.     public function frontendCartAddInit(EventArgs $event)
  145.     {
  146.         $builder $event->getArgument('builder');
  147.         //$event->setArgument('builder', null);
  148.     }
  149.     /**
  150.      * Add product to cart, update the product option data
  151.      * @param EventArgs $event
  152.      */
  153.     public function frontendCartAddComplete(EventArgs $event)
  154.     {
  155.         $eventClass = new CartEvent($this->cartService$this->container$this->baseInfo);
  156.         $eventClass->frontendCartAddCompleteEvent($event);
  157.     }
  158.     /**
  159.      * User order history update the order total price
  160.      *
  161.      * @param EventArgs $event
  162.      * @throws \Doctrine\ORM\ORMException
  163.      * @throws \Doctrine\ORM\OptimisticLockException
  164.      */
  165.     public function frontendShoppingComplete(EventArgs $event)
  166.     {
  167.         $order $event->getArgument('Order');
  168.         $totalPlus $this->entityManager->getRepository(ProductOptionOrderItemGroup::class)->calculateProductOptionTotalPlus($order);
  169.         $order->setSubTotal($order->getSubTotal() + $totalPlus);
  170.         $order->setTotal($order->getTotal() + $totalPlus);
  171.         $order->setPaymentTotal($order->getPaymentTotal() + $totalPlus);
  172.         $this->entityManager->persist($order);
  173.         $this->entityManager->flush();
  174.         $productOptionOrderItemGroups $this->entityManager->getRepository(ProductOptionOrderItemGroup::class)
  175.             ->findBy(array(
  176.                 'order' => $order,
  177.             ));
  178.         // $this->mailService->sendOrderMail($order, $productOptionOrderItemGroups);
  179.         $this->entityManager->flush();
  180.         // remove all the product option data
  181.         // get product option cart groups
  182.         $cartOptionGroups $this->entityManager->getRepository(ProductOptionShoppingCartItemGroup::class)->findAll();
  183.         foreach ($cartOptionGroups as $og) {
  184.             foreach ($og->getProductOptionShoppingCartItems() as $it) {
  185.                 $this->entityManager->remove($it);
  186.             }
  187.             $this->entityManager->remove($og);
  188.         }
  189.         $this->entityManager->flush();
  190.     }
  191.     public function twigFrontendShoppingIndexEvent(TemplateEvent $event)
  192.     {
  193.         $eventClass = new ShoppingEvent($this->cartService$this->container$this->baseInfo);
  194.         $eventClass->twigFrontendShoppingIndexEvent($event$this->cartFlow$this->orderHelper);
  195.     }
  196.     public function twigFrontendBlockCartEvent(TemplateEvent $event) {
  197.         $event->setSource('abc');
  198.     }
  199.     public function twigFrontendShoppingConfirm(TemplateEvent $event)
  200.     {
  201.         $eventClass = new ShoppingEvent($this->cartService$this->container$this->baseInfo);
  202.         $eventClass->twigFrontendShoppingConfirm($event$this->cartFlow$this->orderHelper);
  203.     }
  204.     public function twigFrontendCartIndexEvent(TemplateEvent $event)
  205.     {
  206.         $eventClass = new CartEvent($this->cartService$this->container$this->baseInfo);
  207.         $eventClass->twigFrontendCartIndexEvent($event);
  208.     }
  209.     /**
  210.      * @param TemplateEvent $event
  211.      */
  212.     public function productDetailEvent(TemplateEvent $event)
  213.     {
  214.         $source $event->getSource();
  215.         #-- regex-replace an occurence by count
  216.         $productId $this->container->get('request_stack')->getMasterRequest()->get('id');
  217.         $template $this->container->get('templating');
  218.         $entityManager $this->container->get('doctrine.orm.entity_manager');
  219.         $product $entityManager->getRepository(Product::class)->find($productId);
  220.         $options $entityManager->getRepository(ProductOptionName::class)->getData($product);
  221.         if (count($options) === && count($options[0]['options']) === 0) {
  222.         } else {
  223.             $options $template->render('ProductOption4/Resource/template/default/product_options.twig', [
  224.                 'options' => $options,
  225.             ]);
  226.             $sourceUpdated str_replace('<div class="ec-numberInput">'$options '<div class="ec-numberInput">'$source);
  227.             $event->setSource($sourceUpdated);
  228.         }
  229.         $event->addSnippet('ProductOption4/Resource/template/default/snippet.twig');
  230.     }
  231.     /**
  232.      * @param TemplateEvent $event
  233.      */
  234.     public function adminProductIndexTemplateEvent(TemplateEvent $event)
  235.     {
  236.         $source $event->getSource();
  237.         $source str_replace('admin_product_export''admin_product_export_with_options'$source);
  238.         $source str_replace('admin_product_product_delete''admin_product_product_delete_with_option'$source);
  239.         $event->setSource($source);
  240.     }
  241.     /**
  242.      * @param TemplateEvent $event
  243.      */
  244.     public function adminProductTemplateEvent(TemplateEvent $event)
  245.     {
  246.         $source $event->getSource();
  247.         #-- regex-replace an occurence by count
  248.         $counter 1;
  249.         $s preg_replace_callback('/<div class="card rounded border-0 mb-4"/', function ($m) use (&$counter) {
  250.             #-- replacement for 2nd occurence of "abc"
  251.             if ($counter++ == 3) {
  252.                 return $this->getProductOptionSnipet() . '<div class="card rounded border-0 mb-4"';
  253.             }
  254.             #-- else leave current match
  255.             return $m[0];
  256.         }, $source);
  257.         $event->setSource($s);
  258.         /** @var Product $Product */
  259.         $event->addSnippet('@ProductOption4/admin/js.twig');
  260.         $parameters $event->getParameters();
  261.         $parameters['params'] = [];
  262.         $event->setParameters($parameters);
  263.     }
  264.     /**
  265.      * @param TemplateEvent $event
  266.      */
  267.     public function adminCsvProductTemplateEvent(TemplateEvent $event)
  268.     {
  269.         $source $event->getSource();
  270.         $s str_replace('admin_product_csv_import''admin_product_import_with_options'$source);
  271.         $event->setSource($s);
  272.     }
  273.     /**
  274.      * @param TemplateEvent $event
  275.      */
  276.     public function adminOrderEditTemplateEvent(TemplateEvent $event)
  277.     {
  278.         $TargetOrder null;
  279.         $OriginOrder null;
  280.         $id $this->request->get('id'null);
  281.         if (null === $id) {
  282.             return;
  283.             // 空のエンティティを作成.
  284.             $TargetOrder = new Order();
  285.             $TargetOrder->addShipping((new Shipping())->setOrder($TargetOrder));
  286.             $preOrderId $this->orderHelper->createPreOrderId();
  287.             $TargetOrder->setPreOrderId($preOrderId);
  288.         } else {
  289.             $TargetOrder $this->entityManager->getRepository(Order::class)->find($id);
  290.             if (null === $TargetOrder) {
  291.                 throw new NotFoundHttpException();
  292.             }
  293.         }
  294.         // 編集前の受注情報を保持
  295.         $OriginOrder = clone $TargetOrder;
  296.         $OriginItems = new ArrayCollection();
  297.         foreach ($TargetOrder->getOrderItems() as $Item) {
  298.             $OriginItems->add($Item);
  299.         }
  300.         // get the product option items
  301.         $productOptionOrderItemGroups $this->entityManager->getRepository(ProductOptionOrderItemGroup::class)
  302.             ->findBy(array(
  303.                 'order' => $TargetOrder,
  304.             ));
  305.         $builder $this->formFactory->createBuilder(OrderType::class, $TargetOrder);
  306.         $form $builder->getForm();
  307.         $form->handleRequest($this->request);
  308.         $searchCustomerModalForm $builder->getForm();
  309.         // 商品検索フォーム
  310.         $builder $this->formFactory
  311.             ->createBuilder(SearchProductType::class);
  312.         $searchProductModalForm $builder->getForm();
  313.         // 配送業者のお届け時間
  314.         $times = [];
  315.         $deliveries $this->entityManager->getRepository(Delivery::class)->findAll();
  316.         foreach ($deliveries as $Delivery) {
  317.             $deliveryTimes $Delivery->getDeliveryTimes();
  318.             foreach ($deliveryTimes as $DeliveryTime) {
  319.                 $times[$Delivery->getId()][$DeliveryTime->getId()] = $DeliveryTime->getDeliveryTime();
  320.             }
  321.         }
  322.         $data = [
  323.             'form' => $form->createView(),
  324.             'searchCustomerModalForm' => $searchCustomerModalForm->createView(),
  325.             'searchProductModalForm' => $searchProductModalForm->createView(),
  326.             'Order' => $TargetOrder,
  327.             'id' => $id,
  328.             'shippingDeliveryTimes' => $this->serializer->serialize($times'json'),
  329.             'productOptionOrderItemGroups' => $productOptionOrderItemGroups,
  330.         ];
  331.         $source $this->twigEngine->render('@ProductOption4/admin/order_edit.twig'$data);
  332.         $event->setSource($source);
  333.     }
  334.     public function adminEditComplete(EventArgs $event) {
  335.         $product $event->getArgument('Product');
  336.         $request $event->getRequest();
  337.         $allRequestData $request->request->all();
  338.         $optionGroups = isset($allRequestData['optionGroup']) ? $allRequestData['optionGroup'] : null;
  339.         if ($optionGroups) {
  340.             $entityManager $this->container->get('doctrine.orm.entity_manager');
  341.             $productOptionNameRepo $entityManager->getRepository(ProductOptionName::class);
  342.             $productOptionNameRepo->resetProductOptionName($product);
  343.             $rank 1;
  344.             foreach ($optionGroups as $optionGroup) {
  345.                 $optionUid $optionGroup['optionName']['id'];
  346.                 $optionName $optionGroup['optionName']['name'];
  347.                 $isRequired = isset($optionGroup['optionName']['required']) ? $optionGroup['optionName']['required'] : 0;
  348.                 $productOptionName $productOptionNameRepo->findOneBy(['uid' => $optionUid]);
  349.                 if (!$productOptionName) {
  350.                     $productOptionName = new ProductOptionName();
  351.                 }
  352.                 $productOptionName->setUid($optionUid);
  353.                 $productOptionName->setName($optionName);
  354.                 $productOptionName->setRequired($isRequired);
  355.                 $productOptionName->setProduct($product);
  356.                 $productOptionName->setRank($rank);
  357.                 if (isset($optionGroup['option'])) {
  358.                     foreach ($optionGroup['option'] as $optionItemData) {
  359.                         $name $optionItemData['title'];
  360.                         $optionItem = new ProductOptionCategory();
  361.                         $optionItem->setName($name);
  362.                         $optionItem->setRank($rank);
  363.                         $visibleOption $optionItemData['visible'] == 'true' true false;
  364.                         $optionItem->setVisible($visibleOption);
  365.                         $optionItem->setPrice($optionItemData['price']);
  366.                         $optionItem->setProductOptionName($productOptionName);
  367.                         $optionItem->setCode($optionItemData['code']);
  368.                         $entityManager->persist($optionItem);
  369.                         $productOptionName->addProductOptionCategory($optionItem);
  370.                         $rank++;
  371.                     }
  372.                 }
  373.                 $entityManager->persist($productOptionName);
  374.             }
  375.             $entityManager->flush();
  376.         }
  377.     }
  378.     /**
  379.      * Insert the product option edit html here
  380.      * @return string
  381.      */
  382.     private function getProductOptionSnipet() {
  383.         return $this->twigEngine->render('ProductOption4/Resource/template/admin/option-form.twig', []);
  384.     }
  385.     public function twigMypageHistory(TemplateEvent $event) {
  386.         $orderNo $this->container->get('request_stack')->getMasterRequest()->get('order_no');
  387.         $Order $this->entityManager->getRepository(Order::class)->find($orderNo);
  388.         $this->entityManager->getFilters()
  389.             ->enable('incomplete_order_status_hidden');
  390.         $stockOrder true;
  391.         foreach ($Order->getOrderItems() as $orderItem) {
  392.             if ($orderItem->isProduct() && $orderItem->getQuantity() < 0) {
  393.                 $stockOrder false;
  394.                 break;
  395.             }
  396.         }
  397.         $productOptionOrderItemGroups $this->entityManager->getRepository(ProductOptionOrderItemGroup::class)
  398.             ->findBy(array(
  399.                 'order' => $Order,
  400.             ));
  401.         if (count($productOptionOrderItemGroups) === 0) {
  402.             return;
  403.         }
  404.         $data =  [
  405.             'Order' => $Order,
  406.             'stockOrder' => $stockOrder,
  407.             'productOptionOrderItemGroups' => $productOptionOrderItemGroups,
  408.         ];
  409.         $source $this->twigEngine->render('ProductOption4/Resource/template/default/history.twig'$data);
  410.         $event->setSource($source);
  411.     }
  412.     /**
  413.      * Override the order index template
  414.      *
  415.      * @param TemplateEvent $event
  416.      */
  417.     public function adminOrderIndexTemplateEvent(TemplateEvent $event) {
  418.         // original twig template path
  419.         // src/Eccube/Resource/template/admin/Order/index.twig
  420.         $source $event->getSource();
  421.         // update the order export to new export route
  422.         $s str_replace('admin_order_export_order''admin_order_export_order_with_option'$source);
  423.         // update to new route for export shipping
  424.         $s str_replace('admin_order_export_shipping''admin_order_export_shipping_order_with_option'$s);
  425.         // update the email preview route
  426.         $s str_replace('admin_shipping_preview_notify_mail''admin_shipping_preview_notify_mail_with_option'$s);
  427.         $s str_replace('admin_shipping_notify_mail''admin_shipping_notify_mail_with_option'$s);
  428.         $event->setSource($s);
  429.     }
  430.     /**
  431.      * Override the order index template
  432.      *
  433.      * @param TemplateEvent $event
  434.      */
  435.     public function adminOrderPdfTemplateEvent(TemplateEvent $event) {
  436.         // original twig template path
  437.         // src/Eccube/Resource/template/admin/Order/order_pdf.twig
  438.         $source $event->getSource();
  439.         $s str_replace('admin_order_pdf_download''admin_order_pdf_download_with_option'$source);
  440.         $event->setSource($s);
  441.     }
  442. }