custom/plugins/AdyenPaymentShopware6/src/Subscriber/ContextSubscriber.php line 78

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. /**
  3.  *                       ######
  4.  *                       ######
  5.  * ############    ####( ######  #####. ######  ############   ############
  6.  * #############  #####( ######  #####. ######  #############  #############
  7.  *        ######  #####( ######  #####. ######  #####  ######  #####  ######
  8.  * ###### ######  #####( ######  #####. ######  #####  #####   #####  ######
  9.  * ###### ######  #####( ######  #####. ######  #####          #####  ######
  10.  * #############  #############  #############  #############  #####  ######
  11.  *  ############   ############  #############   ############  #####  ######
  12.  *                                      ######
  13.  *                               #############
  14.  *                               ############
  15.  *
  16.  * Adyen Payment Module
  17.  *
  18.  * Copyright (c) 2021 Adyen B.V.
  19.  * This file is open source and available under the MIT license.
  20.  * See the LICENSE file for more info.
  21.  *
  22.  * Author: Adyen <shopware@adyen.com>
  23.  */
  24. namespace Adyen\Shopware\Subscriber;
  25. use Adyen\Shopware\Entity\PaymentStateData\PaymentStateDataEntity;
  26. use Adyen\Shopware\Service\ConfigurationService;
  27. use Adyen\Shopware\Service\PaymentStateDataService;
  28. use Adyen\Shopware\Struct\AdyenContextDataStruct;
  29. use Adyen\Util\Currency;
  30. use Shopware\Core\Checkout\Cart\AbstractCartPersister;
  31. use Shopware\Core\Checkout\Cart\CartCalculator;
  32. use Shopware\Core\Checkout\Cart\Exception\CartTokenNotFoundException;
  33. use Shopware\Core\Framework\Routing\Event\SalesChannelContextResolvedEvent;
  34. use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
  35. use Shopware\Core\System\SalesChannel\Context\SalesChannelContextService;
  36. use Shopware\Core\System\SalesChannel\Event\SalesChannelContextRestoredEvent;
  37. use Shopware\Core\System\SalesChannel\Event\SalesChannelContextTokenChangeEvent;
  38. use Shopware\Core\System\SalesChannel\SalesChannel\AbstractContextSwitchRoute;
  39. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  40. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  41. class ContextSubscriber implements EventSubscriberInterface
  42. {
  43.     private ConfigurationService $configurationService;
  44.     private PaymentStateDataService $paymentStateDataService;
  45.     private AbstractContextSwitchRoute $contextSwitchRoute;
  46.     private AbstractCartPersister $cartPersister;
  47.     private CartCalculator $cartCalculator;
  48.     private Currency $currency;
  49.     public function __construct(
  50.         ConfigurationService $configurationService,
  51.         PaymentStateDataService $paymentStateDataService,
  52.         AbstractContextSwitchRoute $contextSwitchRoute,
  53.         AbstractCartPersister $cartPersister,
  54.         CartCalculator $cartCalculator,
  55.         Currency $currency
  56.     ) {
  57.         $this->configurationService = $configurationService;
  58.         $this->paymentStateDataService = $paymentStateDataService;
  59.         $this->contextSwitchRoute = $contextSwitchRoute;
  60.         $this->cartPersister = $cartPersister;
  61.         $this->cartCalculator = $cartCalculator;
  62.         $this->currency = $currency;
  63.     }
  64.     public static function getSubscribedEvents()
  65.     {
  66.         return [
  67.             SalesChannelContextResolvedEvent::class => 'addAdyenData',
  68.             SalesChannelContextTokenChangeEvent::class => 'onContextTokenChange',
  69.             SalesChannelContextRestoredEvent::class => 'onContextRestored'
  70.         ];
  71.     }
  72.     public function onContextRestored(SalesChannelContextRestoredEvent $event): void
  73.     {
  74.         $token = $event->getRestoredSalesChannelContext()->getToken();
  75.         $oldToken = $event->getCurrentSalesChannelContext()->getToken();
  76.         $stateData = $this->paymentStateDataService->getPaymentStateDataFromContextToken($oldToken);
  77.         if ($stateData) {
  78.             $this->paymentStateDataService->updateStateDataContextToken($stateData, $token);
  79.             $this->setGiftcardPaymentMethodAfterContextRestored($event->getRestoredSalesChannelContext(), $stateData);
  80.         }
  81.     }
  82.     public function onContextTokenChange(SalesChannelContextTokenChangeEvent $event): void
  83.     {
  84.         $token = $event->getCurrentToken();
  85.         $oldToken = $event->getPreviousToken();
  86.         $stateData = $this->paymentStateDataService->getPaymentStateDataFromContextToken($oldToken);
  87.         if ($stateData) {
  88.             $this->paymentStateDataService->updateStateDataContextToken($stateData, $token);
  89.         }
  90.     }
  91.     public function addAdyenData(SalesChannelContextResolvedEvent $event): void
  92.     {
  93.         $context = $event->getSalesChannelContext();
  94.         $salesChannelId = $context->getSalesChannelId();
  95.         $extension = new AdyenContextDataStruct();
  96.         $context->addExtension('adyenData', $extension);
  97.         $extension->setClientKey($this->configurationService->getClientKey($salesChannelId) ?: null);
  98.         $extension->setEnvironment($this->configurationService->getEnvironment($salesChannelId));
  99.         $data = $this->paymentStateDataService->getPaymentStateDataFromContextToken($context->getToken());
  100.         $extension->setHasPaymentStateData(!empty($data));
  101.     }
  102.     private function setGiftcardPaymentMethodAfterContextRestored(
  103.         SalesChannelContext $context,
  104.         PaymentStateDataEntity $stateData
  105.     ): void {
  106.         $currency = $context->getCurrency()->getIsoCode();
  107.         $decodedStateData = json_decode($stateData->getStateData(), true);
  108.         try {
  109.             $cart = $this->cartCalculator->calculate(
  110.                 $this->cartPersister->load($context->getToken(), $context),
  111.                 $context
  112.             );
  113.             $totalPrice = $cart->getPrice()->getTotalPrice();
  114.         } catch (CartTokenNotFoundException $exception) {
  115.             // No cart information found.
  116.             return;
  117.         }
  118.         $amount = $this->currency->sanitize($totalPrice, $currency);
  119.         $giftcardDiscount = $decodedStateData['additionalData']['amount'] ?? 0;
  120.         if ($giftcardDiscount >= $amount) {
  121.             $this->contextSwitchRoute->switchContext(
  122.                 new RequestDataBag(
  123.                     [
  124.                         SalesChannelContextService::PAYMENT_METHOD_ID =>
  125.                             $decodedStateData['additionalData']['paymentMethodId']
  126.                     ]
  127.                 ),
  128.                 $context
  129.             );
  130.         }
  131.     }
  132. }