app/Plugin/SDream/EventSubscriber/ShoppingFlowSubscriber.php line 94

Open in your IDE?
  1. <?php
  2. /*
  3.     役割:最終チェック・進行可否判定
  4.             不定貫あり → 与信のみ
  5.             不定貫なし → 通常決済
  6. */
  7. namespace Plugin\SDream\EventSubscriber;
  8. use Eccube\Event\EccubeEvents;
  9. use Eccube\Event\EventArgs;
  10. use Eccube\Event\ShoppingFlowEvent;
  11. use Symfony\Component\HttpFoundation\RedirectResponse;
  12. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  13. use Symfony\Component\Routing\RouterInterface;
  14. use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
  15. use Plugin\SDream\Service\CustomerGuard;
  16. use Plugin\SDream\Service\ProductPurchaseRuleChecker;
  17. use Plugin\SDream\Service\PurchaseHistoryLimiter;
  18. use Plugin\SDream\Service\PaymentRestrictionService;
  19. use Psr\Log\LoggerInterface;
  20. use Symfony\Component\Security\Core\Security;
  21. use Eccube\Entity\Customer;
  22. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  23. use Eccube\Service\OrderHelper;
  24. use Doctrine\ORM\EntityManagerInterface;
  25. class ShoppingFlowSubscriber implements EventSubscriberInterface
  26. {
  27.     private Security $security;
  28.     private OrderHelper $orderHelper;
  29.     private CustomerGuard $customerGuard;
  30.     private ProductPurchaseRuleChecker $productPurchaseRuleChecker;
  31.     private PurchaseHistoryLimiter $purchaseHistoryLimiter;
  32.     private PaymentRestrictionService $paymentRestrictionService;
  33.     private FlashBagInterface $flashBag;
  34.     private RouterInterface $router;
  35.     private LoggerInterface $logger;
  36.     private EntityManagerInterface $em;
  37.     public function __construct(
  38.         Security $security,
  39.         OrderHelper $orderHelper,
  40.         CustomerGuard $customerGuard,
  41.         ProductPurchaseRuleChecker $productPurchaseRuleChecker,
  42.         PurchaseHistoryLimiter $purchaseHistoryLimiter,
  43.         PaymentRestrictionService $paymentRestrictionService,
  44.         FlashBagInterface $flashBag,
  45.         LoggerInterface $logger,
  46.         RouterInterface $router,
  47.         EntityManagerInterface $em
  48.     ) {
  49.         $this->security $security;
  50.         $this->orderHelper $orderHelper;
  51.         $this->customerGuard $customerGuard;
  52.         $this->productPurchaseRuleChecker $productPurchaseRuleChecker;
  53.         $this->purchaseHistoryLimiter $purchaseHistoryLimiter;
  54.         $this->paymentRestrictionService $paymentRestrictionService;
  55.         $this->flashBag $flashBag;
  56.         $this->logger $logger;
  57.         $this->router $router;
  58.         $this->em $em;
  59.     }
  60.     
  61.     private function getCurrentCustomer(): ?Customer
  62.     {
  63.         $user $this->security->getUser();
  64.         return $user instanceof Customer $user null;
  65.     }
  66.     public static function getSubscribedEvents(): array
  67.     {
  68.         return [
  69.             EccubeEvents::FRONT_SHOPPING_INDEX_INITIALIZE => 'onConIndexInitialilze',
  70.             EccubeEvents::FRONT_SHOPPING_CONFIRM_INITIALIZE => 'onConfirmInitialilze',
  71.             EccubeEvents::FRONT_SHOPPING_CONFIRM_PROCESSING => 'onConfirmProcessing',
  72.             EccubeEvents::FRONT_SHOPPING_COMPLETE_INITIALIZE => 'onCompleteInit',
  73.         ];
  74.     }
  75.     public function onConIndexInitialilze(EventArgs $event): void
  76.     {
  77.         //デバッグ用 26.02.16時点イベント反応なし(ここは通らない 他のプラグインなどカスタマイズも影響している)
  78.         $this->logger->info('onConIndexInitialilze called (test log)FRONT_SHOPPING_INDEX_INITIALIZE');
  79.     }
  80.     public function onConfirmInitialilze(EventArgs $event): void
  81.     {
  82.         //デバッグ用 26.02.16時点イベント反応なし(ここは通らない 他のプラグインなどカスタマイズも影響している)
  83.         $this->logger->info('onConfirmInitialilze called (test log)FRONT_SHOPPING_CONFIRM_INITIALIZE');
  84.     }
  85.     public function onCompleteInit(EventArgs $event): void
  86.     {
  87.         //デバッグ用
  88.         //$this->logger->info('route name: '.$event->getRequest()->attributes->get('_route'));
  89.         //$this->logger->info('onCompleteInit called (test log)FRONT_SHOPPING_COMPLETE_INITIALIZE');
  90.         $Order $event->getArgument('Order');
  91.         if (!$Order) {
  92.             return;
  93.         }
  94.         //確認用
  95.         /*
  96.         $this->logger->info('[ShoppingFlow] payment validate start', [
  97.             'order_id' => $Order->getId(),
  98.             'payment' => $Order->getPayment()
  99.                         ? $Order->getPayment()->getMethodClass()
  100.                         : null,
  101.         ]);
  102.         */
  103.         //チェックする
  104.         $errors = [];
  105.         //ログインユーザー
  106.         $Customer =
  107.             $this->getCurrentCustomer() ?: $this->orderHelper->getNonMember();
  108.         //1.会員状態・会員区分チェック
  109.         try {
  110.             $this->customerGuard->assertPurchasable($Customer);
  111.         } catch (AccessDeniedException $e) {
  112.             $this->logger->warning('[PurchaseBlock] customerGuard failed', [
  113.                 'customer_id' => $Customer $Customer->getId() : null,
  114.                 'message' => $e->getMessage(),
  115.             ]);
  116.             $errors[] = $e->getMessage();
  117.         }
  118.         /*
  119.          * 2.決済許可確認
  120.          *      不定貫 + ペイド決済 NG
  121.          * 3.商品 × 会員 × 決済制御
  122.          * 4.再購入制限
  123.          */
  124.         $errors array_merge(
  125.             $errors,
  126.             $this->paymentRestrictionService->assertPaymentAllowed($Order),
  127.             $this->productPurchaseRuleChecker->assertPurchasable($Order),
  128.             $this->purchaseHistoryLimiter->assertNotLimited($Order)
  129.         );
  130.         
  131.         if (!empty($errors)) {
  132.             $this->logger->info('[PurchaseBlock] order blocked before complete', [
  133.                 'order_id' => $Order->getId(),
  134.                 'customer_id' => $Customer $Customer->getId() : null,
  135.                 'errors' => $errors,
  136.             ]);
  137.             foreach ($errors as $message) {
  138.                 $this->flashBag->add(
  139.                     'eccube.front.cart.error',
  140.                     $message
  141.                 );
  142.             }
  143.             // 先に「進ませない」           
  144.             $event->setResponse(
  145.                 new RedirectResponse($this->router->generate('shopping'))
  146.             );
  147.             return;
  148.         }
  149.         /*
  150.             ここから「正常注文のみ」の処理
  151.             ★★★余計な変更をしないように注意★★★
  152.             ★★★決済前なので不定貫属性以外は変えない!★★★
  153.             ★★★Paymentを変更したりしない★★★
  154.         */
  155.         // 不定貫判定
  156.         $hasVariable false;
  157.         foreach ($Order->getOrderItems() as $item) {
  158.             $pc $item->getProductClass();
  159.             if (!$pc) {
  160.                 continue;
  161.             }
  162.             $product method_exists($pc'getProduct') ? $pc->getProduct() : null;
  163.             if (!$product) {
  164.                 continue;
  165.             }
  166.             // ProductTrait のプロパティ firmvariableattribute を getter で持っている前提
  167.             if (method_exists($product'getFirmvariableattribute')) {
  168.                 $flag = (int) $product->getFirmvariableattribute(); // 1なら不定貫
  169.                 if ($flag === 1) {
  170.                     $hasVariable true;
  171.                     break;
  172.                 }
  173.             }
  174.         }
  175.         $Order->setHasVariableWeight($hasVariable);
  176.         if ($hasVariable) {
  177.             $Order->setVariableWeightStatus('unprocessed'); // 仮で直接文字列
  178.         }
  179.         //不定貫であれば売価変更時にもともとの売価も保持する(再計算用)
  180.         if ($hasVariable) {
  181.             foreach ($Order->getOrderItems() as $item) {
  182.                 // 商品明細のみ
  183.                 if (!$item->isProduct()) {
  184.                     continue;
  185.                 }
  186.                 // まだ保存されていない場合のみ
  187.                 if ($item->getMotoPrice() === null) {
  188.                     $item->setMotoPrice($item->getPrice());
  189.                 }
  190.             }
  191.         }        
  192.         $this->em->flush();
  193.         $this->logger->info('[VariableWeight] flag initialized', [
  194.             'order_id' => $Order->getId(),
  195.             'has_variable_weight' => $hasVariable,
  196.         ]);
  197.     }
  198.     /**
  199.      * ここは通らない
  200.      * 決済確定前の最終チェック
  201.      */
  202.     public function onConfirmProcessing(EventArgs $event): void
  203.     {
  204.         //デバッグ用 26.02.16時点イベント反応なし(ここは通らない 他のプラグインなどカスタマイズも影響している)
  205.         $this->logger->info('route name: '.$event->getRequest()->attributes->get('_route'));
  206.         $this->logger->info('onConfirmProcessing called (test log)FRONT_SHOPPING_CONFIRM_PROCESSING');
  207.     }
  208. }