app/Plugin/PayPalCheckout42/Event.php line 235

Open in your IDE?
  1. <?php
  2. namespace Plugin\PayPalCheckout42;
  3. use Eccube\Common\EccubeConfig;
  4. use Eccube\Entity\Cart;
  5. use Eccube\Entity\Order;
  6. use Eccube\Entity\Payment;
  7. use Eccube\Entity\Shipping;
  8. use Eccube\Event\EccubeEvents;
  9. use Eccube\Event\EventArgs;
  10. use Eccube\Event\TemplateEvent;
  11. use Eccube\Repository\PaymentRepository;
  12. use Eccube\Service\CartService;
  13. use Eccube\Util\CacheUtil;
  14. use Plugin\PayPalCheckout42\Entity\Config;
  15. use Plugin\PayPalCheckout42\Repository\ConfigRepository;
  16. use Plugin\PayPalCheckout42\Service\LoggerService;
  17. use Plugin\PayPalCheckout42\Service\LoginService;
  18. use Plugin\PayPalCheckout42\Service\Method\Acdc;
  19. use Plugin\PayPalCheckout42\Service\Method\BankTransfer;
  20. use Plugin\PayPalCheckout42\Service\Method\CreditCard;
  21. use Plugin\PayPalCheckout42\Service\Method\InlineGuest;
  22. use Plugin\PayPalCheckout42\Service\PayPalAcdcService;
  23. use Plugin\PayPalCheckout42\Service\PayPalOrderService;
  24. use Plugin\PayPalCheckout42\Service\PayPalService;
  25. use Psr\Container\ContainerInterface;
  26. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  27. use Symfony\Component\HttpFoundation\RequestStack;
  28. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  29. /**
  30.  * Class Event
  31.  */
  32. class Event implements EventSubscriberInterface
  33. {
  34.     /**
  35.      * @var CartService
  36.      */
  37.     protected $cartService;
  38.     /**
  39.      * @var PayPalService
  40.      */
  41.     protected $paypalService;
  42.     /**
  43.      * @var PayPalOrderService
  44.      */
  45.     protected $paypalOrderService;
  46.     /**
  47.      * @var PayPalAcdcService
  48.      */
  49.     protected $paypalAcdcService;
  50.     /**
  51.      * @var ContainerInterface
  52.      */
  53.     protected $container;
  54.     /**
  55.      * @var EccubeConfig
  56.      */
  57.     protected $eccubeConfig;
  58.     /**
  59.      * @var Config
  60.      */
  61.     protected $Config;
  62.     /**
  63.      * @var LoggerService
  64.      */
  65.     protected $logger;
  66.     /**
  67.      * @var SessionInterface
  68.      */
  69.     protected $session;
  70.     /**
  71.      * @var PaymentRepository
  72.      */
  73.     protected $paymentRepository;
  74.     /**
  75.      * @var CacheUtil
  76.      */
  77.     protected $cacheUtil;
  78.     /**
  79.      * @var LoginService
  80.      */
  81.     protected $loginService;
  82.     /**
  83.      * PayPalCheckoutEvent constructor.
  84.      *
  85.      * @param CartService $cartService
  86.      * @param PayPalOrderService $paypalOrderService
  87.      * @param PayPalAcdcService $paypalAcdcService
  88.      * @param EccubeConfig $eccubeConfig
  89.      * @param ConfigRepository $configRepository
  90.      * @param ContainerInterface $container
  91.      * @param LoggerService $loggerService
  92.      * @param RequestStack $requestStack
  93.      * @param PaymentRepository $paymentRepository
  94.      * @param LoginService $loginService
  95.      */
  96.     public function __construct(
  97.         CartService $cartService,
  98.         PayPalService $payPalService,
  99.         PayPalOrderService $paypalOrderService,
  100.         PayPalAcdcService $paypalAcdcService,
  101.         EccubeConfig $eccubeConfig,
  102.         ConfigRepository $configRepository,
  103.         ContainerInterface $container,
  104.         LoggerService $loggerService,
  105.         RequestStack $requestStack,
  106.         PaymentRepository $paymentRepository,
  107.         CacheUtil $cacheUtil,
  108.         LoginService $loginService
  109.     ) {
  110.         $this->cartService $cartService;
  111.         $this->paypalService $payPalService;
  112.         $this->paypalOrderService $paypalOrderService;
  113.         $this->paypalAcdcService $paypalAcdcService;
  114.         $this->container $container;
  115.         $this->eccubeConfig $eccubeConfig;
  116.         $this->Config $configRepository->get();
  117.         $this->logger $loggerService;
  118.         $this->loginService $loginService;
  119.         $this->session $requestStack->getSession();
  120.         $this->paymentRepository $paymentRepository;
  121.         $this->cacheUtil $cacheUtil;
  122.     }
  123.     /**
  124.      * @return array
  125.      */
  126.     public static function getSubscribedEvents(): array
  127.     {
  128.         return [
  129.             'Shopping/login.twig' => 'onDefaultShoppingLoginTwig',
  130.             'Shopping/index.twig' => 'onDefaultShoppingIndexTwig',
  131.             'Shopping/confirm.twig' => 'onDefaultShoppingConfirmTwig',
  132.             'Cart/index.twig' => 'onDefaultCartIndexTwig',
  133.             'Block/paypal_logo.twig' => 'onDefaultPayPalLogoTwig',
  134.             EccubeEvents::FRONT_SHOPPING_SHIPPING_COMPLETE => 'onChangedShippingAddress',
  135.         ];
  136.     }
  137.     /**
  138.      * @param TemplateEvent $event
  139.      *
  140.      * @throws Exception\PayPalCheckoutException
  141.      */
  142.     public function onDefaultShoppingLoginTwig(TemplateEvent $event): void
  143.     {
  144.         $Carts $this->cartService->getCart();
  145.         if (is_null($Carts)) {
  146.             return;
  147.         }
  148.         if (!$this->paypalService->useExpressBtn()) {
  149.             return;
  150.         }
  151.         // カート金額が決済可能金額でない場合、PayPalボタンを表示しない
  152.         $amount $this->paypalService::getCartAmount($Carts);
  153.         if (!$this->isPayableAmount($amount)) {
  154.             return;
  155.         }
  156.         list($snippet$parameters) = $this->paypalOrderService->generateFrontEndParametersOnShoppingLoginPage($Carts);
  157.         $parameters['PayPalCheckout']['Config'] = $this->Config;
  158.         $this->logger->debug('Generate PayPal frontend parameters on /shipping/login page: ', [
  159.             'snippet' => $snippet,
  160.             'parameters' => $parameters,
  161.         ]);
  162.         $event->addSnippet($snippet);
  163.         $event->addAsset('@PayPalCheckout42/default/head.twig');
  164.         $event->setParameters(array_merge($event->getParameters(), $parameters));
  165.     }
  166.     /**
  167.      * @param TemplateEvent $event
  168.      *
  169.      * @throws Exception\PayPalCheckoutException
  170.      */
  171.     public function onDefaultCartIndexTwig(TemplateEvent $event): void
  172.     {
  173.         //        $this->session->remove(OrderHelper::SESSION_NON_MEMBER);
  174.         //        $this->session->remove(OrderHelper::SESSION_NON_MEMBER_ADDRESSES);
  175.         /** @var array $parameters */
  176.         $parameters $event->getParameters();
  177.         if (empty($parameters['Carts'])) {
  178.             return;
  179.         }
  180.         if (!$this->paypalService->useExpressBtn()) {
  181.             return;
  182.         }
  183.         /** @var Cart $cart */
  184.         $cart $parameters['Carts'][0];
  185.         // カート金額が決済可能金額でない場合、PayPalボタンを表示しない
  186.         $amount $this->paypalService::getCartAmount($cart);
  187.         if (!$this->isPayableAmount($amount)) {
  188.             return;
  189.         }
  190.         list($snippet$parameters) = $this->paypalOrderService->generateFrontEndParametersOnCartIndexPage($cart);
  191.         $parameters['PayPalCheckout']['Config'] = $this->Config;
  192.         $this->logger->debug('Generate PayPal frontend parameters on /cart page: ', [
  193.             'snippet' => $snippet,
  194.             'parameters' => $parameters,
  195.         ]);
  196.         $event->addSnippet($snippet);
  197.         $event->addAsset('@PayPalCheckout42/default/head.twig');
  198.         $event->setParameters(array_merge($event->getParameters(), $parameters));
  199.     }
  200.     /**
  201.      * @param TemplateEvent $event
  202.      *
  203.      * @throws \Exception
  204.      */
  205.     public function onDefaultShoppingIndexTwig(TemplateEvent $event): void
  206.     {
  207.         /** @var array $parameters */
  208.         $parameters $event->getParameters();
  209.         if (empty($parameters['Order'])) {
  210.             return;
  211.         }
  212.         /** @var Payment $payment */
  213.         $payment $parameters['Order']->getPayment();
  214.         // 支払い方法が何も選択されてない場合は、処理しない
  215.         if (!isset($payment)) {
  216.             return;
  217.         }
  218.         list($snippet$parameters) = $this->paypalOrderService->generateFrontEndParametersOnShoppingIndexPage();
  219.         $parameters['PayPalCheckout']['Config'] = $this->Config;
  220.         $parameters['PayPalCheckout']['isLogin'] = $this->loginService->isLoginUser();
  221.         $this->logger->debug('Generate PayPal frontend parameters on /shopping page: ', [
  222.             'snippet' => $snippet,
  223.             'parameters' => $parameters,
  224.         ]);
  225.         $event->addSnippet($snippet);
  226.         $event->addAsset('@PayPalCheckout42/default/head.twig');
  227.         if ($payment->getMethodClass() === InlineGuest::class) {
  228.             // inline決済専用のコードを追加で読み込む
  229.             $event->addSnippet('@PayPalCheckout42/default/Shopping/index/inline_guest.twig');
  230.             // inline決済の場合、入力が完了するまで「確認する」ボタンを非表示にしておく
  231.             $source $event->getSource();
  232.             $pattern '#<button[^>]*class="ec-blockBtn--action"[^>]*>[^<]+</button>#';
  233.             $replacedSource preg_replace($pattern'<button class="ec-blockBtn--action" disabled>確認する</button>'$source);
  234.             if (!is_null($replacedSource)) {
  235.                 $event->setSource($replacedSource);
  236.             }
  237.         }
  238.         if ($payment->getMethodClass() === Acdc::class) {
  239.             // Acdc決済専用のコードを追加で読み込む
  240.             $event->addSnippet('@PayPalCheckout42/default/Shopping/index/acdc.twig');
  241.             // クライアントからAPIアクセスするためのトークンを生成
  242.             $useVault $this->paypalAcdcService->canUseVault();
  243.             $parameters['PayPalCheckout']['acdcClientToken'] = $this->paypalAcdcService->getClientToken($useVault);
  244.             $parameters['PayPalCheckout']['acdcShowVault'] = $useVault;
  245.             $parameters['PayPalCheckout']['acdcUse3dsecure'] = $this->Config->getUse3dsecure();
  246.             $parameters['PayPalCheckout']['acdcFraudNetSessionIdentifier'] = $this->paypalAcdcService->createAndSaveFraudNetSessionIdentifierToSession();
  247.             $parameters['PayPalCheckout']['acdcSourceWebsiteIdentifier'] = $this->paypalAcdcService->getSourceWebsiteIdentifier();
  248.             // Vault で保存されたクレジットカード情報があれば取得する
  249.             if ($useVault) {
  250.                 $vault $this->paypalAcdcService->getVaults();
  251.                 // vault が2件以上存在した場合、不整合なので安全を考慮し全ての vault を削除する
  252.                 if (count($vault) >= 2) {
  253.                     $this->paypalAcdcService->bulkDeleteExistingVault();
  254.                     $vault = [];
  255.                 }
  256.                 $parameters['PayPalCheckout']['acdcVault'] = $vault[0] ?? [];
  257.             }
  258.         }
  259.         $event->setParameters(array_merge($event->getParameters(), $parameters));
  260.     }
  261.     /**
  262.      * @param TemplateEvent $event
  263.      */
  264.     public function onDefaultShoppingConfirmTwig(TemplateEvent $event): void
  265.     {
  266.         /** @var Order $order */
  267.         $order $event->getParameter('Order');
  268.         $payment $order->getPayment();
  269.         $isProcessingShortcutPayment $this->paypalOrderService->isProcessingShortcutPayment();
  270.         // PayPal決済以外は処理終了
  271.         if (!(
  272.             $payment->getMethodClass() === BankTransfer::class
  273.             || $payment->getMethodClass() === CreditCard::class
  274.             || $payment->getMethodClass() === InlineGuest::class
  275.             || $payment->getMethodClass() === Acdc::class
  276.         )) {
  277.             return;
  278.         }
  279.         // 必要なテンプレートを読み込み
  280.         if ($isProcessingShortcutPayment) {
  281.             $this->session->remove(PayPalOrderService::SESSION_SHORTCUT);
  282.             $snippet '@PayPalCheckout42/default/Shopping/confirm/shortcut.twig';
  283.         } elseif ($payment->getMethodClass() === InlineGuest::class) {
  284.             $snippet '@PayPalCheckout42/default/Shopping/confirm/inline_guest.twig';
  285.         } elseif ($payment->getMethodClass() === Acdc::class) {
  286.             $snippet '@PayPalCheckout42/default/Shopping/confirm/acdc.twig';
  287.         } else {
  288.             list($snippet$parameters) = $this->paypalOrderService->generateFrontEndParametersOnShoppingConfirmPage($order);
  289.         }
  290.         $parameters['PayPalCheckout']['Config'] = $this->Config;
  291.         // 「注文する」ボタンが一瞬表示されてしまうので、あらかじめ非表示にしておく。
  292.         // 逆にショートカット決済、クレジットカード決済の場合は「注文する」ボタンを使うので処理しない。
  293.         if (
  294.             !$isProcessingShortcutPayment
  295.             && $payment->getMethodClass() !== InlineGuest::class
  296.             && $payment->getMethodClass() !== Acdc::class
  297.         ) {
  298.             $source $event->getSource();
  299.             $pattern '#<button[^>]*class="ec-blockBtn--action"[^>]*>[^<]+</button>#';
  300.             $replacedSource preg_replace($pattern'<button class="ec-blockBtn--action" style="opacity: 0" disabled></button>'$source);
  301.             if (!is_null($replacedSource)) {
  302.                 $event->setSource($replacedSource);
  303.             }
  304.         }
  305.         $this->logger->debug('Generate PayPal frontend parameters on /shopping/confirm page: ', [
  306.             'custom_data' => [
  307.                 'snippet' => $snippet,
  308.                 'parameters' => $parameters,
  309.             ],
  310.         ]);
  311.         $event->addSnippet($snippet);
  312.         $event->addAsset('@PayPalCheckout42/default/head.twig');
  313.         $event->setParameters(array_merge($event->getParameters(), $parameters));
  314.     }
  315.     /**
  316.      * @param EventArgs $event
  317.      */
  318.     public function onChangedShippingAddress(EventArgs $event): void
  319.     {
  320.         /** @var Shipping $shipping */
  321.         $shipping $event->getArgument('Shipping');
  322.         $this->paypalOrderService->setShippingAddress($shipping);
  323.     }
  324.     /**
  325.      * @param TemplateEvent $event
  326.      */
  327.     public function onDefaultPayPalLogoTwig(TemplateEvent $event): void
  328.     {
  329.         /** @var string $selectedNumber */
  330.         $selectedNumber $this->Config->getPaypalLogo();
  331.         $parameters['PayPalCheckout']['paypal_logo'] = $this->eccubeConfig->get("paypal.paypal_express_paypal_logo_{$selectedNumber}");
  332.         $event->setParameters(array_merge($event->getParameters(), $parameters));
  333.     }
  334.     private function isPayableAmount($amount): bool
  335.     {
  336.         $payment $this->paymentRepository->findOneBy(['method_class' => CreditCard::class]);
  337.         if (!empty($payment)) {
  338.             $minRule $payment->getRuleMin();
  339.             $maxRule $payment->getRuleMax();
  340.         }
  341.         if (!isset($minRule) || $minRule PluginManager::MIN_AMOUNT) {
  342.             $minRule PluginManager::MIN_AMOUNT;
  343.         }
  344.         if (!isset($maxRule) || $maxRule PluginManager::MAX_AMOUNT) {
  345.             $maxRule PluginManager::MAX_AMOUNT;
  346.         }
  347.         if ($amount $minRule || $amount $maxRule) {
  348.             return false;
  349.         }
  350.         return true;
  351.     }
  352. }